From 10efacc32f9217d34ebff9bd67eea86580a06371 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Fri, 14 Jan 2022 10:29:26 +0100 Subject: [PATCH 01/47] added the Proto definitions of the subspaces types and messages Signed-off-by: Riccardo Montagnin --- .../profiles/v1beta1/models_chain_links.proto | 6 +- .../profiles/v1beta1/msgs_profile.proto | 9 +- proto/desmos/subspaces/v1/genesis.proto | 34 ++++ proto/desmos/subspaces/v1/msgs.proto | 190 ++++++++++++++++++ proto/desmos/subspaces/v1/query.proto | 128 ++++++++++++ proto/desmos/subspaces/v1/subspace.proto | 40 ++++ 6 files changed, 399 insertions(+), 8 deletions(-) create mode 100644 proto/desmos/subspaces/v1/genesis.proto create mode 100644 proto/desmos/subspaces/v1/msgs.proto create mode 100644 proto/desmos/subspaces/v1/query.proto create mode 100644 proto/desmos/subspaces/v1/subspace.proto diff --git a/proto/desmos/profiles/v1beta1/models_chain_links.proto b/proto/desmos/profiles/v1beta1/models_chain_links.proto index d6579bd58c..c718d7c0f7 100644 --- a/proto/desmos/profiles/v1beta1/models_chain_links.proto +++ b/proto/desmos/profiles/v1beta1/models_chain_links.proto @@ -66,7 +66,8 @@ message Proof { // Signature represents the hex-encoded signature of the PlainText value string signature = 2 [ (gogoproto.moretags) = "yaml:\"signature\"" ]; - // PlainText represents the hex-encoded value signed in order to produce the Signature + // PlainText represents the hex-encoded value signed in order to produce the + // Signature string plain_text = 3 [ (gogoproto.moretags) = "yaml:\"plain_text\"" ]; } @@ -106,6 +107,7 @@ message HexAddress { // Value represents the hex address value string value = 1 [ (gogoproto.moretags) = "yaml:\"value\"" ]; - // Prefix represents the optional prefix used during address encoding (e.g. 0x) + // Prefix represents the optional prefix used during address encoding (e.g. + // 0x) string prefix = 2 [ (gogoproto.moretags) = "yaml:\"prefix\"" ]; } \ No newline at end of file diff --git a/proto/desmos/profiles/v1beta1/msgs_profile.proto b/proto/desmos/profiles/v1beta1/msgs_profile.proto index 2fe4d74b83..13a8139d2f 100644 --- a/proto/desmos/profiles/v1beta1/msgs_profile.proto +++ b/proto/desmos/profiles/v1beta1/msgs_profile.proto @@ -24,13 +24,10 @@ message MsgSaveProfile { string bio = 3 [ (gogoproto.moretags) = "yaml:\"bio\"" ]; - string profile_picture = 4 [ - (gogoproto.moretags) = "yaml:\"profile_picture\"" - ]; + string profile_picture = 4 + [ (gogoproto.moretags) = "yaml:\"profile_picture\"" ]; - string cover_picture = 5 [ - (gogoproto.moretags) = "yaml:\"cover_picture\"" - ]; + string cover_picture = 5 [ (gogoproto.moretags) = "yaml:\"cover_picture\"" ]; string creator = 6 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; } diff --git a/proto/desmos/subspaces/v1/genesis.proto b/proto/desmos/subspaces/v1/genesis.proto new file mode 100644 index 0000000000..570708943e --- /dev/null +++ b/proto/desmos/subspaces/v1/genesis.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; +package desmos.subspaces.v1; + +import "gogoproto/gogo.proto"; +import "desmos/subspaces/v1beta1/subspace.proto"; + +option go_package = "github.com/desmos-labs/desmos/v2/x/staging/subspaces/types"; + +// GenesisState contains the data of the genesis state for the subspaces module +message GenesisState { + repeated desmos.subspaces.v1.Subspace subspaces = 1 + [ (gogoproto.nullable) = false ]; + + repeated ACL access_lists = 3 [ (gogoproto.nullable) = false ]; + + repeated UserGroup user_groups = 2 [ (gogoproto.nullable) = false ]; +} + +message ACL { + // Either group name or + string subject = 1; + bytes permissions = 2; +} + +// UsersEntry contains the data of a slice of users associated to a subspace +// with a specific id +message UserGroup { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + + string subspace_id = 1 [ (gogoproto.customname) = "SubspaceID" ]; + string name = 2; + repeated string users = 3; +} \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/msgs.proto b/proto/desmos/subspaces/v1/msgs.proto new file mode 100644 index 0000000000..81226bdba1 --- /dev/null +++ b/proto/desmos/subspaces/v1/msgs.proto @@ -0,0 +1,190 @@ +syntax = "proto3"; +package desmos.subspaces.v1; + +import "gogoproto/gogo.proto"; +import "desmos/subspaces/v1beta1/subspace.proto"; + +option go_package = "github.com/desmos-labs/desmos/v2/x/staging/subspaces/types"; + +// Msg defines subspaces Msg service. +service Msg { + + // CreateSubspace allows to create a subspace + rpc CreateSubspace(MsgCreateSubspace) returns (MsgCreateSubspaceResponse); + + // EditSubspace allows to edit a subspace + rpc EditSubspace(MsgEditSubspace) returns (MsgEditSubspaceResponse); + + // CreateUserGroup allows to create a new user group + rpc CreateUserGroup(MsgCreateUserGroup) returns (MsgCreateUserGroupResponse); + + // DeleteUserGroup allows to delete an existing user group + rpc DeleteUserGroup(MsgDeleteUserGroup) returns (MsgDeleteUserGroupResponse); + + // SetUserGroupPermissions allows to set a specific group permissions + rpc SetUserGroupPermissions(MsgSetUserGroupPermissions) + returns (MsgSetUserGroupPermissionsResponse); + + // AddUserToUserGroup allows to add a specific user to a specific user group + rpc AddUserToUserGroup(MsgAddUserToUserGroup) + returns (MsgAddUserToUserGroupResponse); + // RemoveUserFromUserGroup allows to remove a specific user from a specific + // user group + rpc RemoveUserFromUserGroup(MsgRemoveUserFromUserGroup) + returns (MsgRemoveUserFromUserGroupResponse); + + // SetUserPermissions allows to set another user's permissions + rpc SetUserPermissions(MsgSetUserPermissions) + returns (MsgSetUserPermissionsResponse) +} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgCreateSubspace represents the message used to create a subspace +message MsgCreateSubspace { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string name = 1 [ (gogoproto.moretags) = "yaml:\"name\"" ]; + string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + string owner = 3 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; + string treasury = 4 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; + string creator = 5 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; +} + +// MsgCreateSubspaceResponse defines the Msg/CreateSubspace response type +message MsgCreateSubspaceResponse { + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; +} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgEditSubspace represents the message used to edit a subspace fields +message MsgEditSubspace { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string id = 1 [ + (gogoproto.customname) = "ID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + + string name = 2 [ (gogoproto.moretags) = "yaml:\"name\"" ]; + string description = 3 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + string owner = 4 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; + string treasury = 5 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; + string signer = 6 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; +} + +// MsgEditSubspaceResponse defines the Msg/EditSubspace response type +message MsgEditSubspaceResponse {} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgCreateUserGroup represents the message used to create a user group +message MsgCreateUserGroup { + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + + string group_name = 2 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; + bytes default_permissions = 3 + [ (gogoproto.moretags) = "yaml:\"default_permissions\"" ]; + string creator = 4 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; +} + +// MsgCreateUserGroupResponse defines the Msg/CreateUserGroup response type +message MsgCreateUserGroupResponse {} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgDeleteUserGroup represents the message used to delete a user group +message MsgDeleteUserGroup { + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + string group_name = 2 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; + string signer = 3 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; +} + +// MsgDeleteUserGroupResponse defines the Msg/DeleteUserGroup response type +message MsgDeleteUserGroupResponse {} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgSetUserGroupPermissions represents the message used to set the permissions +// of a user group +message MsgSetUserGroupPermissions { + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + + string group_name = 2 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; + bytes permissions = 3 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; + string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; +} + +// MsgSetUserGroupPermissionsResponse defines the +// Msg/SetUserGroupPermissionsResponse response type +message MsgSetUserGroupPermissionsResponse {} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgSetUserGroupPermissions represents the message used to add a user to a +// user group +message MsgAddUserToUserGroup { + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + string user = 2 [ (gogoproto.moretags) = "yaml:\"user\"" ]; + string group_name = 3 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; + string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; +} + +// MsgAddUserToUserGroupResponse defines the Msg/AddUserToUserGroupResponse +// response type +message MsgAddUserToUserGroupResponse {} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgRemoveUserFromUserGroup represents the message used to remove a user from +// a user group +message MsgRemoveUserFromUserGroup { + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + string user = 2 [ (gogoproto.moretags) = "yaml:\"user\"" ]; + string group_name = 3 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; + string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; +} + +// MsgRemoveUserFromUserGroupResponse defines the +// Msg/RemoveUserFromUserGroupResponse response type +message MsgRemoveUserFromUserGroupResponse {} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgSetUserPermissions represents the message used to set the permissions of a +// user +message MsgSetUserPermissions { + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + + string user = 2 [ (gogoproto.moretags) = "yaml:\"user\"" ]; + bytes permissions = 3 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; + string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; +} + +// MsgSetUserPermissionsResponse defines the Msg/SetUserPermissionsResponse +// response type +message MsgSetUserPermissionsResponse {} \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/query.proto b/proto/desmos/subspaces/v1/query.proto new file mode 100644 index 0000000000..8362f430f1 --- /dev/null +++ b/proto/desmos/subspaces/v1/query.proto @@ -0,0 +1,128 @@ +syntax = "proto3"; +package desmos.subspaces.v1; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "desmos/subspaces/v1beta1/subspace.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; + +option go_package = "github.com/desmos-labs/desmos/v2/x/staging/subspaces/types"; + +// Query defines the gRPC querier service +service Query { + + // Subspace queries all the information about the subspace with the given id + rpc Subspace(QuerySubspaceRequest) returns (QuerySubspaceResponse) { + option (google.api.http).get = "/desmos/subspaces/v1beta1/{subspace_id}"; + } + + // Admins queries all the admins of the subspace having the given id + rpc Admins(QueryAdminsRequest) returns (QueryAdminsResponse) { + option (google.api.http).get = + "/desmos/subspaces/v1beta1/{subspace_id}/admins"; + } + + // RegisteredUsers queries all the registered users of the subspace having the + // given id + rpc RegisteredUsers(QueryRegisteredUsersRequest) + returns (QueryRegisteredUsersResponse) { + option (google.api.http).get = + "/desmos/subspaces/v1beta1/{subspace_id}/registered_users"; + } + + // BannedUsers queries all the banned users of the subspace having the given + // id + rpc BannedUsers(QueryBannedUsersRequest) returns (QueryBannedUsersResponse) { + option (google.api.http).get = + "/desmos/subspaces/v1beta1/{subspace_id}/banned_users"; + } + + // Subspaces queries all the subspaces inside Desmos + rpc Subspaces(QuerySubspacesRequest) returns (QuerySubspacesResponse) { + option (google.api.http).get = "/desmos/subspaces/v1beta1/subspaces"; + } +} + +// -------------------------------------------------------------------------------------------------------------------- + +// QuerySubspace is the request type for the Query/Subspace RPC method +message QuerySubspaceRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + string subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; +} + +// QuerySubspaceResponse is the response type for the Query/Subspace method +message QuerySubspaceResponse { + desmos.subspaces.v1.Subspace subspace = 1 [ (gogoproto.nullable) = false ]; +} + +// -------------------------------------------------------------------------------------------------------------------- + +// QuerySubspacesRequest is the request type for the Query/Subspaces RPC method +message QuerySubspacesRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QuerySubspacesResponse is the response type for the Query/Subspaces RPC +// method +message QuerySubspacesResponse { + repeated Subspace subspaces = 1 [ (gogoproto.nullable) = false ]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// -------------------------------------------------------------------------------------------------------------------- + +// QueryAdminsRequest is the request type for the Query/Admins RPC +// method +message QueryAdminsRequest { + string subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryAdminsResponse is the response type for the Query/Admins RPC +// method +message QueryAdminsResponse { + repeated string admins = 1; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// -------------------------------------------------------------------------------------------------------------------- + +// QueryRegisteredUsersRequest is the request type for the +// Query/RegisteredUsers RPC method +message QueryRegisteredUsersRequest { + string subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryRegisteredUsersResponse is the response type for the +// Query/RegisteredUsers RPC method +message QueryRegisteredUsersResponse { + repeated string users = 1; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +// -------------------------------------------------------------------------------------------------------------------- + +// QueryBannedUsersRequest is the request type for the Query/BannedUsers +// RPC method +message QueryBannedUsersRequest { + string subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; + + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 2; +} + +// QueryBannedUsersResponse is the response type for the +// Query/BannedUsers RPC method +message QueryBannedUsersResponse { + repeated string users = 1; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/subspace.proto b/proto/desmos/subspaces/v1/subspace.proto new file mode 100644 index 0000000000..fa6efdbefd --- /dev/null +++ b/proto/desmos/subspaces/v1/subspace.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; +package desmos.subspaces.v1; + +import "gogoproto/gogo.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "github.com/desmos-labs/desmos/v2/x/staging/subspaces/types"; + +// Subspace contains all the data of a Desmos subspace +message Subspace { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + + // Unique SHA-256 string that identifies the subspace + uint64 id = 1 + [ (gogoproto.customname) = "ID", (gogoproto.moretags) = "yaml:\"id\"" ]; + + // Human-readable name of the subspace + string name = 2 [ (gogoproto.moretags) = "yaml:\"name\"" ]; + + // Optional description of this subspace + string description = 3 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + + // Address of the user that owns the subspace + string owner = 4 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; + + // Address of the subspace creator + string creator = 5 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; + + // Represents the account that is associated with the subspace and + // should be used to connect external applications to verify this subspace + string treasury = 6 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; + + // the creation time of the subspace + google.protobuf.Timestamp creation_time = 5 [ + (gogoproto.nullable) = false, + (gogoproto.stdtime) = true, + (gogoproto.moretags) = "yaml:\"creation_time\"" + ]; +} From 32f79817bd1624b88ca1a40a7cfa22a6ddda8df0 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Fri, 14 Jan 2022 11:25:41 +0100 Subject: [PATCH 02/47] improved the Proto file definition Signed-off-by: Riccardo Montagnin --- proto/desmos/subspaces/v1/genesis.proto | 17 +++-- proto/desmos/subspaces/v1/msgs.proto | 6 +- proto/desmos/subspaces/v1/query.proto | 92 ++++++++++++------------ proto/desmos/subspaces/v1/subspace.proto | 4 +- 4 files changed, 60 insertions(+), 59 deletions(-) diff --git a/proto/desmos/subspaces/v1/genesis.proto b/proto/desmos/subspaces/v1/genesis.proto index 570708943e..5abdb35a64 100644 --- a/proto/desmos/subspaces/v1/genesis.proto +++ b/proto/desmos/subspaces/v1/genesis.proto @@ -2,24 +2,27 @@ syntax = "proto3"; package desmos.subspaces.v1; import "gogoproto/gogo.proto"; -import "desmos/subspaces/v1beta1/subspace.proto"; +import "desmos/subspaces/v1/subspace.proto"; -option go_package = "github.com/desmos-labs/desmos/v2/x/staging/subspaces/types"; +option go_package = "github.com/desmos-labs/desmos/v2/x/subspaces/types"; // GenesisState contains the data of the genesis state for the subspaces module message GenesisState { repeated desmos.subspaces.v1.Subspace subspaces = 1 [ (gogoproto.nullable) = false ]; - repeated ACL access_lists = 3 [ (gogoproto.nullable) = false ]; + repeated ACLEntry acl = 3 + [ (gogoproto.customname) = "ACL", (gogoproto.nullable) = false ]; repeated UserGroup user_groups = 2 [ (gogoproto.nullable) = false ]; } -message ACL { - // Either group name or - string subject = 1; - bytes permissions = 2; +// ACL represents a single Access Control List entry +message ACLEntry { + // Either group name or user address + uint64 subspace_id = 1; + string target = 2; + bytes permissions = 3; } // UsersEntry contains the data of a slice of users associated to a subspace diff --git a/proto/desmos/subspaces/v1/msgs.proto b/proto/desmos/subspaces/v1/msgs.proto index 81226bdba1..f5ee80a7fb 100644 --- a/proto/desmos/subspaces/v1/msgs.proto +++ b/proto/desmos/subspaces/v1/msgs.proto @@ -2,9 +2,9 @@ syntax = "proto3"; package desmos.subspaces.v1; import "gogoproto/gogo.proto"; -import "desmos/subspaces/v1beta1/subspace.proto"; +import "desmos/subspaces/v1/subspace.proto"; -option go_package = "github.com/desmos-labs/desmos/v2/x/staging/subspaces/types"; +option go_package = "github.com/desmos-labs/desmos/v2/x/subspaces/types"; // Msg defines subspaces Msg service. service Msg { @@ -35,7 +35,7 @@ service Msg { // SetUserPermissions allows to set another user's permissions rpc SetUserPermissions(MsgSetUserPermissions) - returns (MsgSetUserPermissionsResponse) + returns (MsgSetUserPermissionsResponse); } // -------------------------------------------------------------------------------------------------------------------- diff --git a/proto/desmos/subspaces/v1/query.proto b/proto/desmos/subspaces/v1/query.proto index 8362f430f1..44d2cdcf74 100644 --- a/proto/desmos/subspaces/v1/query.proto +++ b/proto/desmos/subspaces/v1/query.proto @@ -3,43 +3,42 @@ package desmos.subspaces.v1; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; -import "desmos/subspaces/v1beta1/subspace.proto"; +import "desmos/subspaces/v1/subspace.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; -option go_package = "github.com/desmos-labs/desmos/v2/x/staging/subspaces/types"; +option go_package = "github.com/desmos-labs/desmos/v2/x/subspaces/types"; // Query defines the gRPC querier service service Query { // Subspace queries all the information about the subspace with the given id rpc Subspace(QuerySubspaceRequest) returns (QuerySubspaceResponse) { - option (google.api.http).get = "/desmos/subspaces/v1beta1/{subspace_id}"; + option (google.api.http).get = "/desmos/subspaces/v1/{subspace_id}"; } - // Admins queries all the admins of the subspace having the given id - rpc Admins(QueryAdminsRequest) returns (QueryAdminsResponse) { - option (google.api.http).get = - "/desmos/subspaces/v1beta1/{subspace_id}/admins"; + // Subspaces queries all the subspaces inside Desmos + rpc Subspaces(QuerySubspacesRequest) returns (QuerySubspacesResponse) { + option (google.api.http).get = "/desmos/subspaces/v1/subspaces"; } - // RegisteredUsers queries all the registered users of the subspace having the - // given id - rpc RegisteredUsers(QueryRegisteredUsersRequest) - returns (QueryRegisteredUsersResponse) { - option (google.api.http).get = - "/desmos/subspaces/v1beta1/{subspace_id}/registered_users"; + // UserGroups queries all the groups that are present inside the subspace with + // the given id + rpc UserGroups(QueryUserGroupsRequest) returns (QueryUserGroupsResponse) { + option (google.api.http).get = "/desmos/subspaces/v1/{subspace_id}/groups"; } - // BannedUsers queries all the banned users of the subspace having the given - // id - rpc BannedUsers(QueryBannedUsersRequest) returns (QueryBannedUsersResponse) { + // UserGroupMembers queries all the members of a given user group + rpc UserGroupMembers(QueryUserGroupMembersRequest) + returns (QueryUserGroupMembersResponse) { option (google.api.http).get = - "/desmos/subspaces/v1beta1/{subspace_id}/banned_users"; + "/desmos/subspaces/v1/{subspace_id}/groups/{group_name}/members"; } - // Subspaces queries all the subspaces inside Desmos - rpc Subspaces(QuerySubspacesRequest) returns (QuerySubspacesResponse) { - option (google.api.http).get = "/desmos/subspaces/v1beta1/subspaces"; + // Permissions queries the permissions for the given target (user address or + // group name) + rpc Permissions(QueryPermissionsRequest) returns (QueryPermissionsResponse) { + option (google.api.http).get = + "/desmos/subspaces/v1/{subspace_id}/permissions/{target}"; } } @@ -50,7 +49,7 @@ message QuerySubspaceRequest { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; + uint64 subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; } // QuerySubspaceResponse is the response type for the Query/Subspace method @@ -75,54 +74,53 @@ message QuerySubspacesResponse { // -------------------------------------------------------------------------------------------------------------------- -// QueryAdminsRequest is the request type for the Query/Admins RPC +// QueryUserGroupsRequest is the request type for the Query/UserGroups RPC // method -message QueryAdminsRequest { - string subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; +message QueryUserGroupsRequest { + uint64 subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageRequest pagination = 2; } -// QueryAdminsResponse is the response type for the Query/Admins RPC +// QueryUserGroupsResponse is the response type for the Query/UserGroups RPC // method -message QueryAdminsResponse { - repeated string admins = 1; +message QueryUserGroupsResponse { + repeated string groups = 1 [ (gogoproto.nullable) = false ]; cosmos.base.query.v1beta1.PageResponse pagination = 2; } // -------------------------------------------------------------------------------------------------------------------- -// QueryRegisteredUsersRequest is the request type for the -// Query/RegisteredUsers RPC method -message QueryRegisteredUsersRequest { - string subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; +// QueryUserGroupMembersRequest is the request type for the +// Query/UserGroupMembers RPC method +message QueryUserGroupMembersRequest { + uint64 subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; + string group_name = 2 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; + cosmos.base.query.v1beta1.PageRequest pagination = 3; } -// QueryRegisteredUsersResponse is the response type for the -// Query/RegisteredUsers RPC method -message QueryRegisteredUsersResponse { - repeated string users = 1; +// QueryUserGroupMembersResponse is the response type for the +// Query/UserGroupMembers RPC method +message QueryUserGroupMembersResponse { + repeated string members = 1 [ (gogoproto.nullable) = false ]; cosmos.base.query.v1beta1.PageResponse pagination = 2; } // -------------------------------------------------------------------------------------------------------------------- -// QueryBannedUsersRequest is the request type for the Query/BannedUsers -// RPC method -message QueryBannedUsersRequest { - string subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; +// QuerySubspace is the request type for the Query/Subspace RPC method +message QueryPermissionsRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; - // pagination defines an optional pagination for the request. - cosmos.base.query.v1beta1.PageRequest pagination = 2; + uint64 subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; + string target = 2 [ (gogoproto.moretags) = "yaml:\"target\"" ]; } -// QueryBannedUsersResponse is the response type for the -// Query/BannedUsers RPC method -message QueryBannedUsersResponse { - repeated string users = 1; - cosmos.base.query.v1beta1.PageResponse pagination = 2; +// QuerySubspaceResponse is the response type for the Query/Subspace method +message QueryPermissionsResponse { + bytes permissions = 1 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; } \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/subspace.proto b/proto/desmos/subspaces/v1/subspace.proto index fa6efdbefd..52595f7562 100644 --- a/proto/desmos/subspaces/v1/subspace.proto +++ b/proto/desmos/subspaces/v1/subspace.proto @@ -4,7 +4,7 @@ package desmos.subspaces.v1; import "gogoproto/gogo.proto"; import "google/protobuf/timestamp.proto"; -option go_package = "github.com/desmos-labs/desmos/v2/x/staging/subspaces/types"; +option go_package = "github.com/desmos-labs/desmos/v2/x/subspaces/types"; // Subspace contains all the data of a Desmos subspace message Subspace { @@ -32,7 +32,7 @@ message Subspace { string treasury = 6 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; // the creation time of the subspace - google.protobuf.Timestamp creation_time = 5 [ + google.protobuf.Timestamp creation_time = 7 [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true, (gogoproto.moretags) = "yaml:\"creation_time\"" From 9293ae28a84efa7d49d61f2f3cad3ae23c2ca9b0 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 17 Jan 2022 11:01:57 +0100 Subject: [PATCH 03/47] improved the Proto file definition Signed-off-by: Riccardo Montagnin --- proto/desmos/subspaces/v1/msgs.proto | 45 +- proto/desmos/subspaces/v1/query.proto | 4 +- x/profiles/types/models_chain_links.pb.go | 6 +- x/subspaces/handler.go | 50 + x/subspaces/keeper/alias_functions.go | 172 + x/subspaces/keeper/alias_functions_test.go | 411 +++ x/subspaces/keeper/common_test.go | 59 + x/subspaces/keeper/genesis.go | 75 + x/subspaces/keeper/genesis_test.go | 342 ++ x/subspaces/keeper/grpc_query.go | 126 + x/subspaces/keeper/grpc_query_test.go | 348 ++ x/subspaces/keeper/invariants.go | 50 + x/subspaces/keeper/invariants_test.go | 64 + x/subspaces/keeper/keeper.go | 230 ++ x/subspaces/keeper/keeper_test.go | 908 +++++ x/subspaces/keeper/msg_server.go | 186 + x/subspaces/keeper/msg_server_test.go | 877 +++++ x/subspaces/module.go | 204 ++ x/subspaces/types/codec.go | 46 + x/subspaces/types/errors.go | 10 + x/subspaces/types/events.go | 19 + x/subspaces/types/genesis.go | 103 + x/subspaces/types/genesis.pb.go | 1039 ++++++ x/subspaces/types/genesis_test.go | 196 ++ x/subspaces/types/keys.go | 28 + x/subspaces/types/msgs.go | 335 ++ x/subspaces/types/msgs.pb.go | 3565 ++++++++++++++++++++ x/subspaces/types/msgs_test.go | 810 +++++ x/subspaces/types/query.go | 41 + x/subspaces/types/query.pb.go | 2494 ++++++++++++++ x/subspaces/types/query.pb.gw.go | 638 ++++ x/subspaces/types/subspace.go | 99 + x/subspaces/types/subspace.pb.go | 678 ++++ x/subspaces/types/subspace_test.go | 236 ++ x/subspaces/types/utils.go | 12 + 35 files changed, 14468 insertions(+), 38 deletions(-) create mode 100644 x/subspaces/handler.go create mode 100644 x/subspaces/keeper/alias_functions.go create mode 100644 x/subspaces/keeper/alias_functions_test.go create mode 100644 x/subspaces/keeper/common_test.go create mode 100644 x/subspaces/keeper/genesis.go create mode 100644 x/subspaces/keeper/genesis_test.go create mode 100644 x/subspaces/keeper/grpc_query.go create mode 100644 x/subspaces/keeper/grpc_query_test.go create mode 100644 x/subspaces/keeper/invariants.go create mode 100644 x/subspaces/keeper/invariants_test.go create mode 100644 x/subspaces/keeper/keeper.go create mode 100644 x/subspaces/keeper/keeper_test.go create mode 100644 x/subspaces/keeper/msg_server.go create mode 100644 x/subspaces/keeper/msg_server_test.go create mode 100644 x/subspaces/module.go create mode 100644 x/subspaces/types/codec.go create mode 100644 x/subspaces/types/errors.go create mode 100644 x/subspaces/types/events.go create mode 100644 x/subspaces/types/genesis.go create mode 100644 x/subspaces/types/genesis.pb.go create mode 100644 x/subspaces/types/genesis_test.go create mode 100644 x/subspaces/types/keys.go create mode 100644 x/subspaces/types/msgs.go create mode 100644 x/subspaces/types/msgs.pb.go create mode 100644 x/subspaces/types/msgs_test.go create mode 100644 x/subspaces/types/query.go create mode 100644 x/subspaces/types/query.pb.go create mode 100644 x/subspaces/types/query.pb.gw.go create mode 100644 x/subspaces/types/subspace.go create mode 100644 x/subspaces/types/subspace.pb.go create mode 100644 x/subspaces/types/subspace_test.go create mode 100644 x/subspaces/types/utils.go diff --git a/proto/desmos/subspaces/v1/msgs.proto b/proto/desmos/subspaces/v1/msgs.proto index f5ee80a7fb..a745428a3e 100644 --- a/proto/desmos/subspaces/v1/msgs.proto +++ b/proto/desmos/subspaces/v1/msgs.proto @@ -15,27 +15,23 @@ service Msg { // EditSubspace allows to edit a subspace rpc EditSubspace(MsgEditSubspace) returns (MsgEditSubspaceResponse); - // CreateUserGroup allows to create a new user group + // CreateUserGroup allows to create a user group rpc CreateUserGroup(MsgCreateUserGroup) returns (MsgCreateUserGroupResponse); // DeleteUserGroup allows to delete an existing user group rpc DeleteUserGroup(MsgDeleteUserGroup) returns (MsgDeleteUserGroupResponse); - // SetUserGroupPermissions allows to set a specific group permissions - rpc SetUserGroupPermissions(MsgSetUserGroupPermissions) - returns (MsgSetUserGroupPermissionsResponse); - // AddUserToUserGroup allows to add a specific user to a specific user group rpc AddUserToUserGroup(MsgAddUserToUserGroup) returns (MsgAddUserToUserGroupResponse); + // RemoveUserFromUserGroup allows to remove a specific user from a specific // user group rpc RemoveUserFromUserGroup(MsgRemoveUserFromUserGroup) returns (MsgRemoveUserFromUserGroupResponse); // SetUserPermissions allows to set another user's permissions - rpc SetUserPermissions(MsgSetUserPermissions) - returns (MsgSetUserPermissionsResponse); + rpc SetPermissions(MsgSetPermissions) returns (MsgSetPermissionsResponse); } // -------------------------------------------------------------------------------------------------------------------- @@ -92,7 +88,7 @@ message MsgCreateUserGroup { ]; string group_name = 2 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; - bytes default_permissions = 3 + uint32 default_permissions = 3 [ (gogoproto.moretags) = "yaml:\"default_permissions\"" ]; string creator = 4 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; } @@ -117,25 +113,6 @@ message MsgDeleteUserGroupResponse {} // -------------------------------------------------------------------------------------------------------------------- -// MsgSetUserGroupPermissions represents the message used to set the permissions -// of a user group -message MsgSetUserGroupPermissions { - uint64 subspace_id = 1 [ - (gogoproto.customname) = "SubspaceID", - (gogoproto.moretags) = "yaml:\"subspace_id\"" - ]; - - string group_name = 2 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; - bytes permissions = 3 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; - string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; -} - -// MsgSetUserGroupPermissionsResponse defines the -// Msg/SetUserGroupPermissionsResponse response type -message MsgSetUserGroupPermissionsResponse {} - -// -------------------------------------------------------------------------------------------------------------------- - // MsgSetUserGroupPermissions represents the message used to add a user to a // user group message MsgAddUserToUserGroup { @@ -172,19 +149,19 @@ message MsgRemoveUserFromUserGroupResponse {} // -------------------------------------------------------------------------------------------------------------------- -// MsgSetUserPermissions represents the message used to set the permissions of a -// user -message MsgSetUserPermissions { +// MsgSetPermissions represents the message used to set the permissions of a +// user or user group +message MsgSetPermissions { uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID", (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; - string user = 2 [ (gogoproto.moretags) = "yaml:\"user\"" ]; - bytes permissions = 3 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; + string target = 2 [ (gogoproto.moretags) = "yaml:\"target\"" ]; + uint32 permissions = 3 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; } -// MsgSetUserPermissionsResponse defines the Msg/SetUserPermissionsResponse +// MsgSetPermissionsResponse defines the Msg/SetPermissionsResponse // response type -message MsgSetUserPermissionsResponse {} \ No newline at end of file +message MsgSetPermissionsResponse {} \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/query.proto b/proto/desmos/subspaces/v1/query.proto index 44d2cdcf74..c99f0df7cc 100644 --- a/proto/desmos/subspaces/v1/query.proto +++ b/proto/desmos/subspaces/v1/query.proto @@ -86,7 +86,7 @@ message QueryUserGroupsRequest { // QueryUserGroupsResponse is the response type for the Query/UserGroups RPC // method message QueryUserGroupsResponse { - repeated string groups = 1 [ (gogoproto.nullable) = false ]; + repeated string groups = 1; cosmos.base.query.v1beta1.PageResponse pagination = 2; } @@ -105,7 +105,7 @@ message QueryUserGroupMembersRequest { // QueryUserGroupMembersResponse is the response type for the // Query/UserGroupMembers RPC method message QueryUserGroupMembersResponse { - repeated string members = 1 [ (gogoproto.nullable) = false ]; + repeated string members = 1; cosmos.base.query.v1beta1.PageResponse pagination = 2; } diff --git a/x/profiles/types/models_chain_links.pb.go b/x/profiles/types/models_chain_links.pb.go index 654930d961..6ad3102b1a 100644 --- a/x/profiles/types/models_chain_links.pb.go +++ b/x/profiles/types/models_chain_links.pb.go @@ -124,7 +124,8 @@ type Proof struct { PubKey *types.Any `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty" yaml:"pub_key"` // Signature represents the hex-encoded signature of the PlainText value Signature string `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty" yaml:"signature"` - // PlainText represents the hex-encoded value signed in order to produce the Signature + // PlainText represents the hex-encoded value signed in order to produce the + // Signature PlainText string `protobuf:"bytes,3,opt,name=plain_text,json=plainText,proto3" json:"plain_text,omitempty" yaml:"plain_text"` } @@ -246,7 +247,8 @@ var xxx_messageInfo_Base58Address proto.InternalMessageInfo type HexAddress struct { // Value represents the hex address value Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` - // Prefix represents the optional prefix used during address encoding (e.g. 0x) + // Prefix represents the optional prefix used during address encoding (e.g. + // 0x) Prefix string `protobuf:"bytes,2,opt,name=prefix,proto3" json:"prefix,omitempty" yaml:"prefix"` } diff --git a/x/subspaces/handler.go b/x/subspaces/handler.go new file mode 100644 index 0000000000..fb20f6d374 --- /dev/null +++ b/x/subspaces/handler.go @@ -0,0 +1,50 @@ +package subspaces + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/gogo/protobuf/proto" + + keeper2 "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// NewHandler returns a handler for subspaces type messages +func NewHandler(k keeper2.Keeper) sdk.Handler { + msgServer := keeper2.NewMsgServerImpl(k) + + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + switch msg := msg.(type) { + case *types2.MsgCreateSubspace: + res, err := msgServer.CreateSubspace(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types2.MsgEditSubspace: + res, err := msgServer.EditSubspace(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types2.MsgAddAdmin: + res, err := msgServer.AddAdmin(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types2.MsgRemoveAdmin: + res, err := msgServer.RemoveAdmin(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types2.MsgRegisterUser: + res, err := msgServer.RegisterUser(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types2.MsgUnregisterUser: + res, err := msgServer.UnregisterUser(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types2.MsgBanUser: + res, err := msgServer.BanUser(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types2.MsgUnbanUser: + res, err := msgServer.UnbanUser(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + + default: + return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, + "unrecognized %s message type: %v", types2.ModuleName, proto.MessageName(msg)) + } + } +} diff --git a/x/subspaces/keeper/alias_functions.go b/x/subspaces/keeper/alias_functions.go new file mode 100644 index 0000000000..35a3048e34 --- /dev/null +++ b/x/subspaces/keeper/alias_functions.go @@ -0,0 +1,172 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// IterateSubspaces iterates through the subspaces set and performs the given function +func (k Keeper) IterateSubspaces(ctx sdk.Context, fn func(index int64, subspace types2.Subspace) (stop bool)) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types2.SubspaceStorePrefix) + defer iterator.Close() + + i := int64(0) + for ; iterator.Valid(); iterator.Next() { + var subspace types2.Subspace + k.cdc.MustUnmarshal(iterator.Value(), &subspace) + stop := fn(i, subspace) + if stop { + break + } + i++ + } +} + +// GetAllSubspaces returns a list of all the subspaces that have been store inside the given context +func (k Keeper) GetAllSubspaces(ctx sdk.Context) []types2.Subspace { + var subspaces []types2.Subspace + k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { + subspaces = append(subspaces, subspace) + return false + }) + + return subspaces +} + +// IterateSubspaceAdmins iterates over all the admins of the subspace having the given id +func (k Keeper) IterateSubspaceAdmins(ctx sdk.Context, id string, fn func(index int64, admin string) (stop bool)) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types2.SubspaceAdminsPrefix(id)) + defer iterator.Close() + + i := int64(0) + for ; iterator.Valid(); iterator.Next() { + stop := fn(i, string(iterator.Value())) + if stop { + break + } + i++ + } +} + +// GetAllAdmins returns the entries containing the data of all the admins of all the subspaces +func (k Keeper) GetAllAdmins(ctx sdk.Context) []types2.UsersEntry { + var entries []types2.UsersEntry + k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { + + var admins []string + k.IterateSubspaceAdmins(ctx, subspace.ID, func(_ int64, admin string) (stop bool) { + admins = append(admins, admin) + return false + }) + + entries = append(entries, types2.NewUsersEntry(subspace.ID, admins)) + return false + }) + + return entries +} + +// IterateSubspaceRegisteredUsers iterates over all the registered users of the subspace having the given id +func (k Keeper) IterateSubspaceRegisteredUsers(ctx sdk.Context, id string, fn func(index int64, user string) (stop bool)) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types2.SubspaceRegisteredUsersPrefix(id)) + defer iterator.Close() + + i := int64(0) + for ; iterator.Valid(); iterator.Next() { + stop := fn(i, string(iterator.Value())) + if stop { + break + } + i++ + } +} + +// GetAllRegisteredUsers returns the entries containing the data of all the registered users of all the subspaces +func (k Keeper) GetAllRegisteredUsers(ctx sdk.Context) []types2.UsersEntry { + var entries []types2.UsersEntry + k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { + + var users []string + k.IterateSubspaceRegisteredUsers(ctx, subspace.ID, func(_ int64, user string) (stop bool) { + users = append(users, user) + return false + }) + + entries = append(entries, types2.NewUsersEntry(subspace.ID, users)) + return false + }) + + return entries +} + +// IterateSubspaceBannedUsers iterates over all the banned users of the subspace having the given id +func (k Keeper) IterateSubspaceBannedUsers(ctx sdk.Context, id string, fn func(index int64, user string) (stop bool)) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types2.SubspaceBannedUsersPrefix(id)) + defer iterator.Close() + + i := int64(0) + for ; iterator.Valid(); iterator.Next() { + stop := fn(i, string(iterator.Value())) + if stop { + break + } + i++ + } +} + +// GetAllBannedUsers returns the entries containing the data of all the banned users of all the subspaces +func (k Keeper) GetAllBannedUsers(ctx sdk.Context) []types2.UsersEntry { + var entries []types2.UsersEntry + k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { + + var users []string + k.IterateSubspaceBannedUsers(ctx, subspace.ID, func(_ int64, user string) (stop bool) { + users = append(users, user) + return false + }) + + entries = append(entries, types2.NewUsersEntry(subspace.ID, users)) + return false + }) + + return entries +} + +// checkSubspaceAdmin checks if the subspace with the given id exists and +// if the address belongs to the owner of the subspace or one of its admins. +func (k Keeper) checkSubspaceAdmin(ctx sdk.Context, id, address string) error { + subspace, found := k.GetSubspace(ctx, id) + if !found { + return sdkerrors.Wrapf(types2.ErrInvalidSubspaceID, "the subspace with id %s doesn't exist", id) + } + + if subspace.Owner != address { + store := ctx.KVStore(k.storeKey) + if !store.Has(types2.SubspaceAdminKey(subspace.ID, address)) { + return sdkerrors.Wrapf(types2.ErrInvalidSubspaceAdmin, address) + } + } + + return nil +} + +// checkSubspaceOwner checks if the subspace with the given id exists and +// if the address belongs to the owner of the subspace. +func (k Keeper) checkSubspaceOwner(ctx sdk.Context, id, address string) error { + subspace, found := k.GetSubspace(ctx, id) + if !found { + return sdkerrors.Wrapf(types2.ErrInvalidSubspaceID, "the subspace with id %s doesn't exist", id) + } + + if subspace.Owner != address { + return sdkerrors.Wrapf(types2.ErrInvalidSubspaceOwner, address) + } + + return nil +} diff --git a/x/subspaces/keeper/alias_functions_test.go b/x/subspaces/keeper/alias_functions_test.go new file mode 100644 index 0000000000..07f6d00f9a --- /dev/null +++ b/x/subspaces/keeper/alias_functions_test.go @@ -0,0 +1,411 @@ +package keeper_test + +import ( + "time" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (suite *KeeperTestsuite) TestKeeper_IterateSubspace() { + date, err := time.Parse(time.RFC3339, "2010-10-02T12:10:00.000Z") + suite.NoError(err) + + subspaces := []*types2.Subspace{ + { + ID: "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + Name: "mooncake", + Owner: "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + Creator: "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + CreationTime: date, + Type: types2.SubspaceTypeOpen, + }, + { + ID: "dd065b70feb810a8c6f535cf670fe6e3534085221fa964ed2660ebca93f910d1", + Name: "star", + Owner: "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + Creator: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + CreationTime: date, + Type: types2.SubspaceTypeOpen, + }, + { + ID: "e1ba4807a15d8579f79cfd90a07fc015e6125565c9271eb94aded0b2ebf86163", + Name: "bad", + Owner: "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + Creator: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + CreationTime: date, + Type: types2.SubspaceTypeOpen, + }, + } + + expSubspaces := []*types2.Subspace{ + subspaces[0], + subspaces[1], + } + + for _, subspace := range subspaces { + _ = suite.k.SaveSubspace(suite.ctx, *subspace, subspace.Owner) + } + + var validSubspaces []*types2.Subspace + suite.k.IterateSubspaces(suite.ctx, func(index int64, subspace types2.Subspace) (stop bool) { + if index == 2 { + return false + } + validSubspaces = append(validSubspaces, &subspace) + return false + }) + + suite.Len(expSubspaces, len(validSubspaces)) + suite.Equal(expSubspaces, validSubspaces) +} + +func (suite *KeeperTestsuite) TestKeeper_GetAllSubspaces() { + tests := []struct { + name string + store func(ctx sdk.Context) + expSubspaces []types2.Subspace + }{ + { + name: "Returns all the subspaces", + store: func(ctx sdk.Context) { + sub1 := types2.NewSubspace( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + err := suite.k.SaveSubspace(ctx, sub1, sub1.Owner) + suite.Require().NoError(err) + + sub2 := types2.NewSubspace( + "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", + "mooncake", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + err = suite.k.SaveSubspace(ctx, sub2, sub2.Owner) + suite.Require().NoError(err) + }, + expSubspaces: []types2.Subspace{ + types2.NewSubspace( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + types2.NewSubspace( + "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", + "mooncake", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + }, + { + name: "Returns an empty slice with no subspaces", + expSubspaces: nil, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + subspaces := suite.k.GetAllSubspaces(suite.ctx) + suite.Equal(test.expSubspaces, subspaces) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_IterateSubspaceAdmins() { + subspace := types2.NewSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "mooncake", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ) + suite.Require().NoError(suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner)) + + admins := []string{ + "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", + } + for _, admin := range admins { + suite.Require().NoError(suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, admin, subspace.Owner)) + } + + var iterated = 0 + suite.k.IterateSubspaceAdmins(suite.ctx, subspace.ID, func(index int64, admin string) (stop bool) { + iterated++ + suite.Require().Contains(admins, admin) + return false + }) +} + +func (suite *KeeperTestsuite) TestKeeper_GetAllAdmins() { + data := map[types2.Subspace][]string{ + types2.NewSubspace( + "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", + "mooncake1", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ): { + "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", + }, + types2.NewSubspace( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + "mooncake2", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ): { + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", + }, + types2.NewSubspace( + "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", + "mooncake3", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ): {}, + } + + for subspace, admins := range data { + err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + for _, admin := range admins { + err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, admin, subspace.Owner) + suite.Require().NoError(err) + } + } + + expected := []types2.UsersEntry{ + types2.NewUsersEntry( + "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", + []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, + ), + types2.NewUsersEntry( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + []string{ + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", + }, + ), + types2.NewUsersEntry( + "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", + nil, + ), + } + + stored := suite.k.GetAllAdmins(suite.ctx) + suite.Require().Equal(expected, stored) +} + +func (suite *KeeperTestsuite) TestKeeper_IterateSubspaceRegisteredUsers() { + subspace := types2.NewSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "mooncake", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ) + suite.Require().NoError(suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner)) + + admins := []string{ + "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", + } + for _, admin := range admins { + suite.Require().NoError(suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, admin, subspace.Owner)) + } + + var iterated = 0 + suite.k.IterateSubspaceRegisteredUsers(suite.ctx, subspace.ID, func(index int64, admin string) (stop bool) { + iterated++ + suite.Require().Contains(admins, admin) + return false + }) +} + +func (suite *KeeperTestsuite) TestKeeper_GetAllRegisteredUsers() { + data := map[types2.Subspace][]string{ + types2.NewSubspace( + "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", + "mooncake1", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ): { + "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", + }, + types2.NewSubspace( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + "mooncake2", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ): { + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", + }, + types2.NewSubspace( + "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", + "mooncake3", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ): {}, + } + + for subspace, users := range data { + err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + for _, admin := range users { + err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, admin, subspace.Owner) + suite.Require().NoError(err) + } + } + + expected := []types2.UsersEntry{ + types2.NewUsersEntry( + "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", + []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, + ), + types2.NewUsersEntry( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + []string{ + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", + }, + ), + types2.NewUsersEntry( + "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", + nil, + ), + } + + stored := suite.k.GetAllRegisteredUsers(suite.ctx) + suite.Require().Equal(expected, stored) +} + +func (suite *KeeperTestsuite) TestKeeper_IterateSubspaceBannedUsers() { + subspace := types2.NewSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "mooncake", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ) + suite.Require().NoError(suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner)) + + admins := []string{ + "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", + } + for _, admin := range admins { + suite.Require().NoError(suite.k.BanUserInSubspace(suite.ctx, subspace.ID, admin, subspace.Owner)) + } + + var iterated = 0 + suite.k.IterateSubspaceBannedUsers(suite.ctx, subspace.ID, func(index int64, admin string) (stop bool) { + iterated++ + suite.Require().Contains(admins, admin) + return false + }) +} + +func (suite *KeeperTestsuite) TestKeeper_GetAllBannedUsers() { + data := map[types2.Subspace][]string{ + types2.NewSubspace( + "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", + "mooncake1", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ): { + "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", + }, + types2.NewSubspace( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + "mooncake2", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ): { + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", + }, + types2.NewSubspace( + "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", + "mooncake3", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + types2.SubspaceTypeOpen, + time.Now(), + ): {}, + } + + for subspace, users := range data { + err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + for _, admin := range users { + err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, admin, subspace.Owner) + suite.Require().NoError(err) + } + } + + expected := []types2.UsersEntry{ + types2.NewUsersEntry( + "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", + []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, + ), + types2.NewUsersEntry( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + []string{ + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", + }, + ), + types2.NewUsersEntry( + "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", + nil, + ), + } + + stored := suite.k.GetAllBannedUsers(suite.ctx) + suite.Require().Equal(expected, stored) +} diff --git a/x/subspaces/keeper/common_test.go b/x/subspaces/keeper/common_test.go new file mode 100644 index 0000000000..8bff55144e --- /dev/null +++ b/x/subspaces/keeper/common_test.go @@ -0,0 +1,59 @@ +package keeper_test + +import ( + "testing" + + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + paramstypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/stretchr/testify/suite" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + db "github.com/tendermint/tm-db" + + "github.com/desmos-labs/desmos/v2/app" +) + +type KeeperTestsuite struct { + suite.Suite + + cdc codec.Codec + legacyAminoCdc *codec.LegacyAmino + ctx sdk.Context + k keeper.Keeper + paramsKeeper paramskeeper.Keeper + storeKey sdk.StoreKey +} + +func (suite *KeeperTestsuite) SetupTest() { + // Define store keys + keys := sdk.NewMemoryStoreKeys(types.StoreKey, paramstypes.StoreKey) + + suite.storeKey = keys[types.StoreKey] + + // Create an in-memory db + memDB := db.NewMemDB() + ms := store.NewCommitMultiStore(memDB) + for _, key := range keys { + ms.MountStoreWithDB(key, sdk.StoreTypeIAVL, memDB) + } + + if err := ms.LoadLatestVersion(); err != nil { + panic(err) + } + + suite.ctx = sdk.NewContext(ms, tmproto.Header{ChainID: "test-chain"}, false, log.NewNopLogger()) + suite.cdc, suite.legacyAminoCdc = app.MakeCodecs() + + // Define keeper + suite.k = keeper.NewKeeper(suite.storeKey, suite.cdc) +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestsuite)) +} diff --git a/x/subspaces/keeper/genesis.go b/x/subspaces/keeper/genesis.go new file mode 100644 index 0000000000..099637daac --- /dev/null +++ b/x/subspaces/keeper/genesis.go @@ -0,0 +1,75 @@ +package keeper + +import ( + "fmt" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// ExportGenesis returns the GenesisState associated with the given context +func (k Keeper) ExportGenesis(ctx sdk.Context) *types2.GenesisState { + return types2.NewGenesisState( + k.GetAllSubspaces(ctx), + k.GetAllAdmins(ctx), + k.GetAllRegisteredUsers(ctx), + k.GetAllBannedUsers(ctx), + ) +} + +// InitGenesis initializes the chain state based on the given GenesisState +func (k Keeper) InitGenesis(ctx sdk.Context, data *types2.GenesisState) { + // Initialize the subspaces + for _, subspace := range data.Subspaces { + err := k.SaveSubspace(ctx, subspace, subspace.Owner) + if err != nil { + panic(err) + } + } + + // Initialize the admins + for _, entry := range data.Admins { + subspace, found := k.GetSubspace(ctx, entry.SubspaceID) + if !found { + panic(fmt.Errorf("invalid admins entry: subspace with id %s does not exist", entry.SubspaceID)) + } + + for _, admin := range entry.Users { + err := k.AddAdminToSubspace(ctx, subspace.ID, admin, subspace.Owner) + if err != nil { + panic(err) + } + } + } + + // Initialize the registered users + for _, entry := range data.RegisteredUsers { + subspace, found := k.GetSubspace(ctx, entry.SubspaceID) + if !found { + panic(fmt.Errorf("invalid registered user entry: subspace with id %s does not exist", entry.SubspaceID)) + } + + for _, user := range entry.Users { + err := k.RegisterUserInSubspace(ctx, subspace.ID, user, subspace.Owner) + if err != nil { + panic(err) + } + } + } + + // Initialize the banned users + for _, entry := range data.BannedUsers { + subspace, found := k.GetSubspace(ctx, entry.SubspaceID) + if !found { + panic(fmt.Errorf("invalid banned user entry: subspace with id %s does not exist", entry.SubspaceID)) + } + + for _, user := range entry.Users { + err := k.BanUserInSubspace(ctx, subspace.ID, user, subspace.Owner) + if err != nil { + panic(err) + } + } + } +} diff --git a/x/subspaces/keeper/genesis_test.go b/x/subspaces/keeper/genesis_test.go new file mode 100644 index 0000000000..838065a423 --- /dev/null +++ b/x/subspaces/keeper/genesis_test.go @@ -0,0 +1,342 @@ +package keeper_test + +import ( + "time" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { + tests := []struct { + name string + store func(ctx sdk.Context) + expected *types2.GenesisState + }{ + { + name: "Default expected state", + expected: &types2.GenesisState{Subspaces: nil}, + }, + { + name: "Genesis exported successfully", + store: func(ctx sdk.Context) { + + subspace := types2.NewSubspace( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", subspace.Owner) + suite.Require().NoError(err) + }, + expected: types2.NewGenesisState( + []types2.Subspace{ + types2.NewSubspace( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + []types2.UsersEntry{ + types2.NewUsersEntry( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, + ), + }, + []types2.UsersEntry{ + types2.NewUsersEntry( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + []string{"cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"}, + ), + }, + []types2.UsersEntry{ + types2.NewUsersEntry( + "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", + []string{"cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0"}, + ), + }, + ), + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + exported := suite.k.ExportGenesis(suite.ctx) + suite.Equal(test.expected, exported) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_InitGenesis() { + tests := []struct { + name string + genesis *types2.GenesisState + expError bool + check func(ctx sdk.Context) + }{ + { + name: "Default genesis is initialized properly", + genesis: types2.DefaultGenesisState(), + expError: false, + }, + { + name: "Invalid subspace panics", + genesis: types2.NewGenesisState( + []types2.Subspace{ + types2.NewSubspace( + "", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + nil, + nil, + nil, + ), + expError: true, + }, + { + name: "Admins entry for non existing subspace returns error", + genesis: types2.NewGenesisState( + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"}, + ), + }, + nil, + nil, + ), + expError: true, + }, + { + name: "Duplicated admins returns error", + genesis: types2.NewGenesisState( + []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{ + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + }, + ), + }, + nil, + nil, + ), + expError: true, + }, + { + name: "Registered users entry for non existing subspace returns error", + genesis: types2.NewGenesisState( + nil, + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"}, + ), + }, + nil, + ), + expError: true, + }, + { + name: "Duplicated registered users returns error", + genesis: types2.NewGenesisState( + []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{ + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + }, + ), + }, + nil, + ), + expError: true, + }, + { + name: "Banned users entry for non existing subspace returns error", + genesis: types2.NewGenesisState( + nil, + nil, + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"}, + ), + }, + ), + expError: true, + }, + { + name: "Duplicated banned users returns error", + genesis: types2.NewGenesisState( + []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + nil, + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{ + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + }, + ), + }, + ), + expError: true, + }, + { + name: "Valid genesis initialized correctly", + genesis: types2.NewGenesisState( + []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 0, 00, 00, 000, time.UTC), + ), + }, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"}, + ), + }, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, + ), + }, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0"}, + ), + }, + ), + check: func(ctx sdk.Context) { + subspace, found := suite.k.GetSubspace(ctx, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e") + suite.Require().True(found) + suite.Require().True(subspace.Equal(types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 0, 00, 00, 000, time.UTC), + ))) + + suite.Require().Equal( + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"}, + ), + }, + suite.k.GetAllAdmins(ctx), + ) + + suite.Require().Equal( + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, + ), + }, + suite.k.GetAllRegisteredUsers(ctx), + ) + + suite.Require().Equal( + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0"}, + ), + }, + suite.k.GetAllBannedUsers(ctx), + ) + }, + expError: false, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + + if test.expError { + suite.Require().Panics(func() { suite.k.InitGenesis(suite.ctx, test.genesis) }) + } else { + suite.k.InitGenesis(suite.ctx, test.genesis) + if test.check != nil { + test.check(suite.ctx) + } + } + }) + } +} diff --git a/x/subspaces/keeper/grpc_query.go b/x/subspaces/keeper/grpc_query.go new file mode 100644 index 0000000000..d7b668685e --- /dev/null +++ b/x/subspaces/keeper/grpc_query.go @@ -0,0 +1,126 @@ +package keeper + +import ( + "context" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +var _ types2.QueryServer = Keeper{} + +func (k Keeper) Subspace(ctx context.Context, request *types2.QuerySubspaceRequest) (*types2.QuerySubspaceResponse, error) { + if !types2.IsValidSubspace(request.SubspaceId) { + return nil, sdkerrors.Wrap(types2.ErrInvalidSubspaceID, request.SubspaceId) + } + + sdkCtx := sdk.UnwrapSDKContext(ctx) + subspace, found := k.GetSubspace(sdkCtx, request.SubspaceId) + if !found { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "subspace with id %s not found", request.SubspaceId) + } + + return &types2.QuerySubspaceResponse{Subspace: subspace}, nil +} + +func (k Keeper) Subspaces(goCtx context.Context, request *types2.QuerySubspacesRequest) (*types2.QuerySubspacesResponse, error) { + var subspaces []types2.Subspace + ctx := sdk.UnwrapSDKContext(goCtx) + + store := ctx.KVStore(k.storeKey) + subspacesStore := prefix.NewStore(store, types2.SubspaceStorePrefix) + + pageRes, err := query.Paginate(subspacesStore, request.Pagination, func(key []byte, value []byte) error { + var subspace types2.Subspace + if err := k.cdc.Unmarshal(value, &subspace); err != nil { + return status.Error(codes.Internal, err.Error()) + } + + subspaces = append(subspaces, subspace) + return nil + }) + + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types2.QuerySubspacesResponse{Subspaces: subspaces, Pagination: pageRes}, nil +} + +func (k Keeper) Admins(goCtx context.Context, request *types2.QueryAdminsRequest) (*types2.QueryAdminsResponse, error) { + if !types2.IsValidSubspace(request.SubspaceId) { + return nil, sdkerrors.Wrap(types2.ErrInvalidSubspaceID, request.SubspaceId) + } + + var admins []string + ctx := sdk.UnwrapSDKContext(goCtx) + + store := ctx.KVStore(k.storeKey) + subspacesStore := prefix.NewStore(store, types2.SubspaceAdminsPrefix(request.SubspaceId)) + + pageRes, err := query.Paginate(subspacesStore, request.Pagination, func(_ []byte, value []byte) error { + admin := string(value) + admins = append(admins, admin) + return nil + }) + + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types2.QueryAdminsResponse{Admins: admins, Pagination: pageRes}, nil +} + +func (k Keeper) RegisteredUsers(goCtx context.Context, request *types2.QueryRegisteredUsersRequest) (*types2.QueryRegisteredUsersResponse, error) { + if !types2.IsValidSubspace(request.SubspaceId) { + return nil, sdkerrors.Wrap(types2.ErrInvalidSubspaceID, request.SubspaceId) + } + + var users []string + ctx := sdk.UnwrapSDKContext(goCtx) + + store := ctx.KVStore(k.storeKey) + subspacesStore := prefix.NewStore(store, types2.SubspaceRegisteredUsersPrefix(request.SubspaceId)) + + pageRes, err := query.Paginate(subspacesStore, request.Pagination, func(_ []byte, value []byte) error { + user := string(value) + users = append(users, user) + return nil + }) + + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types2.QueryRegisteredUsersResponse{Users: users, Pagination: pageRes}, nil +} + +func (k Keeper) BannedUsers(goCtx context.Context, request *types2.QueryBannedUsersRequest) (*types2.QueryBannedUsersResponse, error) { + if !types2.IsValidSubspace(request.SubspaceId) { + return nil, sdkerrors.Wrap(types2.ErrInvalidSubspaceID, request.SubspaceId) + } + + var users []string + ctx := sdk.UnwrapSDKContext(goCtx) + + store := ctx.KVStore(k.storeKey) + subspacesStore := prefix.NewStore(store, types2.SubspaceBannedUsersPrefix(request.SubspaceId)) + + pageRes, err := query.Paginate(subspacesStore, request.Pagination, func(_ []byte, value []byte) error { + user := string(value) + users = append(users, user) + return nil + }) + + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types2.QueryBannedUsersResponse{Users: users, Pagination: pageRes}, nil +} diff --git a/x/subspaces/keeper/grpc_query_test.go b/x/subspaces/keeper/grpc_query_test.go new file mode 100644 index 0000000000..8c84e8c4dd --- /dev/null +++ b/x/subspaces/keeper/grpc_query_test.go @@ -0,0 +1,348 @@ +package keeper_test + +import ( + "time" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" +) + +func (suite *KeeperTestsuite) TestQueryServer_Subspace() { + tests := []struct { + name string + store func(ctx sdk.Context) + request *types2.QuerySubspaceRequest + shouldErr bool + expResponse *types2.QuerySubspaceResponse + }{ + { + name: "Invalid subspace id returns error", + request: types2.NewQuerySubspaceRequest("123"), + shouldErr: true, + }, + { + name: "Not found subspace returns error", + request: types2.NewQuerySubspaceRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + shouldErr: true, + }, + { + name: "Found subspace is returned properly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + request: types2.NewQuerySubspaceRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + shouldErr: false, + expResponse: &types2.QuerySubspaceResponse{ + Subspace: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + response, err := suite.k.Subspace(sdk.WrapSDKContext(suite.ctx), test.request) + if test.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(test.expResponse, response) + } + }) + } +} + +func (suite *KeeperTestsuite) TestQueryServer_Subspaces() { + tests := []struct { + name string + store func(ctx sdk.Context) + req *types2.QuerySubspacesRequest + expSubspaces []types2.Subspace + }{ + + { + name: "Invalid pagination returns empty slice", + req: types2.NewQuerySubspacesRequest(&query.PageRequest{ + Limit: 1, + Offset: 1, + }), + expSubspaces: nil, + }, + { + name: "Valid pagination returns result properly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + req: &types2.QuerySubspacesRequest{}, + expSubspaces: []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + res, err := suite.k.Subspaces(sdk.WrapSDKContext(suite.ctx), test.req) + suite.Require().NoError(err) + suite.Require().Equal(test.expSubspaces, res.Subspaces) + }) + } +} + +func (suite *KeeperTestsuite) TestQueryServer_Admins() { + tests := []struct { + name string + store func(ctx sdk.Context) + req *types2.QueryAdminsRequest + shouldErr bool + expAdmins []string + }{ + { + name: "Invalid subspace id returns error", + req: types2.NewQueryAdminsRequest("123", nil), + shouldErr: true, + }, + { + name: "Non existing subspace returns empty slice", + req: types2.NewQueryAdminsRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), + shouldErr: false, + expAdmins: nil, + }, + { + name: "Requests pagination works properly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) + suite.Require().NoError(err) + }, + req: types2.NewQueryAdminsRequest( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + &query.PageRequest{ + Offset: 1, + Limit: 1, + }, + ), + expAdmins: []string{ + "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + res, err := suite.k.Admins(sdk.WrapSDKContext(suite.ctx), test.req) + if test.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(test.expAdmins, res.Admins) + } + }) + } +} + +func (suite *KeeperTestsuite) TestQueryServer_RegisteredUsers() { + tests := []struct { + name string + store func(ctx sdk.Context) + req *types2.QueryRegisteredUsersRequest + shouldErr bool + expUsers []string + }{ + { + name: "Invalid subspace id returns error", + req: types2.NewQueryRegisteredUsersRequest("123", nil), + shouldErr: true, + }, + { + name: "Non existing subspace returns empty slice", + req: types2.NewQueryRegisteredUsersRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), + shouldErr: false, + expUsers: nil, + }, + { + name: "Requests pagination works properly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) + suite.Require().NoError(err) + }, + req: types2.NewQueryRegisteredUsersRequest( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + &query.PageRequest{ + Offset: 1, + Limit: 1, + }, + ), + expUsers: []string{ + "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + res, err := suite.k.RegisteredUsers(sdk.WrapSDKContext(suite.ctx), test.req) + if test.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(test.expUsers, res.Users) + } + }) + } +} + +func (suite *KeeperTestsuite) TestQueryServer_BannedUsers() { + tests := []struct { + name string + store func(ctx sdk.Context) + req *types2.QueryBannedUsersRequest + shouldErr bool + expUsers []string + }{ + { + name: "Invalid subspace id returns error", + req: types2.NewQueryBannedUsersRequest("123", nil), + shouldErr: true, + }, + { + name: "Non existing subspace returns empty slice", + req: types2.NewQueryBannedUsersRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), + shouldErr: false, + expUsers: nil, + }, + { + name: "Requests pagination works properly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) + suite.Require().NoError(err) + }, + req: types2.NewQueryBannedUsersRequest( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + &query.PageRequest{ + Offset: 1, + Limit: 1, + }, + ), + expUsers: []string{ + "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + res, err := suite.k.BannedUsers(sdk.WrapSDKContext(suite.ctx), test.req) + if test.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(test.expUsers, res.Users) + } + }) + } +} diff --git a/x/subspaces/keeper/invariants.go b/x/subspaces/keeper/invariants.go new file mode 100644 index 0000000000..655b03ecac --- /dev/null +++ b/x/subspaces/keeper/invariants.go @@ -0,0 +1,50 @@ +package keeper + +import ( + "fmt" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// RegisterInvariants registers all subspaces invariants +func RegisterInvariants(ir sdk.InvariantRegistry, keeper Keeper) { + ir.RegisterRoute(types2.ModuleName, "valid-subspaces", + ValidSubspacesInvariant(keeper)) +} + +// AllInvariants runs all invariants of the module +func AllInvariants(k Keeper) sdk.Invariant { + return func(ctx sdk.Context) (string, bool) { + if res, stop := ValidSubspacesInvariant(k)(ctx); stop { + return res, stop + } + return "Every invariant condition is fulfilled correctly", true + } +} + +// formatOutputSubspaces concatenate the subspaces given into a unique string +func formatOutputSubspaces(subspaces []types2.Subspace) (outputSubspaces string) { + for _, subspace := range subspaces { + outputSubspaces += subspace.ID + "\n" + } + return outputSubspaces +} + +// ValidSubspacesInvariant checks that all the subspaces are valid +func ValidSubspacesInvariant(k Keeper) sdk.Invariant { + return func(ctx sdk.Context) (string, bool) { + var invalidSubspaces []types2.Subspace + k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { + if err := subspace.Validate(); err != nil { + invalidSubspaces = append(invalidSubspaces, subspace) + } + return false + }) + + return sdk.FormatInvariant(types2.ModuleName, "invalid subspaces", + fmt.Sprintf("the following subspaces are invalid:\n %s", formatOutputSubspaces(invalidSubspaces)), + ), invalidSubspaces != nil + } +} diff --git a/x/subspaces/keeper/invariants_test.go b/x/subspaces/keeper/invariants_test.go new file mode 100644 index 0000000000..3eb759326a --- /dev/null +++ b/x/subspaces/keeper/invariants_test.go @@ -0,0 +1,64 @@ +package keeper_test + +import ( + "time" + + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (suite *KeeperTestsuite) TestInvariants() { + tests := []struct { + name string + store func(ctx sdk.Context) + expStop bool + }{ + { + name: "All invariants are not violated", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + expStop: true, + }, + { + name: "Valid subspace invariant violated", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC), + ) + _ = suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + }, + expStop: true, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + _, stop := keeper.AllInvariants(suite.k)(suite.ctx) + suite.Require().Equal(test.expStop, stop) + }) + } +} diff --git a/x/subspaces/keeper/keeper.go b/x/subspaces/keeper/keeper.go new file mode 100644 index 0000000000..22f417d003 --- /dev/null +++ b/x/subspaces/keeper/keeper.go @@ -0,0 +1,230 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/tendermint/tendermint/libs/log" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +type Keeper struct { + storeKey sdk.StoreKey + cdc codec.BinaryCodec +} + +// NewKeeper creates new instances of the subspaces keeper +func NewKeeper(storeKey sdk.StoreKey, cdc codec.BinaryCodec) Keeper { + return Keeper{ + storeKey: storeKey, + cdc: cdc, + } +} + +// Logger returns a module-specific logger. +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", "x/"+types.ModuleName) +} + +// SaveSubspace saves the given subspace inside the current context. +func (k Keeper) SaveSubspace(ctx sdk.Context, subspace types.Subspace, user string) error { + err := subspace.Validate() + if err != nil { + return err + } + + storedSubspace, found := k.GetSubspace(ctx, subspace.ID) + + // Check the editor when the user is trying to edit the subspace + if found && storedSubspace.Owner != user { + return sdkerrors.Wrapf(types.ErrInvalidSubspaceOwner, user) + } + + store := ctx.KVStore(k.storeKey) + key := types.SubspaceStoreKey(subspace.ID) + store.Set(key, k.cdc.MustMarshal(&subspace)) + + k.Logger(ctx).Info("saved subspace", "id", subspace.ID, "owner", subspace.Owner) + return nil +} + +// DoesSubspaceExist checks if the subspace with the given id exists. +func (k Keeper) DoesSubspaceExist(ctx sdk.Context, subspaceID string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.SubspaceStoreKey(subspaceID)) +} + +// GetSubspace returns the subspace associated with the given ID. +// If there is no subspace associated with the given ID the function will return an empty subspace and false. +func (k Keeper) GetSubspace(ctx sdk.Context, subspaceID string) (subspace types.Subspace, found bool) { + if !k.DoesSubspaceExist(ctx, subspaceID) { + return types.Subspace{}, false + } + + store := ctx.KVStore(k.storeKey) + k.cdc.MustUnmarshal(store.Get(types.SubspaceStoreKey(subspaceID)), &subspace) + return subspace, true +} + +// IsAdmin returns true iff the given user is an admin of the subspace with the given id +func (k Keeper) IsAdmin(ctx sdk.Context, subspaceID string, user string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.SubspaceAdminKey(subspaceID, user)) +} + +// AddAdminToSubspace sets the given user as an admin of the subspace having the given id. +// Returns an error if the user is already an admin or the subspace does not exist. +func (k Keeper) AddAdminToSubspace(ctx sdk.Context, subspaceID, user, owner string) error { + // Check if the subspace exists and the owner is valid + err := k.checkSubspaceOwner(ctx, subspaceID, owner) + if err != nil { + return err + } + + // Check if the user we want to set as admin is already an admin + if k.IsAdmin(ctx, subspaceID, user) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "the user with address %s is already an admin", user) + } + + // Store the admin + store := ctx.KVStore(k.storeKey) + store.Set(types.SubspaceAdminKey(subspaceID, user), []byte(user)) + + k.Logger(ctx).Info("added admin", "subspace-id", subspaceID, "admin", user) + return nil +} + +// RemoveAdminFromSubspace removes the given user from the admin set of the subspace having the given id. +// It returns an error if the user was not an admin or the subspace does not exist. +func (k Keeper) RemoveAdminFromSubspace(ctx sdk.Context, subspaceID, user, owner string) error { + // Check if the subspace exists and the owner is valid + err := k.checkSubspaceOwner(ctx, subspaceID, owner) + if err != nil { + return err + } + + // Check if the user is not an admin + if !k.IsAdmin(ctx, subspaceID, user) { + return sdkerrors.Wrapf(types.ErrInvalidSubspaceAdmin, user) + } + + // Delete the admin + store := ctx.KVStore(k.storeKey) + store.Delete(types.SubspaceAdminKey(subspaceID, user)) + + k.Logger(ctx).Info("removed admin", "subspace-id", subspaceID, "admin", user) + return nil +} + +// IsRegistered returns true iff the given user is registered inside the subspace with the given id +func (k Keeper) IsRegistered(ctx sdk.Context, subspaceID, user string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.SubspaceRegisteredUserKey(subspaceID, user)) +} + +// RegisterUserInSubspace registers the given user inside the subspace with the given ID. +// It returns error if the user is already registered or the subspace does not exist. +func (k Keeper) RegisterUserInSubspace(ctx sdk.Context, subspaceID, user, admin string) error { + // Check if the subspace exists and the admin is an actual admin + err := k.checkSubspaceAdmin(ctx, subspaceID, admin) + if err != nil { + return err + } + + // Check if the user is already registered inside the subspace + if k.IsRegistered(ctx, subspaceID, user) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user already registered") + } + + // Store the new user + store := ctx.KVStore(k.storeKey) + store.Set(types.SubspaceRegisteredUserKey(subspaceID, user), []byte(user)) + return nil +} + +// UnregisterUserFromSubspace unregisters the given user from the subspace with the given ID. +// It returns error if the user is not registered or the subspace does not exist. +func (k Keeper) UnregisterUserFromSubspace(ctx sdk.Context, subspaceID, user, admin string) error { + // Check if the subspace exists and the admin is an actual admin + err := k.checkSubspaceAdmin(ctx, subspaceID, admin) + if err != nil { + return err + } + + // Check if the user is already registered inside the subspace + if !k.IsRegistered(ctx, subspaceID, user) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, + "the user with address : %s is not registered inside the subspace: %s", user, subspaceID) + } + + // Remove the user + store := ctx.KVStore(k.storeKey) + store.Delete(types.SubspaceRegisteredUserKey(subspaceID, user)) + return nil +} + +// IsBanned returns true iff the given user is banned inside the subspace with the given id +func (k Keeper) IsBanned(ctx sdk.Context, subspaceID, user string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.SubspaceBannedUserKey(subspaceID, user)) +} + +// BanUserInSubspace bans the given user inside the subspace with the given ID. +// It returns and error if the user is already blocked inside the subspace or the subspace does not exist. +func (k Keeper) BanUserInSubspace(ctx sdk.Context, subspaceID, user, admin string) error { + // Check if the subspace exists and the admin is an actual admin + err := k.checkSubspaceAdmin(ctx, subspaceID, admin) + if err != nil { + return err + } + + // Check if the user is already banned inside the subspace + if k.IsBanned(ctx, subspaceID, user) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user already banned") + } + + // Store the banned user + store := ctx.KVStore(k.storeKey) + store.Set(types.SubspaceBannedUserKey(subspaceID, user), []byte(user)) + return nil +} + +// UnbanUserInSubspace unbans the given user inside the subspace with the given ID. +// It returns error if the user is not banned inside the subspace or the subspace does not exist. +func (k Keeper) UnbanUserInSubspace(ctx sdk.Context, subspaceID, user, admin string) error { + // Check if the subspace exists and the admin is an actual admin + err := k.checkSubspaceAdmin(ctx, subspaceID, admin) + if err != nil { + return err + } + + // Check if the user is already banned inside the subspace + if !k.IsBanned(ctx, subspaceID, user) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "the user is not blocked inside the subspace") + } + + // Remove the banned user + store := ctx.KVStore(k.storeKey) + store.Delete(types.SubspaceBannedUserKey(subspaceID, user)) + return nil +} + +// CheckSubspaceUserPermission checks the permission of the given user inside the subspace with the +// given id to make sure they are able to perform operations inside it +func (k Keeper) CheckSubspaceUserPermission(ctx sdk.Context, subspaceID string, user string) error { + subspace, found := k.GetSubspace(ctx, subspaceID) + if !found { + return sdkerrors.Wrapf(types.ErrInvalidSubspaceID, subspaceID) + } + + if k.IsBanned(ctx, subspaceID, user) { + return sdkerrors.Wrapf(types.ErrPermissionDenied, user) + } + + if subspace.Type == types.SubspaceTypeClosed && !k.IsRegistered(ctx, subspaceID, user) { + return sdkerrors.Wrapf(types.ErrPermissionDenied, user) + } + + return nil +} diff --git a/x/subspaces/keeper/keeper_test.go b/x/subspaces/keeper/keeper_test.go new file mode 100644 index 0000000000..ec590dbd72 --- /dev/null +++ b/x/subspaces/keeper/keeper_test.go @@ -0,0 +1,908 @@ +package keeper_test + +import ( + "time" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (suite *KeeperTestsuite) TestKeeper_SaveSubspace() { + tests := []struct { + name string + storedSubspaces []types2.Subspace + subspaceToSave types2.Subspace + expErr bool + expStored []types2.Subspace + }{ + { + name: "Already stored subspace with different owner", + storedSubspaces: []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + subspaceToSave: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + expErr: true, + }, + { + name: "New subspace saved correctly", + subspaceToSave: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + expErr: false, + expStored: []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + }, + { + name: "Old subspace edited correctly", + storedSubspaces: []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + subspaceToSave: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test-updated", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeClosed, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + expErr: false, + expStored: []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test-updated", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeClosed, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + store := suite.ctx.KVStore(suite.storeKey) + for _, subspace := range test.storedSubspaces { + store.Set(types2.SubspaceStoreKey(subspace.ID), suite.cdc.MustMarshal(&subspace)) + } + + err := suite.k.SaveSubspace(suite.ctx, test.subspaceToSave, test.subspaceToSave.Owner) + if test.expErr { + suite.Error(err) + } else { + suite.NoError(err) + suite.Require().Equal(test.expStored, suite.k.GetAllSubspaces(suite.ctx)) + } + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_DoesSubspaceExists() { + tests := []struct { + name string + subspaceID string + storedSubspaces []types2.Subspace + exists bool + }{ + { + name: "Returns true when the subspace exists", + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + storedSubspaces: []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ), + }, + exists: true, + }, + { + name: "Return false when the subspace doesn't exist", + subspaceID: "123", + exists: false, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + for _, subspace := range test.storedSubspaces { + suite.Require().NoError(suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner)) + } + + exists := suite.k.DoesSubspaceExist(suite.ctx, test.subspaceID) + suite.Equal(test.exists, exists) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_GetSubspace() { + tests := []struct { + name string + store func(ctx sdk.Context) + subspaceID string + expFound bool + expSubspace types2.Subspace + }{ + { + name: "Return false when not found", + subspaceID: "123", + expFound: false, + }, + { + name: "Returns the subspace and true when found", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + expFound: true, + expSubspace: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ), + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + subspace, found := suite.k.GetSubspace(suite.ctx, test.subspaceID) + suite.Require().Equal(test.expFound, found) + + if test.expFound { + suite.Equal(test.expSubspace, subspace) + } + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_AddAdminToSubspace() { + tests := []struct { + name string + store func(ctx sdk.Context) + subspaceID string + user string + owner string + expError bool + expAdmins []string + }{ + { + name: "Non existent subspace returns error", + subspaceID: "", + expError: true, + }, + { + name: "User already an admin returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: true, + expAdmins: []string{ + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + { + name: "User added as admin correctly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: false, + expAdmins: []string{ + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + err := suite.k.AddAdminToSubspace(suite.ctx, test.subspaceID, test.user, test.owner) + if test.expError { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + } + + var admins []string + suite.k.IterateSubspaceAdmins(suite.ctx, test.subspaceID, func(index int64, admin string) (stop bool) { + admins = append(admins, admin) + return false + }) + suite.Require().Equal(test.expAdmins, admins) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_RemoveAdminFromSubspace() { + tests := []struct { + name string + store func(ctx sdk.Context) + subspaceID string + user string + owner string + expAdmins []string + expError bool + }{ + { + name: "Non existent subspace returns error", + subspaceID: "non-existing", + expError: true, + }, + { + name: "Invalid admin returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: true, + expAdmins: []string{ + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + { + name: "One of many admins is removed correctly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: false, + expAdmins: []string{ + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + { + name: "Single admin is removed correctly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: false, + expAdmins: nil, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + err := suite.k.RemoveAdminFromSubspace(suite.ctx, test.subspaceID, test.user, test.owner) + if test.expError { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + } + }) + + var admins []string + suite.k.IterateSubspaceAdmins(suite.ctx, test.subspaceID, func(index int64, admin string) (stop bool) { + admins = append(admins, admin) + return false + }) + suite.Require().Equal(test.expAdmins, admins) + } +} + +func (suite *KeeperTestsuite) TestKeeper_RegisterUserInSubspace() { + tests := []struct { + name string + store func(ctx sdk.Context) + subspaceID string + user string + admin string + expError bool + expUsers []string + }{ + { + name: "Non existent subspace returns error", + subspaceID: "non-existing", + expError: true, + }, + { + name: "User already registered returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: true, + expUsers: []string{ + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + { + name: "User registered correctly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: false, + expUsers: []string{ + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + err := suite.k.RegisterUserInSubspace(suite.ctx, test.subspaceID, test.user, test.admin) + if test.expError { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + } + + var users []string + suite.k.IterateSubspaceRegisteredUsers(suite.ctx, test.subspaceID, func(index int64, user string) (stop bool) { + users = append(users, user) + return false + }) + suite.Require().Equal(users, test.expUsers) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_UnregisterUserInSubspace() { + tests := []struct { + name string + store func(ctx sdk.Context) + subspaceID string + user string + admin string + expError bool + expUsers []string + }{ + { + name: "Non existent subspace returns error", + subspaceID: "non-existing", + expError: true, + }, + { + name: "Invalid user returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: true, + expUsers: []string{ + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + { + name: "Valid user unregistered correctly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: false, + expUsers: []string{ + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + err := suite.k.UnregisterUserFromSubspace(suite.ctx, test.subspaceID, test.user, test.admin) + if test.expError { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + } + }) + + var users []string + suite.k.IterateSubspaceRegisteredUsers(suite.ctx, test.subspaceID, func(index int64, user string) (stop bool) { + users = append(users, user) + return false + }) + suite.Require().Equal(users, test.expUsers) + } +} + +func (suite *KeeperTestsuite) TestKeeper_BanUser() { + tests := []struct { + name string + store func(ctx sdk.Context) + subspaceID string + user string + admin string + expError bool + expUsers []string + }{ + { + name: "Non existent subspace returns error", + subspaceID: "non-existing", + expError: true, + }, + { + name: "User already banned returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: true, + expUsers: []string{ + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + { + name: "User banned correctly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: false, + expUsers: []string{ + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + err := suite.k.BanUserInSubspace(suite.ctx, test.subspaceID, test.user, test.admin) + if test.expError { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + } + }) + + var users []string + suite.k.IterateSubspaceBannedUsers(suite.ctx, test.subspaceID, func(index int64, user string) (stop bool) { + users = append(users, user) + return false + }) + suite.Require().Equal(users, test.expUsers) + } +} + +func (suite *KeeperTestsuite) TestKeeper_UnbanUser() { + tests := []struct { + name string + store func(ctx sdk.Context) + subspaceID string + user string + admin string + expUsers []string + expError bool + }{ + { + name: "Non existent subspace returns error", + subspaceID: "non-existing", + expError: true, + }, + { + name: "Invalid user returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: true, + expUsers: []string{ + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + { + name: "User unbanned correctly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + expError: false, + expUsers: []string{ + "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + err := suite.k.UnbanUserInSubspace(suite.ctx, test.subspaceID, test.user, test.admin) + if test.expError { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + } + + var users []string + suite.k.IterateSubspaceBannedUsers(suite.ctx, test.subspaceID, func(index int64, user string) (stop bool) { + users = append(users, user) + return false + }) + suite.Require().Equal(users, test.expUsers) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_CheckSubspaceUserPermission() { + tests := []struct { + name string + store func(ctx sdk.Context) + subspaceID string + user string + expError bool + }{ + { + name: "Non existent subspace returns error", + subspaceID: "non-existing", + expError: true, + }, + { + name: "Banned user returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + expError: true, + }, + { + name: "Subspace types closed and not registered user returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeClosed, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + expError: true, + }, + { + name: "No errors", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Unix(1, 1), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) + suite.Require().NoError(err) + }, + subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + user: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", + expError: false, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + err := suite.k.CheckSubspaceUserPermission(suite.ctx, test.subspaceID, test.user) + if test.expError { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + } + }) + } +} diff --git a/x/subspaces/keeper/msg_server.go b/x/subspaces/keeper/msg_server.go new file mode 100644 index 0000000000..2e125ba311 --- /dev/null +++ b/x/subspaces/keeper/msg_server.go @@ -0,0 +1,186 @@ +package keeper + +import ( + "context" + "time" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +type msgServer struct { + Keeper +} + +// NewMsgServerImpl returns an implementation of the stored MsgServer interface +// for the provided keeper +func NewMsgServerImpl(keeper Keeper) types2.MsgServer { + return &msgServer{Keeper: keeper} +} + +var _ types2.MsgServer = msgServer{} + +func (k msgServer) CreateSubspace(goCtx context.Context, msg *types2.MsgCreateSubspace) (*types2.MsgCreateSubspaceResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // Check the if the subspace already exists + if k.DoesSubspaceExist(ctx, msg.SubspaceID) { + return nil, + sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "the subspaces with id %s already exists", msg.SubspaceID) + } + + // Create and store the new subspaces + creationTime := ctx.BlockTime() + subspace := types2.NewSubspace(msg.SubspaceID, msg.Name, msg.Creator, msg.Creator, msg.SubspaceType, creationTime) + + // Validate the subspace + if err := subspace.Validate(); err != nil { + return nil, err + } + + _ = k.SaveSubspace(ctx, subspace, subspace.Owner) + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types2.EventTypeCreateSubspace, + sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), + sdk.NewAttribute(types2.AttributeKeySubspaceName, msg.Name), + sdk.NewAttribute(types2.AttributeKeySubspaceCreator, msg.Creator), + sdk.NewAttribute(types2.AttributeKeyCreationTime, creationTime.Format(time.RFC3339)), + )) + + return &types2.MsgCreateSubspaceResponse{}, nil +} + +func (k msgServer) EditSubspace(goCtx context.Context, msg *types2.MsgEditSubspace) (*types2.MsgEditSubspaceResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // Check the if the subspace exists + subspace, exist := k.GetSubspace(ctx, msg.ID) + if !exist { + return nil, + sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "the subspaces with id %s doesn't exists", msg.ID) + } + + editedSubspace := subspace. + WithName(msg.Name). + WithOwner(msg.Owner). + WithSubspaceType(msg.SubspaceType) + + // Validate the subspace + if err := editedSubspace.Validate(); err != nil { + return nil, err + } + + if err := k.SaveSubspace(ctx, editedSubspace, msg.Editor); err != nil { + return nil, err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types2.EventTypeEditSubspace, + sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.ID), + sdk.NewAttribute(types2.AttributeKeyNewOwner, editedSubspace.Owner), + sdk.NewAttribute(types2.AttributeKeySubspaceName, editedSubspace.Name), + )) + + return &types2.MsgEditSubspaceResponse{}, nil +} + +func (k msgServer) AddAdmin(goCtx context.Context, msg *types2.MsgAddAdmin) (*types2.MsgAddAdminResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + err := k.AddAdminToSubspace(ctx, msg.SubspaceID, msg.Admin, msg.Owner) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types2.EventTypeAddAdmin, + sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), + sdk.NewAttribute(types2.AttributeKeySubspaceNewAdmin, msg.Admin), + )) + + return &types2.MsgAddAdminResponse{}, nil +} + +func (k msgServer) RemoveAdmin(goCtx context.Context, msg *types2.MsgRemoveAdmin) (*types2.MsgRemoveAdminResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + err := k.RemoveAdminFromSubspace(ctx, msg.SubspaceID, msg.Admin, msg.Owner) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types2.EventTypeRemoveAdmin, + sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), + sdk.NewAttribute(types2.AttributeKeySubspaceRemovedAdmin, msg.Admin), + )) + + return &types2.MsgRemoveAdminResponse{}, nil +} + +func (k msgServer) RegisterUser(goCtx context.Context, msg *types2.MsgRegisterUser) (*types2.MsgRegisterUserResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if err := k.RegisterUserInSubspace(ctx, msg.SubspaceID, msg.User, msg.Admin); err != nil { + return nil, err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types2.EventTypeRegisterUser, + sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), + sdk.NewAttribute(types2.AttributeKeyRegisteredUser, msg.User), + )) + + return &types2.MsgRegisterUserResponse{}, nil +} + +func (k msgServer) UnregisterUser(goCtx context.Context, msg *types2.MsgUnregisterUser) (*types2.MsgUnregisterUserResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if err := k.UnregisterUserFromSubspace(ctx, msg.SubspaceID, msg.User, msg.Admin); err != nil { + return nil, err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types2.EventTypeUnregisterUser, + sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), + sdk.NewAttribute(types2.AttributeKeyUnregisteredUser, msg.User), + )) + + return &types2.MsgUnregisterUserResponse{}, nil +} + +func (k msgServer) BanUser(goCtx context.Context, msg *types2.MsgBanUser) (*types2.MsgBanUserResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if err := k.BanUserInSubspace(ctx, msg.SubspaceID, msg.User, msg.Admin); err != nil { + return nil, err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types2.EventTypeBanUser, + sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), + sdk.NewAttribute(types2.AttributeKeyBanUser, msg.User), + )) + + return &types2.MsgBanUserResponse{}, nil +} + +func (k msgServer) UnbanUser(goCtx context.Context, msg *types2.MsgUnbanUser) (*types2.MsgUnbanUserResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + if err := k.UnbanUserInSubspace(ctx, msg.SubspaceID, msg.User, msg.Admin); err != nil { + return nil, err + } + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types2.EventTypeUnbanUser, + sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), + sdk.NewAttribute(types2.AttributeKeyUnbannedUser, msg.User), + )) + + return &types2.MsgUnbanUserResponse{}, nil +} diff --git a/x/subspaces/keeper/msg_server_test.go b/x/subspaces/keeper/msg_server_test.go new file mode 100644 index 0000000000..a3aa88369d --- /dev/null +++ b/x/subspaces/keeper/msg_server_test.go @@ -0,0 +1,877 @@ +package keeper_test + +import ( + "time" + + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (suite *KeeperTestsuite) TestMsgServer_CreateSubspace() { + creationTime := time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC) + + tests := []struct { + name string + blockTime time.Time + store func(ctx sdk.Context) + msg *types2.MsgCreateSubspace + expErr bool + expEvents sdk.Events + }{ + { + name: "Subspace already existing returns error", + blockTime: creationTime, + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + ctx.BlockTime(), + ) + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgCreateSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test2", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ), + expErr: true, + }, + { + name: "Non existing subspace is saved properly", + blockTime: creationTime, + msg: types2.NewMsgCreateSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test2", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ), + expErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + types2.EventTypeCreateSubspace, + sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types2.AttributeKeySubspaceName, "test2"), + sdk.NewAttribute(types2.AttributeKeySubspaceCreator, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"), + sdk.NewAttribute(types2.AttributeKeyCreationTime, creationTime.Format(time.RFC3339)), + ), + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + suite.ctx = suite.ctx.WithBlockTime(test.blockTime) + if test.store != nil { + test.store(suite.ctx) + } + + handler := keeper.NewMsgServerImpl(suite.k) + _, err := handler.CreateSubspace(sdk.WrapSDKContext(suite.ctx), test.msg) + + if test.expErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + + events := suite.ctx.EventManager().Events() + suite.Equal(test.expEvents, events) + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_EditSubspace() { + creationTime := time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC) + tests := []struct { + name string + blockTime time.Time + store func(ctx sdk.Context) + msg *types2.MsgEditSubspace + expErr bool + expEvents sdk.Events + expStored []types2.Subspace + }{ + { + name: "Non existing subspace returns error", + blockTime: creationTime, + msg: types2.NewMsgEditSubspace( + "1234", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "edited", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + ), + expErr: true, + }, + { + name: "Wrong editor returns error", + blockTime: creationTime, + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + creationTime, + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgEditSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "ccosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "edited", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeClosed, + ), + expErr: true, + }, + { + name: "subspace edited successfully", + blockTime: creationTime, + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + creationTime, + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgEditSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "edited", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeClosed, + ), + expErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + types2.EventTypeEditSubspace, + sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types2.AttributeKeyNewOwner, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"), + sdk.NewAttribute(types2.AttributeKeySubspaceName, "edited"), + ), + }, + expStored: []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "edited", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeClosed, + creationTime, + ), + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + suite.ctx = suite.ctx.WithBlockTime(test.blockTime) + if test.store != nil { + test.store(suite.ctx) + } + + handler := keeper.NewMsgServerImpl(suite.k) + _, err := handler.EditSubspace(sdk.WrapSDKContext(suite.ctx), test.msg) + + if test.expErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Equal(test.expEvents, suite.ctx.EventManager().Events()) + + var subspaces []types2.Subspace + suite.k.IterateSubspaces(suite.ctx, func(index int64, subspace types2.Subspace) (stop bool) { + subspaces = append(subspaces, subspace) + return false + }) + suite.Require().Equal(test.expStored, subspaces) + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_AddAdmin() { + tests := []struct { + name string + store func(ctx sdk.Context) + msg *types2.MsgAddAdmin + expErr bool + expEvents sdk.Events + expAdmins []string + }{ + { + name: "Non existing subspace returns error", + msg: types2.NewMsgAddAdmin( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "Duplicated admin returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgAddAdmin( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "Wrong owner returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgAddAdmin( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + ), + expErr: true, + }, + { + name: "Valid request adds the admin properly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgAddAdmin( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + types2.EventTypeAddAdmin, + sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types2.AttributeKeySubspaceNewAdmin, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"), + ), + }, + expAdmins: []string{ + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + handler := keeper.NewMsgServerImpl(suite.k) + _, err := handler.AddAdmin(sdk.WrapSDKContext(suite.ctx), test.msg) + + if test.expErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + + suite.Equal(test.expEvents, suite.ctx.EventManager().Events()) + + var admins []string + suite.k.IterateSubspaceAdmins(suite.ctx, test.msg.SubspaceID, func(index int64, admin string) (stop bool) { + admins = append(admins, admin) + return false + }) + suite.Require().Equal(test.expAdmins, admins) + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_RemoveAdmin() { + tests := []struct { + name string + store func(ctx sdk.Context) + msg *types2.MsgRemoveAdmin + expErr bool + expEvents sdk.Events + expAdmins []string + }{ + { + name: "Non existing subspace returns error", + msg: types2.NewMsgRemoveAdmin( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "Non existing admin returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgRemoveAdmin( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "Existing admin is removed successfully", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgRemoveAdmin( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + types2.EventTypeRemoveAdmin, + sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types2.AttributeKeySubspaceRemovedAdmin, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"), + ), + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + handler := keeper.NewMsgServerImpl(suite.k) + _, err := handler.RemoveAdmin(sdk.WrapSDKContext(suite.ctx), test.msg) + + if test.expErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(test.expEvents, suite.ctx.EventManager().Events()) + + var admins []string + suite.k.IterateSubspaceAdmins(suite.ctx, test.msg.SubspaceID, func(index int64, admin string) (stop bool) { + admins = append(admins, admin) + return false + }) + suite.Require().Equal(test.expAdmins, admins) + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_RegisterUser() { + tests := []struct { + name string + store func(ctx sdk.Context) + msg *types2.MsgRegisterUser + expErr bool + expEvents sdk.Events + expUsers []string + }{ + { + name: "Non existing subspace returns error", + msg: types2.NewMsgRegisterUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "Registered user returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgRegisterUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + expUsers: []string{ + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + }, + }, + { + name: "Non registered user is registered correctly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgRegisterUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + types2.EventTypeRegisterUser, + sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types2.AttributeKeyRegisteredUser, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"), + ), + }, + expUsers: []string{ + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + handler := keeper.NewMsgServerImpl(suite.k) + _, err := handler.RegisterUser(sdk.WrapSDKContext(suite.ctx), test.msg) + + if test.expErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Equal(test.expEvents, suite.ctx.EventManager().Events()) + } + + var users []string + suite.k.IterateSubspaceRegisteredUsers(suite.ctx, test.msg.SubspaceID, func(index int64, user string) (stop bool) { + users = append(users, user) + return false + }) + suite.Require().Equal(test.expUsers, users) + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_UnregisterUser() { + tests := []struct { + name string + store func(ctx sdk.Context) + msg *types2.MsgUnregisterUser + expErr bool + expEvents sdk.Events + expUsers []string + }{ + { + name: "Non existing subspace returns error", + msg: types2.NewMsgUnregisterUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "Not found user returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgUnregisterUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + expUsers: []string{ + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + }, + }, + { + name: "Valid user unregistered successfully", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgUnregisterUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + types2.EventTypeUnregisterUser, + sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types2.AttributeKeyUnregisteredUser, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"), + ), + }, + expUsers: nil, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + handler := keeper.NewMsgServerImpl(suite.k) + _, err := handler.UnregisterUser(sdk.WrapSDKContext(suite.ctx), test.msg) + + if test.expErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(test.expEvents, suite.ctx.EventManager().Events()) + } + + var users []string + suite.k.IterateSubspaceRegisteredUsers(suite.ctx, test.msg.SubspaceID, func(index int64, user string) (stop bool) { + users = append(users, user) + return false + }) + suite.Require().Equal(test.expUsers, users) + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_BlockUser() { + tests := []struct { + name string + store func(ctx sdk.Context) + msg *types2.MsgBanUser + expErr bool + expEvents sdk.Events + expUsers []string + }{ + { + name: "Non existing subspace returns error", + msg: types2.NewMsgBanUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "Duplicated ban returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgBanUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + expUsers: []string{ + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + }, + }, + { + name: "Valid ban request works properly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgBanUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + types2.EventTypeBanUser, + sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types2.AttributeKeyBanUser, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"), + ), + }, + expUsers: []string{ + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + }, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + handler := keeper.NewMsgServerImpl(suite.k) + _, err := handler.BanUser(sdk.WrapSDKContext(suite.ctx), test.msg) + + if test.expErr { + suite.Error(err) + } else { + suite.NoError(err) + suite.Require().Equal(test.expEvents, suite.ctx.EventManager().Events()) + } + + var users []string + suite.k.IterateSubspaceBannedUsers(suite.ctx, test.msg.SubspaceID, func(index int64, user string) (stop bool) { + users = append(users, user) + return false + }) + suite.Require().Equal(test.expUsers, users) + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_UnblockUser() { + tests := []struct { + name string + store func(ctx sdk.Context) + msg *types2.MsgUnbanUser + expErr bool + expEvents sdk.Events + expUsers []string + }{ + { + name: "Non existing subspace returns error", + msg: types2.NewMsgUnbanUser( + "123", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "Not found user returns error", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgUnbanUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "Valid block works properly", + store: func(ctx sdk.Context) { + subspace := types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), + ) + + err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) + suite.Require().NoError(err) + + err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", subspace.Owner) + suite.Require().NoError(err) + }, + msg: types2.NewMsgUnbanUser( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + types2.EventTypeUnbanUser, + sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types2.AttributeKeyUnbannedUser, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"), + ), + }, + expUsers: nil, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + suite.SetupTest() + if test.store != nil { + test.store(suite.ctx) + } + + handler := keeper.NewMsgServerImpl(suite.k) + _, err := handler.UnbanUser(sdk.WrapSDKContext(suite.ctx), test.msg) + + if test.expErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(test.expEvents, suite.ctx.EventManager().Events()) + } + + var users []string + suite.k.IterateSubspaceBannedUsers(suite.ctx, test.msg.SubspaceID, func(index int64, user string) (stop bool) { + users = append(users, user) + return false + }) + suite.Require().Equal(test.expUsers, users) + }) + } +} diff --git a/x/subspaces/module.go b/x/subspaces/module.go new file mode 100644 index 0000000000..4340c8d66f --- /dev/null +++ b/x/subspaces/module.go @@ -0,0 +1,204 @@ +package subspaces + +import ( + "context" + "encoding/json" + "fmt" + "math/rand" + + "github.com/desmos-labs/desmos/v2/x/subspaces/client/cli" + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + "github.com/desmos-labs/desmos/v2/x/subspaces/simulation" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" +) + +// type check to ensure the interface is properly implemented +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} + _ module.AppModuleSimulation = AppModule{} +) + +// AppModuleBasic defines the basic application module used by the subspaces module. +type AppModuleBasic struct { + cdc codec.Codec +} + +// Name returns the subspaces module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +// RegisterLegacyAminoCodec registers the subspaces module's types for the given codec. +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterLegacyAminoCodec(cdc) +} + +// DefaultGenesis returns default genesis state as raw bytes for the subspaces module. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesisState()) +} + +// ValidateGenesis performs genesis state validation for the subspaces module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var data types.GenesisState + if err := cdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return types.ValidateGenesis(&data) +} + +// RegisterRESTRoutes registers the REST routes for the subspaces module. +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the subspaces module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) +} + +// GetTxCmd returns the root tx command for the subspaces module. +func (AppModuleBasic) GetTxCmd() *cobra.Command { + return cli.NewTxCmd() +} + +// GetQueryCmd returns the root query command for the subspaces module. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return cli.GetQueryCmd() +} + +// RegisterInterfaces registers interfaces and implementations of the subspaces module. +func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) { + types.RegisterInterfaces(registry) +} + +//____________________________________________________________________________ + +// AppModule implements an application module for the subspaces module. +type AppModule struct { + AppModuleBasic + keeper keeper.Keeper + ak authkeeper.AccountKeeper + bk bankkeeper.Keeper +} + +// RegisterServices registers module services. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), keeper.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), am.keeper) +} + +// NewAppModule creates a new AppModule Object +func NewAppModule( + cdc codec.Codec, keeper keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, +) AppModule { + return AppModule{ + AppModuleBasic: AppModuleBasic{cdc: cdc}, + keeper: keeper, + ak: ak, + bk: bk, + } +} + +// Name returns the subspaces module's name. +func (AppModule) Name() string { + return types.ModuleName +} + +// RegisterInvariants performs a no-op. +func (am AppModule) RegisterInvariants(ir sdk.InvariantRegistry) { + keeper.RegisterInvariants(ir, am.keeper) +} + +// Route returns the message routing key for the subspaces module. +func (am AppModule) Route() sdk.Route { + return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) +} + +// NewHandler returns an sdk.Handler for the subspaces module. +func (am AppModule) NewHandler() sdk.Handler { + return NewHandler(am.keeper) +} + +// QuerierRoute returns the subspaces module's querier route name. +func (am AppModule) QuerierRoute() string { + return types.QuerierRoute +} + +// LegacyQuerierHandler returns the subspaces module sdk.Querier. +func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { + return nil +} + +// InitGenesis performs genesis initialization for the subspaces module. +// It returns no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { + var genesisState types.GenesisState + cdc.MustUnmarshalJSON(data, &genesisState) + am.keeper.InitGenesis(ctx, &genesisState) + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the exported genesis state as raw bytes for the +// subspaces module. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + gs := am.keeper.ExportGenesis(ctx) + return cdc.MustMarshalJSON(gs) +} + +// ConsensusVersion implements AppModule. +func (AppModule) ConsensusVersion() uint64 { + return 1 +} + +// BeginBlock returns the begin blocker for the subspaces module. +func (am AppModule) BeginBlock(_ sdk.Context, _ abci.RequestBeginBlock) { +} + +// EndBlock returns the end blocker for the subspaces module. It returns no validator +// updates. +func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate { + return []abci.ValidatorUpdate{} +} + +//____________________________________________________________________________ + +// AppModuleSimulation defines the module simulation functions used by the subspaces module. +type AppModuleSimulation struct{} + +// GenerateGenesisState creates a randomized GenState of the bank module. +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + simulation.RandomizeGenState(simState) +} + +// ProposalContents doesn't return any content functions for governance proposals. +func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { + return nil +} + +// RandomizedParams creates randomized subspaces param changes for the simulator. +func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { + return nil +} + +// RegisterStoreDecoder performs a no-op. +func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { + sdr[types.ModuleName] = simulation.NewDecodeStore(am.cdc) +} + +// WeightedOperations returns the all the subspaces module operations with their respective weights. +func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { + return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keeper, am.ak, am.bk) +} diff --git a/x/subspaces/types/codec.go b/x/subspaces/types/codec.go new file mode 100644 index 0000000000..8ac6ec1602 --- /dev/null +++ b/x/subspaces/types/codec.go @@ -0,0 +1,46 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" +) + +func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(MsgCreateSubspace{}, "desmos/MsgCreateSubspace", nil) + cdc.RegisterConcrete(MsgEditSubspace{}, "desmos/MsgEditSubspace", nil) + cdc.RegisterConcrete(MsgCreateUserGroup{}, "desmos/MsgCreateUserGroup", nil) + cdc.RegisterConcrete(MsgDeleteUserGroup{}, "desmos/MsgDeleteUserGroup", nil) + cdc.RegisterConcrete(MsgSetUserGroupPermissions{}, "desmos/MsgSetUserGroupPermissions", nil) + cdc.RegisterConcrete(MsgAddUserToUserGroup{}, "desmos/MsgAddUserToUserGroup", nil) + cdc.RegisterConcrete(MsgRemoveUserFromUserGroup{}, "desmos/MsgRemoveUserFromUserGroup", nil) + cdc.RegisterConcrete(MsgSetUserPermissions{}, "desmos/MsgSetUserPermissions", nil) +} + +func RegisterInterfaces(registry types.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgCreateSubspace{}, + &MsgEditSubspace{}, + &MsgCreateUserGroup{}, + &MsgDeleteUserGroup{}, + &MsgSetUserGroupPermissions{}, + &MsgAddUserToUserGroup{}, + &MsgRemoveUserFromUserGroup{}, + &MsgSetUserPermissions{}, + ) + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + amino = codec.NewLegacyAmino() + + // AminoCodec references the global x/subspaces module codec. Note, the codec should + // ONLY be used in certain instances of tests and for JSON encoding as Amino is + // still used for that purpose. + // + // The actual codec used for serialization should be provided to x/subspaces and + // defined at the application level. + AminoCodec = codec.NewAminoCodec(amino) +) diff --git a/x/subspaces/types/errors.go b/x/subspaces/types/errors.go new file mode 100644 index 0000000000..4ca43b6da0 --- /dev/null +++ b/x/subspaces/types/errors.go @@ -0,0 +1,10 @@ +package types + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +var ( + // ErrPermissionDenied is returned if a user cannot perform a specific action inside a subspace + ErrPermissionDenied = sdkerrors.Register(ModuleName, 1, "permission denied for user") +) diff --git a/x/subspaces/types/events.go b/x/subspaces/types/events.go new file mode 100644 index 0000000000..3d57983314 --- /dev/null +++ b/x/subspaces/types/events.go @@ -0,0 +1,19 @@ +package types + +// Subspaces module event types +const ( + EventTypeCreateSubspace = "create_subspace" + EventTypeEditSubspace = "edit_subspace" + + AttributeKeySubspaceID = "subspace_id" + AttributeKeySubspaceName = "subspace_name" + AttributeKeySubspaceCreator = "subspace_creator" + AttributeKeyCreationTime = "creation_date" + AttributeKeySubspaceNewAdmin = "new_admin" + AttributeKeySubspaceRemovedAdmin = "removed_admin" + AttributeKeyRegisteredUser = "registered_user" + AttributeKeyUnregisteredUser = "unregistered_user" + AttributeKeyBanUser = "banned_user" + AttributeKeyUnbannedUser = "unbanned_user" + AttributeKeyNewOwner = "new_owner" +) diff --git a/x/subspaces/types/genesis.go b/x/subspaces/types/genesis.go new file mode 100644 index 0000000000..c2de5538ee --- /dev/null +++ b/x/subspaces/types/genesis.go @@ -0,0 +1,103 @@ +package types + +import "fmt" + +// NewGenesisState creates a new genesis state +func NewGenesisState(subspaces []Subspace, acl []ACLEntry, userGroups []UserGroup) *GenesisState { + return &GenesisState{ + Subspaces: subspaces, + ACL: acl, + UserGroups: userGroups, + } +} + +// DefaultGenesisState returns a default GenesisState +func DefaultGenesisState() *GenesisState { + return NewGenesisState(nil, nil, nil) +} + +// ValidateGenesis validates the given genesis state and returns an error if something is invalid +func ValidateGenesis(data *GenesisState) error { + for _, subspace := range data.Subspaces { + err := subspace.Validate() + if err != nil { + return err + } + } + + for _, subspace := range data.Subspaces { + if containsDuplicatedSubspace(data.Subspaces, subspace) { + return fmt.Errorf("duplicated subspace: %s", subspace.ID) + } + } + + for _, entry := range data.Admins { + if isEntryDuplicated(data.Admins, entry) { + return fmt.Errorf("duplicated admins entry for subspace with id %s", entry.SubspaceID) + } + + for _, admin := range entry.Users { + if containsDuplicatedValue(entry.Users, admin) { + return fmt.Errorf("duplicated admin for subspace with id %s: %s", entry.SubspaceID, admin) + } + } + } + + for _, entry := range data.RegisteredUsers { + if isEntryDuplicated(data.RegisteredUsers, entry) { + return fmt.Errorf("duplicated registered users entry for subspace with id %s", entry.SubspaceID) + } + + for _, user := range entry.Users { + if containsDuplicatedValue(entry.Users, user) { + return fmt.Errorf("duplicated registered user for subspace with id %s: %s", entry.SubspaceID, user) + } + } + } + + for _, entry := range data.BannedUsers { + if isEntryDuplicated(data.BannedUsers, entry) { + return fmt.Errorf("duplicated banned users entry for subspace with id %s", entry.SubspaceID) + } + + for _, user := range entry.Users { + if containsDuplicatedValue(entry.Users, user) { + return fmt.Errorf("duplicated banned user for subspace with id %s: %s", entry.SubspaceID, user) + } + } + } + + return nil +} + +// containsDuplicatedSubspace tells whether the given subspaces slice contain duplicates of the provided subspace +func containsDuplicatedSubspace(subspaces []Subspace, subspace Subspace) bool { + var count = 0 + for _, s := range subspaces { + if s.Equal(subspace) { + count++ + } + } + return count > 1 +} + +func isEntryDuplicated(entries []UsersEntry, entry UsersEntry) bool { + var count = 0 + for _, e := range entries { + if e.SubspaceID == entry.SubspaceID { + count++ + } + } + return count > 1 +} + +// containsDuplicatedValue tells whether the given entries slice contains duplicates of the provided value +func containsDuplicatedValue(slice []string, value string) bool { + var count = 0 + for _, e := range slice { + if e == value { + count++ + } + } + return count > 1 +} diff --git a/x/subspaces/types/genesis.pb.go b/x/subspaces/types/genesis.pb.go new file mode 100644 index 0000000000..485c4c0fc9 --- /dev/null +++ b/x/subspaces/types/genesis.pb.go @@ -0,0 +1,1039 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: desmos/subspaces/v1/genesis.proto + +package types + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// GenesisState contains the data of the genesis state for the subspaces module +type GenesisState struct { + Subspaces []Subspace `protobuf:"bytes,1,rep,name=subspaces,proto3" json:"subspaces"` + ACL []ACLEntry `protobuf:"bytes,3,rep,name=acl,proto3" json:"acl"` + UserGroups []UserGroup `protobuf:"bytes,2,rep,name=user_groups,json=userGroups,proto3" json:"user_groups"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_bce8af665337782b, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetSubspaces() []Subspace { + if m != nil { + return m.Subspaces + } + return nil +} + +func (m *GenesisState) GetACL() []ACLEntry { + if m != nil { + return m.ACL + } + return nil +} + +func (m *GenesisState) GetUserGroups() []UserGroup { + if m != nil { + return m.UserGroups + } + return nil +} + +// ACL represents a single Access Control List entry +type ACLEntry struct { + // Either group name or user address + SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` + Target string `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty"` + Permissions []byte `protobuf:"bytes,3,opt,name=permissions,proto3" json:"permissions,omitempty"` +} + +func (m *ACLEntry) Reset() { *m = ACLEntry{} } +func (m *ACLEntry) String() string { return proto.CompactTextString(m) } +func (*ACLEntry) ProtoMessage() {} +func (*ACLEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_bce8af665337782b, []int{1} +} +func (m *ACLEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ACLEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ACLEntry.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ACLEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_ACLEntry.Merge(m, src) +} +func (m *ACLEntry) XXX_Size() int { + return m.Size() +} +func (m *ACLEntry) XXX_DiscardUnknown() { + xxx_messageInfo_ACLEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_ACLEntry proto.InternalMessageInfo + +func (m *ACLEntry) GetSubspaceId() uint64 { + if m != nil { + return m.SubspaceId + } + return 0 +} + +func (m *ACLEntry) GetTarget() string { + if m != nil { + return m.Target + } + return "" +} + +func (m *ACLEntry) GetPermissions() []byte { + if m != nil { + return m.Permissions + } + return nil +} + +// UsersEntry contains the data of a slice of users associated to a subspace +// with a specific id +type UserGroup struct { + SubspaceID string `protobuf:"bytes,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Users []string `protobuf:"bytes,3,rep,name=users,proto3" json:"users,omitempty"` +} + +func (m *UserGroup) Reset() { *m = UserGroup{} } +func (m *UserGroup) String() string { return proto.CompactTextString(m) } +func (*UserGroup) ProtoMessage() {} +func (*UserGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_bce8af665337782b, []int{2} +} +func (m *UserGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UserGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UserGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UserGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_UserGroup.Merge(m, src) +} +func (m *UserGroup) XXX_Size() int { + return m.Size() +} +func (m *UserGroup) XXX_DiscardUnknown() { + xxx_messageInfo_UserGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_UserGroup proto.InternalMessageInfo + +func (m *UserGroup) GetSubspaceID() string { + if m != nil { + return m.SubspaceID + } + return "" +} + +func (m *UserGroup) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *UserGroup) GetUsers() []string { + if m != nil { + return m.Users + } + return nil +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "desmos.subspaces.v1.GenesisState") + proto.RegisterType((*ACLEntry)(nil), "desmos.subspaces.v1.ACLEntry") + proto.RegisterType((*UserGroup)(nil), "desmos.subspaces.v1.UserGroup") +} + +func init() { proto.RegisterFile("desmos/subspaces/v1/genesis.proto", fileDescriptor_bce8af665337782b) } + +var fileDescriptor_bce8af665337782b = []byte{ + // 388 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0x3f, 0xeb, 0xda, 0x50, + 0x14, 0xcd, 0xfb, 0xc5, 0x8a, 0x79, 0x91, 0x0e, 0xaf, 0x52, 0x82, 0xd0, 0x24, 0xcd, 0x94, 0xa5, + 0x79, 0x68, 0xb7, 0xd2, 0xc5, 0x58, 0x11, 0xc1, 0x29, 0xd2, 0xa5, 0x8b, 0x24, 0xfa, 0x48, 0x03, + 0x26, 0x2f, 0xe4, 0xbe, 0x48, 0xfd, 0x16, 0x1d, 0x3b, 0xfa, 0x71, 0x1c, 0x9d, 0x4a, 0x27, 0x29, + 0x71, 0xe9, 0xc7, 0x28, 0xf9, 0x67, 0x2d, 0x95, 0x6e, 0xf7, 0xdc, 0x77, 0xce, 0x3d, 0xf7, 0x1d, + 0x2e, 0x7e, 0xbd, 0x65, 0x10, 0x73, 0xa0, 0x90, 0x07, 0x90, 0xfa, 0x1b, 0x06, 0x74, 0x3f, 0xa2, + 0x21, 0x4b, 0x18, 0x44, 0xe0, 0xa4, 0x19, 0x17, 0x9c, 0xbc, 0xa8, 0x29, 0xce, 0x8d, 0xe2, 0xec, + 0x47, 0xc3, 0x41, 0xc8, 0x43, 0x5e, 0xbd, 0xd3, 0xb2, 0xaa, 0xa9, 0x43, 0xeb, 0xd1, 0xb4, 0x16, + 0xd4, 0x1c, 0xeb, 0x3b, 0xc2, 0xfd, 0x79, 0x6d, 0xb0, 0x12, 0xbe, 0x60, 0x64, 0x82, 0x95, 0x1b, + 0x5f, 0x43, 0xa6, 0x6c, 0xab, 0xe3, 0x57, 0xce, 0x03, 0x4f, 0x67, 0xd5, 0x00, 0xb7, 0x73, 0xba, + 0x18, 0x92, 0xf7, 0x47, 0x45, 0xde, 0x63, 0xd9, 0xdf, 0xec, 0x34, 0xf9, 0x3f, 0xe2, 0xc9, 0x74, + 0x39, 0x4b, 0x44, 0x76, 0x70, 0xd5, 0x52, 0x5c, 0x5c, 0x0c, 0x79, 0x32, 0x5d, 0x7a, 0xa5, 0x8c, + 0xcc, 0xb0, 0x9a, 0x03, 0xcb, 0xd6, 0x61, 0xc6, 0xf3, 0x14, 0xb4, 0xa7, 0x6a, 0x8a, 0xfe, 0x70, + 0xca, 0x47, 0x60, 0xd9, 0xbc, 0xa4, 0x35, 0x3b, 0xe0, 0xbc, 0x6d, 0x80, 0xc5, 0x70, 0xaf, 0x35, + 0x21, 0x06, 0x56, 0x5b, 0xdd, 0x3a, 0xda, 0x6a, 0xc8, 0x44, 0x76, 0xc7, 0xc3, 0x6d, 0x6b, 0xb1, + 0x25, 0x2f, 0x71, 0x57, 0xf8, 0x59, 0xc8, 0x84, 0xf6, 0x64, 0x22, 0x5b, 0xf1, 0x1a, 0x44, 0x4c, + 0xac, 0xa6, 0x2c, 0x8b, 0x23, 0x80, 0x88, 0x27, 0xa0, 0xc9, 0x26, 0xb2, 0xfb, 0xde, 0x7d, 0xcb, + 0x4a, 0xb1, 0x72, 0xdb, 0x82, 0xd0, 0x7f, 0x7d, 0x14, 0xf7, 0x79, 0x71, 0x31, 0x70, 0x1b, 0xd6, + 0xe2, 0xc3, 0x5f, 0xbe, 0x04, 0x77, 0x12, 0x3f, 0x66, 0x8d, 0x6b, 0x55, 0x93, 0x01, 0x7e, 0x56, + 0x7e, 0x03, 0xaa, 0xfc, 0x14, 0xaf, 0x06, 0xef, 0x7a, 0xdf, 0x8e, 0x06, 0xfa, 0x75, 0x34, 0x90, + 0xbb, 0x3c, 0x15, 0x3a, 0x3a, 0x17, 0x3a, 0xfa, 0x59, 0xe8, 0xe8, 0xeb, 0x55, 0x97, 0xce, 0x57, + 0x5d, 0xfa, 0x71, 0xd5, 0xa5, 0x4f, 0xe3, 0x30, 0x12, 0x9f, 0xf3, 0xc0, 0xd9, 0xf0, 0x98, 0xd6, + 0x71, 0xbd, 0xd9, 0xf9, 0x01, 0x34, 0x35, 0xdd, 0x8f, 0xe9, 0x97, 0xbb, 0x5b, 0x10, 0x87, 0x94, + 0x41, 0xd0, 0xad, 0xce, 0xe0, 0xed, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x95, 0x9a, 0x3b, + 0x7a, 0x02, 0x00, 0x00, +} + +func (this *UserGroup) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*UserGroup) + if !ok { + that2, ok := that.(UserGroup) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.SubspaceID != that1.SubspaceID { + return false + } + if this.Name != that1.Name { + return false + } + if len(this.Users) != len(that1.Users) { + return false + } + for i := range this.Users { + if this.Users[i] != that1.Users[i] { + return false + } + } + return true +} +func (m *GenesisState) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ACL) > 0 { + for iNdEx := len(m.ACL) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ACL[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.UserGroups) > 0 { + for iNdEx := len(m.UserGroups) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.UserGroups[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Subspaces) > 0 { + for iNdEx := len(m.Subspaces) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Subspaces[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *ACLEntry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ACLEntry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ACLEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Permissions) > 0 { + i -= len(m.Permissions) + copy(dAtA[i:], m.Permissions) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Permissions))) + i-- + dAtA[i] = 0x1a + } + if len(m.Target) > 0 { + i -= len(m.Target) + copy(dAtA[i:], m.Target) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Target))) + i-- + dAtA[i] = 0x12 + } + if m.SubspaceId != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.SubspaceId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *UserGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UserGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Users) > 0 { + for iNdEx := len(m.Users) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Users[iNdEx]) + copy(dAtA[i:], m.Users[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Users[iNdEx]))) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if len(m.SubspaceID) > 0 { + i -= len(m.SubspaceID) + copy(dAtA[i:], m.SubspaceID) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.SubspaceID))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Subspaces) > 0 { + for _, e := range m.Subspaces { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.UserGroups) > 0 { + for _, e := range m.UserGroups { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.ACL) > 0 { + for _, e := range m.ACL { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *ACLEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceId != 0 { + n += 1 + sovGenesis(uint64(m.SubspaceId)) + } + l = len(m.Target) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.Permissions) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + return n +} + +func (m *UserGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SubspaceID) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovGenesis(uint64(l)) + } + if len(m.Users) > 0 { + for _, s := range m.Users { + l = len(s) + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subspaces", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subspaces = append(m.Subspaces, Subspace{}) + if err := m.Subspaces[len(m.Subspaces)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserGroups", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UserGroups = append(m.UserGroups, UserGroup{}) + if err := m.UserGroups[len(m.UserGroups)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ACL", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ACL = append(m.ACL, ACLEntry{}) + if err := m.ACL[len(m.ACL)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ACLEntry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ACLEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ACLEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceId", wireType) + } + m.SubspaceId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Target = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Permissions = append(m.Permissions[:0], dAtA[iNdEx:postIndex]...) + if m.Permissions == nil { + m.Permissions = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UserGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UserGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SubspaceID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Users", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Users = append(m.Users, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowGenesis + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/subspaces/types/genesis_test.go b/x/subspaces/types/genesis_test.go new file mode 100644 index 0000000000..bde7c656ee --- /dev/null +++ b/x/subspaces/types/genesis_test.go @@ -0,0 +1,196 @@ +package types_test + +import ( + "testing" + "time" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + "github.com/stretchr/testify/require" +) + +func TestValidateGenesis(t *testing.T) { + date, err := time.Parse(time.RFC3339, "2050-01-01T15:15:00.000Z") + require.NoError(t, err) + + tests := []struct { + name string + genesis *types2.GenesisState + shouldErr bool + }{ + { + name: "Default genesis does not error", + genesis: types2.DefaultGenesisState(), + shouldErr: false, + }, + { + name: "Genesis with invalid subspaces returns error", + genesis: types2.NewGenesisState( + []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "", + "", + "", + types2.SubspaceTypeOpen, + time.Time{}, + ), + }, + nil, + nil, + nil, + ), + shouldErr: true, + }, + { + name: "Genesis with duplicated subspaces returns error", + genesis: types2.NewGenesisState( + []types2.Subspace{ + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "name", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + date, + ), + types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "name", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + date, + ), + }, + nil, + nil, + nil, + ), + shouldErr: true, + }, + { + name: "Genesis with duplicated admins entry returns error", + genesis: types2.NewGenesisState( + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, + ), + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, + ), + }, + nil, + nil, + ), + shouldErr: true, + }, + { + name: "Genesis with duplicated admins returns error", + genesis: types2.NewGenesisState( + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{ + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + }, + ), + }, + nil, + nil, + ), + shouldErr: true, + }, + { + name: "Genesis with duplicated registered users entry returns error", + genesis: types2.NewGenesisState( + nil, + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, + ), + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, + ), + }, + nil, + ), + shouldErr: true, + }, + { + name: "Genesis with duplicated registered users returns error", + genesis: types2.NewGenesisState( + nil, + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{ + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + }, + ), + }, + nil, + ), + shouldErr: true, + }, + { + name: "Genesis with duplicated banned users entry returns error", + genesis: types2.NewGenesisState( + nil, + nil, + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, + ), + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, + ), + }, + ), + shouldErr: true, + }, + { + name: "Genesis with duplicated banned users returns error", + genesis: types2.NewGenesisState( + nil, + nil, + nil, + []types2.UsersEntry{ + types2.NewUsersEntry( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + []string{ + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + }, + ), + }, + ), + shouldErr: true, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err = types2.ValidateGenesis(test.genesis) + if test.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/x/subspaces/types/keys.go b/x/subspaces/types/keys.go new file mode 100644 index 0000000000..0c8cccc89b --- /dev/null +++ b/x/subspaces/types/keys.go @@ -0,0 +1,28 @@ +package types + +// DONTCOVER + +const ( + ModuleName = "subspaces" + RouterKey = ModuleName + StoreKey = ModuleName + + ActionCreateSubspace = "create_subspace" + ActionEditSubspace = "edit_subspace" + ActionCreateUserGroup = "create_user_group" + ActionDeleteUserGroup = "delete_user_group" + ActionAddUserToUserGroup = "add_user_to_user_group" + ActionRemoveUserFromUserGroup = "remove_user_from_user_group" + ActionSetPermissions = "set_permissions" + + QuerierRoute = ModuleName +) + +var ( + SubspaceStorePrefix = []byte("subspace") +) + +// SubspaceStoreKey turns an id to a key used to store a subspace into the subspaces store +func SubspaceStoreKey(id string) []byte { + return append(SubspaceStorePrefix, []byte(id)...) +} diff --git a/x/subspaces/types/msgs.go b/x/subspaces/types/msgs.go new file mode 100644 index 0000000000..426efea92d --- /dev/null +++ b/x/subspaces/types/msgs.go @@ -0,0 +1,335 @@ +package types + +import ( + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// NewMsgCreateSubspace creates a new MsgCreateSubspace instance +func NewMsgCreateSubspace(name, description, owner, treasury, creator string) *MsgCreateSubspace { + if owner == "" { + // If the owner is empty, set the creator as the owner + owner = creator + } + + return &MsgCreateSubspace{ + Name: name, + Description: description, + Owner: owner, + Treasury: treasury, + Creator: creator, + } +} + +// Route implements sdk.Msg +func (msg MsgCreateSubspace) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgCreateSubspace) Type() string { return ActionCreateSubspace } + +// ValidateBasic implements sdk.Msg +func (msg MsgCreateSubspace) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address") + } + + _, err = sdk.AccAddressFromBech32(msg.Owner) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid owner address") + } + + if strings.TrimSpace(msg.Name) == "" { + return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "subspace name cannot be empty or blank") + } + + if msg.Treasury != "" { + _, err = sdk.AccAddressFromBech32(msg.Treasury) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid treasury address") + } + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgCreateSubspace) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgCreateSubspace) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Creator) + return []sdk.AccAddress{addr} +} + +// -------------------------------------------------------------------------------------------------------------------- + +// NewMsgEditSubspace creates a new MsgEditSubspace instance +func NewMsgEditSubspace(subspaceID, name, description, owner, treasury, signer string) *MsgEditSubspace { + return &MsgEditSubspace{ + ID: subspaceID, + Name: name, + Description: description, + Owner: owner, + Treasury: treasury, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgEditSubspace) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgEditSubspace) Type() string { return ActionEditSubspace } + +// ValidateBasic implements sdk.Msg +func (msg MsgEditSubspace) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + } + + if strings.TrimSpace(msg.Owner) != "" { + _, err = sdk.AccAddressFromBech32(msg.Owner) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid owner address") + } + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgEditSubspace) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgEditSubspace) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Signer) + return []sdk.AccAddress{addr} +} + +// -------------------------------------------------------------------------------------------------------------------- + +// NewMsgCreateUserGroup creates a new MsgCreateUserGroup instance +func NewMsgCreateUserGroup(subspaceID uint64, name string, permissions uint32, creator string) *MsgCreateUserGroup { + return &MsgCreateUserGroup{ + SubspaceID: subspaceID, + GroupName: name, + DefaultPermissions: permissions, + Creator: creator, + } +} + +// Route implements sdk.Msg +func (msg MsgCreateUserGroup) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgCreateUserGroup) Type() string { return ActionCreateUserGroup } + +// ValidateBasic implements sdk.Msg +func (msg MsgCreateUserGroup) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address") + } + + if strings.TrimSpace(msg.GroupName) != "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group name cannot be empty or blank") + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgCreateUserGroup) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgCreateUserGroup) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Creator) + return []sdk.AccAddress{addr} +} + +// -------------------------------------------------------------------------------------------------------------------- + +// NewMsgDeleteUserGroup creates a new MsgDeleteUserGroup instance +func NewMsgDeleteUserGroup(subspaceID uint64, group string, signer string) *MsgDeleteUserGroup { + return &MsgDeleteUserGroup{ + SubspaceID: subspaceID, + GroupName: group, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgDeleteUserGroup) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgDeleteUserGroup) Type() string { return ActionDeleteUserGroup } + +// ValidateBasic implements sdk.Msg +func (msg MsgDeleteUserGroup) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + } + + if strings.TrimSpace(msg.GroupName) != "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group name cannot be empty or blank") + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgDeleteUserGroup) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgDeleteUserGroup) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Signer) + return []sdk.AccAddress{addr} +} + +// -------------------------------------------------------------------------------------------------------------------- + +// NewMsgAddUserToUserGroup creates a new MsgAddUserToUserGroup instance +func NewMsgAddUserToUserGroup(subspaceID uint64, group string, user string, signer string) *MsgAddUserToUserGroup { + return &MsgAddUserToUserGroup{ + SubspaceID: subspaceID, + GroupName: group, + User: user, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgAddUserToUserGroup) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgAddUserToUserGroup) Type() string { return ActionAddUserToUserGroup } + +// ValidateBasic implements sdk.Msg +func (msg MsgAddUserToUserGroup) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + } + + _, err = sdk.AccAddressFromBech32(msg.User) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address") + } + + if strings.TrimSpace(msg.GroupName) != "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group name cannot be empty or blank") + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgAddUserToUserGroup) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgAddUserToUserGroup) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Signer) + return []sdk.AccAddress{addr} +} + +// -------------------------------------------------------------------------------------------------------------------- + +// NewMsgRemoveUserFromUserGroup creates a new MsgRemoveUserFromUserGroup instance +func NewMsgRemoveUserFromUserGroup(subspaceID uint64, group string, user string, signer string) *MsgRemoveUserFromUserGroup { + return &MsgRemoveUserFromUserGroup{ + SubspaceID: subspaceID, + GroupName: group, + User: user, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgRemoveUserFromUserGroup) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgRemoveUserFromUserGroup) Type() string { return ActionRemoveUserFromUserGroup } + +// ValidateBasic implements sdk.Msg +func (msg MsgRemoveUserFromUserGroup) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + } + + _, err = sdk.AccAddressFromBech32(msg.User) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address") + } + + if strings.TrimSpace(msg.GroupName) != "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group name cannot be empty or blank") + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgRemoveUserFromUserGroup) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgRemoveUserFromUserGroup) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Signer) + return []sdk.AccAddress{addr} +} + +// -------------------------------------------------------------------------------------------------------------------- + +// NewMsgSetPermissions creates a new MsgSetPermissions instance +func NewMsgSetPermissions(subspaceID uint64, target string, permissions uint32, signer string) *MsgSetPermissions { + return &MsgSetPermissions{ + SubspaceID: subspaceID, + Target: target, + Permissions: permissions, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgSetPermissions) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgSetPermissions) Type() string { return ActionSetPermissions } + +// ValidateBasic implements sdk.Msg +func (msg MsgSetPermissions) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgSetPermissions) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgSetPermissions) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Signer) + return []sdk.AccAddress{addr} +} diff --git a/x/subspaces/types/msgs.pb.go b/x/subspaces/types/msgs.pb.go new file mode 100644 index 0000000000..7351655d78 --- /dev/null +++ b/x/subspaces/types/msgs.pb.go @@ -0,0 +1,3565 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: desmos/subspaces/v1/msgs.proto + +package types + +import ( + context "context" + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// MsgCreateSubspace represents the message used to create a subspace +type MsgCreateSubspace struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` + Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` + Treasury string `protobuf:"bytes,4,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + Creator string `protobuf:"bytes,5,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` +} + +func (m *MsgCreateSubspace) Reset() { *m = MsgCreateSubspace{} } +func (m *MsgCreateSubspace) String() string { return proto.CompactTextString(m) } +func (*MsgCreateSubspace) ProtoMessage() {} +func (*MsgCreateSubspace) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{0} +} +func (m *MsgCreateSubspace) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateSubspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateSubspace.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgCreateSubspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateSubspace.Merge(m, src) +} +func (m *MsgCreateSubspace) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateSubspace) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateSubspace.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateSubspace proto.InternalMessageInfo + +// MsgCreateSubspaceResponse defines the Msg/CreateSubspace response type +type MsgCreateSubspaceResponse struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` +} + +func (m *MsgCreateSubspaceResponse) Reset() { *m = MsgCreateSubspaceResponse{} } +func (m *MsgCreateSubspaceResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCreateSubspaceResponse) ProtoMessage() {} +func (*MsgCreateSubspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{1} +} +func (m *MsgCreateSubspaceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateSubspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateSubspaceResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgCreateSubspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateSubspaceResponse.Merge(m, src) +} +func (m *MsgCreateSubspaceResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateSubspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateSubspaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateSubspaceResponse proto.InternalMessageInfo + +func (m *MsgCreateSubspaceResponse) GetSubspaceID() uint64 { + if m != nil { + return m.SubspaceID + } + return 0 +} + +// MsgEditSubspace represents the message used to edit a subspace fields +type MsgEditSubspace struct { + ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"subspace_id"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` + Owner string `protobuf:"bytes,4,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` + Treasury string `protobuf:"bytes,5,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` +} + +func (m *MsgEditSubspace) Reset() { *m = MsgEditSubspace{} } +func (m *MsgEditSubspace) String() string { return proto.CompactTextString(m) } +func (*MsgEditSubspace) ProtoMessage() {} +func (*MsgEditSubspace) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{2} +} +func (m *MsgEditSubspace) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgEditSubspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgEditSubspace.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgEditSubspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgEditSubspace.Merge(m, src) +} +func (m *MsgEditSubspace) XXX_Size() int { + return m.Size() +} +func (m *MsgEditSubspace) XXX_DiscardUnknown() { + xxx_messageInfo_MsgEditSubspace.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgEditSubspace proto.InternalMessageInfo + +// MsgEditSubspaceResponse defines the Msg/EditSubspace response type +type MsgEditSubspaceResponse struct { +} + +func (m *MsgEditSubspaceResponse) Reset() { *m = MsgEditSubspaceResponse{} } +func (m *MsgEditSubspaceResponse) String() string { return proto.CompactTextString(m) } +func (*MsgEditSubspaceResponse) ProtoMessage() {} +func (*MsgEditSubspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{3} +} +func (m *MsgEditSubspaceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgEditSubspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgEditSubspaceResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgEditSubspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgEditSubspaceResponse.Merge(m, src) +} +func (m *MsgEditSubspaceResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgEditSubspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgEditSubspaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgEditSubspaceResponse proto.InternalMessageInfo + +// MsgCreateUserGroup represents the message used to create a user group +type MsgCreateUserGroup struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` + DefaultPermissions uint32 `protobuf:"varint,3,opt,name=default_permissions,json=defaultPermissions,proto3" json:"default_permissions,omitempty" yaml:"default_permissions"` + Creator string `protobuf:"bytes,4,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` +} + +func (m *MsgCreateUserGroup) Reset() { *m = MsgCreateUserGroup{} } +func (m *MsgCreateUserGroup) String() string { return proto.CompactTextString(m) } +func (*MsgCreateUserGroup) ProtoMessage() {} +func (*MsgCreateUserGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{4} +} +func (m *MsgCreateUserGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateUserGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateUserGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgCreateUserGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateUserGroup.Merge(m, src) +} +func (m *MsgCreateUserGroup) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateUserGroup) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateUserGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateUserGroup proto.InternalMessageInfo + +func (m *MsgCreateUserGroup) GetSubspaceID() uint64 { + if m != nil { + return m.SubspaceID + } + return 0 +} + +func (m *MsgCreateUserGroup) GetGroupName() string { + if m != nil { + return m.GroupName + } + return "" +} + +func (m *MsgCreateUserGroup) GetDefaultPermissions() uint32 { + if m != nil { + return m.DefaultPermissions + } + return 0 +} + +func (m *MsgCreateUserGroup) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +// MsgCreateUserGroupResponse defines the Msg/CreateUserGroup response type +type MsgCreateUserGroupResponse struct { +} + +func (m *MsgCreateUserGroupResponse) Reset() { *m = MsgCreateUserGroupResponse{} } +func (m *MsgCreateUserGroupResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCreateUserGroupResponse) ProtoMessage() {} +func (*MsgCreateUserGroupResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{5} +} +func (m *MsgCreateUserGroupResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCreateUserGroupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCreateUserGroupResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgCreateUserGroupResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCreateUserGroupResponse.Merge(m, src) +} +func (m *MsgCreateUserGroupResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCreateUserGroupResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCreateUserGroupResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCreateUserGroupResponse proto.InternalMessageInfo + +// MsgDeleteUserGroup represents the message used to delete a user group +type MsgDeleteUserGroup struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` + Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` +} + +func (m *MsgDeleteUserGroup) Reset() { *m = MsgDeleteUserGroup{} } +func (m *MsgDeleteUserGroup) String() string { return proto.CompactTextString(m) } +func (*MsgDeleteUserGroup) ProtoMessage() {} +func (*MsgDeleteUserGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{6} +} +func (m *MsgDeleteUserGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDeleteUserGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDeleteUserGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgDeleteUserGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDeleteUserGroup.Merge(m, src) +} +func (m *MsgDeleteUserGroup) XXX_Size() int { + return m.Size() +} +func (m *MsgDeleteUserGroup) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDeleteUserGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDeleteUserGroup proto.InternalMessageInfo + +func (m *MsgDeleteUserGroup) GetSubspaceID() uint64 { + if m != nil { + return m.SubspaceID + } + return 0 +} + +func (m *MsgDeleteUserGroup) GetGroupName() string { + if m != nil { + return m.GroupName + } + return "" +} + +func (m *MsgDeleteUserGroup) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +// MsgDeleteUserGroupResponse defines the Msg/DeleteUserGroup response type +type MsgDeleteUserGroupResponse struct { +} + +func (m *MsgDeleteUserGroupResponse) Reset() { *m = MsgDeleteUserGroupResponse{} } +func (m *MsgDeleteUserGroupResponse) String() string { return proto.CompactTextString(m) } +func (*MsgDeleteUserGroupResponse) ProtoMessage() {} +func (*MsgDeleteUserGroupResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{7} +} +func (m *MsgDeleteUserGroupResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDeleteUserGroupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDeleteUserGroupResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgDeleteUserGroupResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDeleteUserGroupResponse.Merge(m, src) +} +func (m *MsgDeleteUserGroupResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgDeleteUserGroupResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDeleteUserGroupResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDeleteUserGroupResponse proto.InternalMessageInfo + +// MsgSetUserGroupPermissions represents the message used to add a user to a +// user group +type MsgAddUserToUserGroup struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` + GroupName string `protobuf:"bytes,3,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` +} + +func (m *MsgAddUserToUserGroup) Reset() { *m = MsgAddUserToUserGroup{} } +func (m *MsgAddUserToUserGroup) String() string { return proto.CompactTextString(m) } +func (*MsgAddUserToUserGroup) ProtoMessage() {} +func (*MsgAddUserToUserGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{8} +} +func (m *MsgAddUserToUserGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAddUserToUserGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAddUserToUserGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAddUserToUserGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAddUserToUserGroup.Merge(m, src) +} +func (m *MsgAddUserToUserGroup) XXX_Size() int { + return m.Size() +} +func (m *MsgAddUserToUserGroup) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAddUserToUserGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAddUserToUserGroup proto.InternalMessageInfo + +func (m *MsgAddUserToUserGroup) GetSubspaceID() uint64 { + if m != nil { + return m.SubspaceID + } + return 0 +} + +func (m *MsgAddUserToUserGroup) GetUser() string { + if m != nil { + return m.User + } + return "" +} + +func (m *MsgAddUserToUserGroup) GetGroupName() string { + if m != nil { + return m.GroupName + } + return "" +} + +func (m *MsgAddUserToUserGroup) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +// MsgAddUserToUserGroupResponse defines the Msg/AddUserToUserGroupResponse +// response type +type MsgAddUserToUserGroupResponse struct { +} + +func (m *MsgAddUserToUserGroupResponse) Reset() { *m = MsgAddUserToUserGroupResponse{} } +func (m *MsgAddUserToUserGroupResponse) String() string { return proto.CompactTextString(m) } +func (*MsgAddUserToUserGroupResponse) ProtoMessage() {} +func (*MsgAddUserToUserGroupResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{9} +} +func (m *MsgAddUserToUserGroupResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgAddUserToUserGroupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgAddUserToUserGroupResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgAddUserToUserGroupResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgAddUserToUserGroupResponse.Merge(m, src) +} +func (m *MsgAddUserToUserGroupResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgAddUserToUserGroupResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgAddUserToUserGroupResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgAddUserToUserGroupResponse proto.InternalMessageInfo + +// MsgRemoveUserFromUserGroup represents the message used to remove a user from +// a user group +type MsgRemoveUserFromUserGroup struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` + GroupName string `protobuf:"bytes,3,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` +} + +func (m *MsgRemoveUserFromUserGroup) Reset() { *m = MsgRemoveUserFromUserGroup{} } +func (m *MsgRemoveUserFromUserGroup) String() string { return proto.CompactTextString(m) } +func (*MsgRemoveUserFromUserGroup) ProtoMessage() {} +func (*MsgRemoveUserFromUserGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{10} +} +func (m *MsgRemoveUserFromUserGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRemoveUserFromUserGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRemoveUserFromUserGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgRemoveUserFromUserGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRemoveUserFromUserGroup.Merge(m, src) +} +func (m *MsgRemoveUserFromUserGroup) XXX_Size() int { + return m.Size() +} +func (m *MsgRemoveUserFromUserGroup) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRemoveUserFromUserGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRemoveUserFromUserGroup proto.InternalMessageInfo + +func (m *MsgRemoveUserFromUserGroup) GetSubspaceID() uint64 { + if m != nil { + return m.SubspaceID + } + return 0 +} + +func (m *MsgRemoveUserFromUserGroup) GetUser() string { + if m != nil { + return m.User + } + return "" +} + +func (m *MsgRemoveUserFromUserGroup) GetGroupName() string { + if m != nil { + return m.GroupName + } + return "" +} + +func (m *MsgRemoveUserFromUserGroup) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +// MsgRemoveUserFromUserGroupResponse defines the +// Msg/RemoveUserFromUserGroupResponse response type +type MsgRemoveUserFromUserGroupResponse struct { +} + +func (m *MsgRemoveUserFromUserGroupResponse) Reset() { *m = MsgRemoveUserFromUserGroupResponse{} } +func (m *MsgRemoveUserFromUserGroupResponse) String() string { return proto.CompactTextString(m) } +func (*MsgRemoveUserFromUserGroupResponse) ProtoMessage() {} +func (*MsgRemoveUserFromUserGroupResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{11} +} +func (m *MsgRemoveUserFromUserGroupResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRemoveUserFromUserGroupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRemoveUserFromUserGroupResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgRemoveUserFromUserGroupResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRemoveUserFromUserGroupResponse.Merge(m, src) +} +func (m *MsgRemoveUserFromUserGroupResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgRemoveUserFromUserGroupResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRemoveUserFromUserGroupResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRemoveUserFromUserGroupResponse proto.InternalMessageInfo + +// MsgSetPermissions represents the message used to set the permissions of a +// user or user group +type MsgSetPermissions struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + Target string `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty" yaml:"target"` + Permissions uint32 `protobuf:"varint,3,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` +} + +func (m *MsgSetPermissions) Reset() { *m = MsgSetPermissions{} } +func (m *MsgSetPermissions) String() string { return proto.CompactTextString(m) } +func (*MsgSetPermissions) ProtoMessage() {} +func (*MsgSetPermissions) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{12} +} +func (m *MsgSetPermissions) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetPermissions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetPermissions.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetPermissions) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetPermissions.Merge(m, src) +} +func (m *MsgSetPermissions) XXX_Size() int { + return m.Size() +} +func (m *MsgSetPermissions) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetPermissions.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetPermissions proto.InternalMessageInfo + +func (m *MsgSetPermissions) GetSubspaceID() uint64 { + if m != nil { + return m.SubspaceID + } + return 0 +} + +func (m *MsgSetPermissions) GetTarget() string { + if m != nil { + return m.Target + } + return "" +} + +func (m *MsgSetPermissions) GetPermissions() uint32 { + if m != nil { + return m.Permissions + } + return 0 +} + +func (m *MsgSetPermissions) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +// MsgSetPermissionsResponse defines the Msg/SetPermissionsResponse +// response type +type MsgSetPermissionsResponse struct { +} + +func (m *MsgSetPermissionsResponse) Reset() { *m = MsgSetPermissionsResponse{} } +func (m *MsgSetPermissionsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSetPermissionsResponse) ProtoMessage() {} +func (*MsgSetPermissionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{13} +} +func (m *MsgSetPermissionsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetPermissionsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetPermissionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetPermissionsResponse.Merge(m, src) +} +func (m *MsgSetPermissionsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSetPermissionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetPermissionsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetPermissionsResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgCreateSubspace)(nil), "desmos.subspaces.v1.MsgCreateSubspace") + proto.RegisterType((*MsgCreateSubspaceResponse)(nil), "desmos.subspaces.v1.MsgCreateSubspaceResponse") + proto.RegisterType((*MsgEditSubspace)(nil), "desmos.subspaces.v1.MsgEditSubspace") + proto.RegisterType((*MsgEditSubspaceResponse)(nil), "desmos.subspaces.v1.MsgEditSubspaceResponse") + proto.RegisterType((*MsgCreateUserGroup)(nil), "desmos.subspaces.v1.MsgCreateUserGroup") + proto.RegisterType((*MsgCreateUserGroupResponse)(nil), "desmos.subspaces.v1.MsgCreateUserGroupResponse") + proto.RegisterType((*MsgDeleteUserGroup)(nil), "desmos.subspaces.v1.MsgDeleteUserGroup") + proto.RegisterType((*MsgDeleteUserGroupResponse)(nil), "desmos.subspaces.v1.MsgDeleteUserGroupResponse") + proto.RegisterType((*MsgAddUserToUserGroup)(nil), "desmos.subspaces.v1.MsgAddUserToUserGroup") + proto.RegisterType((*MsgAddUserToUserGroupResponse)(nil), "desmos.subspaces.v1.MsgAddUserToUserGroupResponse") + proto.RegisterType((*MsgRemoveUserFromUserGroup)(nil), "desmos.subspaces.v1.MsgRemoveUserFromUserGroup") + proto.RegisterType((*MsgRemoveUserFromUserGroupResponse)(nil), "desmos.subspaces.v1.MsgRemoveUserFromUserGroupResponse") + proto.RegisterType((*MsgSetPermissions)(nil), "desmos.subspaces.v1.MsgSetPermissions") + proto.RegisterType((*MsgSetPermissionsResponse)(nil), "desmos.subspaces.v1.MsgSetPermissionsResponse") +} + +func init() { proto.RegisterFile("desmos/subspaces/v1/msgs.proto", fileDescriptor_c16a431ff9a3b35b) } + +var fileDescriptor_c16a431ff9a3b35b = []byte{ + // 814 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0xcd, 0x6e, 0xd3, 0x4a, + 0x14, 0xc7, 0x63, 0x27, 0xcd, 0x6d, 0x4f, 0x3f, 0x72, 0xeb, 0xde, 0xde, 0xa6, 0xa6, 0xd8, 0x68, + 0x5a, 0x15, 0x8a, 0x4a, 0xac, 0x06, 0x24, 0x50, 0x77, 0x84, 0x16, 0x54, 0x89, 0x00, 0x72, 0x61, + 0xc3, 0xa6, 0x72, 0xe2, 0xc1, 0xb5, 0x88, 0xe3, 0xc8, 0xe3, 0x04, 0xba, 0xee, 0x86, 0x65, 0x25, + 0x5e, 0xa0, 0x0f, 0xc0, 0x23, 0xf0, 0x00, 0x2c, 0xbb, 0x64, 0x65, 0xa1, 0x94, 0x05, 0xb0, 0xf4, + 0x13, 0x20, 0x8f, 0x3f, 0xe2, 0x38, 0x31, 0x4d, 0x50, 0x17, 0x88, 0x9d, 0x7d, 0xce, 0x6f, 0xce, + 0xf8, 0xfc, 0xcf, 0xcc, 0x39, 0x06, 0x41, 0xc5, 0xc4, 0x30, 0x89, 0x44, 0xda, 0x35, 0xd2, 0x52, + 0xea, 0x98, 0x48, 0x9d, 0x2d, 0xc9, 0x20, 0x1a, 0x29, 0xb5, 0x2c, 0xd3, 0x36, 0xb9, 0x05, 0xdf, + 0x5f, 0x8a, 0xfc, 0xa5, 0xce, 0x16, 0xff, 0x9f, 0x66, 0x6a, 0x26, 0xf5, 0x4b, 0xde, 0x93, 0x8f, + 0xf2, 0x68, 0x58, 0xa8, 0xf0, 0xc5, 0x67, 0xd0, 0x31, 0x0b, 0xf3, 0x55, 0xa2, 0x3d, 0xb0, 0xb0, + 0x62, 0xe3, 0xfd, 0xc0, 0xc7, 0xad, 0x42, 0xae, 0xa9, 0x18, 0xb8, 0xc8, 0x5c, 0x63, 0x6e, 0x4c, + 0x55, 0x0a, 0xae, 0x23, 0x4e, 0x1f, 0x29, 0x46, 0x63, 0x1b, 0x79, 0x56, 0x24, 0x53, 0x27, 0x77, + 0x0f, 0xa6, 0x55, 0x4c, 0xea, 0x96, 0xde, 0xb2, 0x75, 0xb3, 0x59, 0x64, 0x29, 0xfb, 0xbf, 0xeb, + 0x88, 0x9c, 0xcf, 0xc6, 0x9c, 0x48, 0x8e, 0xa3, 0xdc, 0x3a, 0x4c, 0x98, 0x6f, 0x9a, 0xd8, 0x2a, + 0x66, 0xe9, 0x9a, 0x7f, 0x5d, 0x47, 0x9c, 0xf1, 0xd7, 0x50, 0x33, 0x92, 0x7d, 0x37, 0x27, 0xc1, + 0xa4, 0x6d, 0x61, 0x85, 0xb4, 0xad, 0xa3, 0x62, 0x8e, 0xa2, 0x0b, 0xae, 0x23, 0x16, 0x7c, 0x34, + 0xf4, 0x20, 0x39, 0x82, 0xb8, 0x4d, 0xf8, 0xa7, 0xee, 0x65, 0x62, 0x5a, 0xc5, 0x09, 0xca, 0x73, + 0xae, 0x23, 0xce, 0xf9, 0x7c, 0xe0, 0x40, 0x72, 0x88, 0x6c, 0x4f, 0xbe, 0x3b, 0x15, 0x33, 0xdf, + 0x4e, 0xc5, 0x0c, 0xaa, 0xc1, 0xf2, 0x80, 0x08, 0x32, 0x26, 0x2d, 0xb3, 0x49, 0x30, 0xb7, 0x0b, + 0xd3, 0xa1, 0x68, 0x07, 0xba, 0x4a, 0x35, 0xc9, 0x55, 0xd6, 0xba, 0x8e, 0x08, 0x21, 0xba, 0xb7, + 0xd3, 0xcb, 0x3a, 0x86, 0x22, 0x19, 0xc2, 0xb7, 0x3d, 0x15, 0x7d, 0x60, 0xa1, 0x50, 0x25, 0xda, + 0xae, 0xaa, 0xdb, 0x91, 0xce, 0x9b, 0xc0, 0x06, 0x11, 0xa7, 0x2a, 0x2b, 0x5d, 0x47, 0x64, 0x53, + 0x23, 0xb1, 0xba, 0x1a, 0x55, 0x85, 0x1d, 0xa3, 0x2a, 0xd9, 0xdf, 0xa8, 0x4a, 0x6e, 0xf4, 0xaa, + 0x4c, 0x8c, 0x52, 0x95, 0x0d, 0xc8, 0x13, 0x5d, 0xf3, 0x22, 0xe7, 0x29, 0x3e, 0xef, 0x3a, 0xe2, + 0x6c, 0x90, 0x23, 0xb5, 0x23, 0x39, 0x00, 0x62, 0x25, 0x59, 0x86, 0xa5, 0x84, 0x5a, 0x61, 0x41, + 0xd0, 0x09, 0x0b, 0x5c, 0x54, 0xae, 0x17, 0x04, 0x5b, 0x8f, 0x2c, 0xb3, 0xdd, 0xba, 0xa4, 0x3a, + 0x71, 0x77, 0x00, 0x34, 0x2f, 0xde, 0x41, 0x4c, 0xeb, 0x45, 0xd7, 0x11, 0xe7, 0xfd, 0x75, 0x3d, + 0x1f, 0x92, 0xa7, 0xe8, 0xcb, 0x13, 0x4f, 0xf6, 0xa7, 0xb0, 0xa0, 0xe2, 0x57, 0x4a, 0xbb, 0x61, + 0x1f, 0xb4, 0xb0, 0x65, 0xe8, 0x84, 0xe8, 0x66, 0x93, 0x50, 0xf9, 0x67, 0x2b, 0x82, 0xeb, 0x88, + 0x7c, 0x28, 0xff, 0x00, 0x84, 0x64, 0x2e, 0xb0, 0x3e, 0xeb, 0x19, 0xe3, 0x47, 0x39, 0x77, 0xe1, + 0x51, 0x46, 0x2b, 0xc0, 0x0f, 0x2a, 0x12, 0x09, 0xf6, 0x91, 0xa1, 0x82, 0xed, 0xe0, 0x06, 0xfe, + 0x63, 0x04, 0xeb, 0x1d, 0x8a, 0xec, 0x05, 0x87, 0x22, 0x48, 0x2e, 0xf1, 0xf5, 0x51, 0x72, 0x5f, + 0x19, 0x58, 0xac, 0x12, 0xed, 0xbe, 0xaa, 0x7a, 0xbe, 0xe7, 0xe6, 0xa5, 0xe7, 0xb7, 0x0a, 0xb9, + 0x36, 0xc1, 0xd6, 0xe0, 0xb5, 0xf3, 0xac, 0x48, 0xa6, 0xce, 0x84, 0x08, 0xd9, 0xb1, 0x45, 0xc8, + 0x5d, 0x24, 0x82, 0x08, 0x57, 0x87, 0x66, 0x19, 0xe9, 0xf0, 0x9d, 0xa1, 0x32, 0xc9, 0xd8, 0x30, + 0x3b, 0x54, 0xa6, 0x87, 0x96, 0x69, 0xfc, 0xa5, 0x62, 0xac, 0x01, 0x4a, 0x4f, 0x35, 0x52, 0xe4, + 0x07, 0x43, 0x67, 0xdb, 0x3e, 0xee, 0xbb, 0x58, 0x97, 0x24, 0xc4, 0x06, 0xe4, 0x6d, 0xc5, 0xd2, + 0xb0, 0x1d, 0x48, 0x11, 0xfb, 0x5a, 0xdf, 0x8e, 0xe4, 0x00, 0xf0, 0x5a, 0xf2, 0x60, 0x4f, 0x88, + 0xb5, 0xe4, 0xbe, 0x5e, 0x10, 0x47, 0xc7, 0x91, 0xe4, 0x0a, 0x1d, 0x61, 0xfd, 0xb9, 0x86, 0x4a, + 0x94, 0xdf, 0xe7, 0x21, 0x5b, 0x25, 0x1a, 0x77, 0x08, 0x73, 0x89, 0x49, 0xbf, 0x5e, 0x1a, 0xf2, + 0x3f, 0x51, 0x1a, 0x18, 0x86, 0x7c, 0x69, 0x34, 0x2e, 0x1a, 0x9a, 0x35, 0x98, 0xe9, 0x9b, 0x74, + 0x6b, 0x69, 0xeb, 0xe3, 0x14, 0xbf, 0x39, 0x0a, 0x15, 0xed, 0xf1, 0x1a, 0x0a, 0xc9, 0x19, 0x70, + 0xfd, 0xd7, 0x9f, 0x19, 0x81, 0xbc, 0x34, 0x22, 0x18, 0xdf, 0x2c, 0xd9, 0x3f, 0x53, 0x37, 0x4b, + 0x80, 0xe9, 0x9b, 0xa5, 0xf4, 0x34, 0xce, 0x06, 0x6e, 0x48, 0x3f, 0xbb, 0x99, 0x16, 0x66, 0x90, + 0xe5, 0xcb, 0xa3, 0xb3, 0xd1, 0xae, 0xc7, 0x0c, 0x2c, 0xa5, 0xb5, 0x8f, 0xd4, 0x14, 0x52, 0x16, + 0xf0, 0x77, 0xc7, 0x5c, 0x10, 0x7d, 0xc5, 0x21, 0xcc, 0x25, 0x6e, 0x6c, 0xea, 0x19, 0xed, 0xe7, + 0xd2, 0xcf, 0xe8, 0xf0, 0x5b, 0x51, 0x79, 0xfc, 0xa9, 0x2b, 0x30, 0x67, 0x5d, 0x81, 0xf9, 0xd2, + 0x15, 0x98, 0x93, 0x73, 0x21, 0x73, 0x76, 0x2e, 0x64, 0x3e, 0x9f, 0x0b, 0x99, 0x97, 0x65, 0x4d, + 0xb7, 0x0f, 0xdb, 0xb5, 0x52, 0xdd, 0x34, 0x24, 0x3f, 0xe6, 0xad, 0x86, 0x52, 0x23, 0xc1, 0xb3, + 0xd4, 0x29, 0x4b, 0x6f, 0x63, 0x7f, 0xd5, 0xf6, 0x51, 0x0b, 0x93, 0x5a, 0x9e, 0xfe, 0x50, 0xdf, + 0xfe, 0x19, 0x00, 0x00, 0xff, 0xff, 0xe6, 0xa0, 0xbf, 0x5e, 0xc1, 0x0b, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + // CreateSubspace allows to create a subspace + CreateSubspace(ctx context.Context, in *MsgCreateSubspace, opts ...grpc.CallOption) (*MsgCreateSubspaceResponse, error) + // EditSubspace allows to edit a subspace + EditSubspace(ctx context.Context, in *MsgEditSubspace, opts ...grpc.CallOption) (*MsgEditSubspaceResponse, error) + // CreateUserGroup allows to create a user group + CreateUserGroup(ctx context.Context, in *MsgCreateUserGroup, opts ...grpc.CallOption) (*MsgCreateUserGroupResponse, error) + // DeleteUserGroup allows to delete an existing user group + DeleteUserGroup(ctx context.Context, in *MsgDeleteUserGroup, opts ...grpc.CallOption) (*MsgDeleteUserGroupResponse, error) + // AddUserToUserGroup allows to add a specific user to a specific user group + AddUserToUserGroup(ctx context.Context, in *MsgAddUserToUserGroup, opts ...grpc.CallOption) (*MsgAddUserToUserGroupResponse, error) + // RemoveUserFromUserGroup allows to remove a specific user from a specific + // user group + RemoveUserFromUserGroup(ctx context.Context, in *MsgRemoveUserFromUserGroup, opts ...grpc.CallOption) (*MsgRemoveUserFromUserGroupResponse, error) + // SetUserPermissions allows to set another user's permissions + SetPermissions(ctx context.Context, in *MsgSetPermissions, opts ...grpc.CallOption) (*MsgSetPermissionsResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) CreateSubspace(ctx context.Context, in *MsgCreateSubspace, opts ...grpc.CallOption) (*MsgCreateSubspaceResponse, error) { + out := new(MsgCreateSubspaceResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/CreateSubspace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) EditSubspace(ctx context.Context, in *MsgEditSubspace, opts ...grpc.CallOption) (*MsgEditSubspaceResponse, error) { + out := new(MsgEditSubspaceResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/EditSubspace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) CreateUserGroup(ctx context.Context, in *MsgCreateUserGroup, opts ...grpc.CallOption) (*MsgCreateUserGroupResponse, error) { + out := new(MsgCreateUserGroupResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/CreateUserGroup", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) DeleteUserGroup(ctx context.Context, in *MsgDeleteUserGroup, opts ...grpc.CallOption) (*MsgDeleteUserGroupResponse, error) { + out := new(MsgDeleteUserGroupResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/DeleteUserGroup", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) AddUserToUserGroup(ctx context.Context, in *MsgAddUserToUserGroup, opts ...grpc.CallOption) (*MsgAddUserToUserGroupResponse, error) { + out := new(MsgAddUserToUserGroupResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/AddUserToUserGroup", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) RemoveUserFromUserGroup(ctx context.Context, in *MsgRemoveUserFromUserGroup, opts ...grpc.CallOption) (*MsgRemoveUserFromUserGroupResponse, error) { + out := new(MsgRemoveUserFromUserGroupResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/RemoveUserFromUserGroup", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) SetPermissions(ctx context.Context, in *MsgSetPermissions, opts ...grpc.CallOption) (*MsgSetPermissionsResponse, error) { + out := new(MsgSetPermissionsResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/SetPermissions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + // CreateSubspace allows to create a subspace + CreateSubspace(context.Context, *MsgCreateSubspace) (*MsgCreateSubspaceResponse, error) + // EditSubspace allows to edit a subspace + EditSubspace(context.Context, *MsgEditSubspace) (*MsgEditSubspaceResponse, error) + // CreateUserGroup allows to create a user group + CreateUserGroup(context.Context, *MsgCreateUserGroup) (*MsgCreateUserGroupResponse, error) + // DeleteUserGroup allows to delete an existing user group + DeleteUserGroup(context.Context, *MsgDeleteUserGroup) (*MsgDeleteUserGroupResponse, error) + // AddUserToUserGroup allows to add a specific user to a specific user group + AddUserToUserGroup(context.Context, *MsgAddUserToUserGroup) (*MsgAddUserToUserGroupResponse, error) + // RemoveUserFromUserGroup allows to remove a specific user from a specific + // user group + RemoveUserFromUserGroup(context.Context, *MsgRemoveUserFromUserGroup) (*MsgRemoveUserFromUserGroupResponse, error) + // SetUserPermissions allows to set another user's permissions + SetPermissions(context.Context, *MsgSetPermissions) (*MsgSetPermissionsResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) CreateSubspace(ctx context.Context, req *MsgCreateSubspace) (*MsgCreateSubspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateSubspace not implemented") +} +func (*UnimplementedMsgServer) EditSubspace(ctx context.Context, req *MsgEditSubspace) (*MsgEditSubspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EditSubspace not implemented") +} +func (*UnimplementedMsgServer) CreateUserGroup(ctx context.Context, req *MsgCreateUserGroup) (*MsgCreateUserGroupResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateUserGroup not implemented") +} +func (*UnimplementedMsgServer) DeleteUserGroup(ctx context.Context, req *MsgDeleteUserGroup) (*MsgDeleteUserGroupResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteUserGroup not implemented") +} +func (*UnimplementedMsgServer) AddUserToUserGroup(ctx context.Context, req *MsgAddUserToUserGroup) (*MsgAddUserToUserGroupResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AddUserToUserGroup not implemented") +} +func (*UnimplementedMsgServer) RemoveUserFromUserGroup(ctx context.Context, req *MsgRemoveUserFromUserGroup) (*MsgRemoveUserFromUserGroupResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RemoveUserFromUserGroup not implemented") +} +func (*UnimplementedMsgServer) SetPermissions(ctx context.Context, req *MsgSetPermissions) (*MsgSetPermissionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetPermissions not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_CreateSubspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgCreateSubspace) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CreateSubspace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/CreateSubspace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CreateSubspace(ctx, req.(*MsgCreateSubspace)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_EditSubspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgEditSubspace) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).EditSubspace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/EditSubspace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).EditSubspace(ctx, req.(*MsgEditSubspace)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_CreateUserGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgCreateUserGroup) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CreateUserGroup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/CreateUserGroup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CreateUserGroup(ctx, req.(*MsgCreateUserGroup)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_DeleteUserGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgDeleteUserGroup) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).DeleteUserGroup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/DeleteUserGroup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).DeleteUserGroup(ctx, req.(*MsgDeleteUserGroup)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_AddUserToUserGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgAddUserToUserGroup) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).AddUserToUserGroup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/AddUserToUserGroup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).AddUserToUserGroup(ctx, req.(*MsgAddUserToUserGroup)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_RemoveUserFromUserGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgRemoveUserFromUserGroup) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).RemoveUserFromUserGroup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/RemoveUserFromUserGroup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RemoveUserFromUserGroup(ctx, req.(*MsgRemoveUserFromUserGroup)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_SetPermissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSetPermissions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SetPermissions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/SetPermissions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SetPermissions(ctx, req.(*MsgSetPermissions)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "desmos.subspaces.v1.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateSubspace", + Handler: _Msg_CreateSubspace_Handler, + }, + { + MethodName: "EditSubspace", + Handler: _Msg_EditSubspace_Handler, + }, + { + MethodName: "CreateUserGroup", + Handler: _Msg_CreateUserGroup_Handler, + }, + { + MethodName: "DeleteUserGroup", + Handler: _Msg_DeleteUserGroup_Handler, + }, + { + MethodName: "AddUserToUserGroup", + Handler: _Msg_AddUserToUserGroup_Handler, + }, + { + MethodName: "RemoveUserFromUserGroup", + Handler: _Msg_RemoveUserFromUserGroup_Handler, + }, + { + MethodName: "SetPermissions", + Handler: _Msg_SetPermissions_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "desmos/subspaces/v1/msgs.proto", +} + +func (m *MsgCreateSubspace) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgCreateSubspace) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateSubspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0x2a + } + if len(m.Treasury) > 0 { + i -= len(m.Treasury) + copy(dAtA[i:], m.Treasury) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Treasury))) + i-- + dAtA[i] = 0x22 + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0x1a + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgCreateSubspaceResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgCreateSubspaceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateSubspaceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgEditSubspace) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgEditSubspace) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgEditSubspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x32 + } + if len(m.Treasury) > 0 { + i -= len(m.Treasury) + copy(dAtA[i:], m.Treasury) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Treasury))) + i-- + dAtA[i] = 0x2a + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0x22 + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x1a + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if len(m.ID) > 0 { + i -= len(m.ID) + copy(dAtA[i:], m.ID) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.ID))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgEditSubspaceResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgEditSubspaceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgEditSubspaceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgCreateUserGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgCreateUserGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0x22 + } + if m.DefaultPermissions != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.DefaultPermissions)) + i-- + dAtA[i] = 0x18 + } + if len(m.GroupName) > 0 { + i -= len(m.GroupName) + copy(dAtA[i:], m.GroupName) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.GroupName))) + i-- + dAtA[i] = 0x12 + } + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgCreateUserGroupResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgCreateUserGroupResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCreateUserGroupResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgDeleteUserGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgDeleteUserGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDeleteUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x1a + } + if len(m.GroupName) > 0 { + i -= len(m.GroupName) + copy(dAtA[i:], m.GroupName) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.GroupName))) + i-- + dAtA[i] = 0x12 + } + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgDeleteUserGroupResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgDeleteUserGroupResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDeleteUserGroupResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgAddUserToUserGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAddUserToUserGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAddUserToUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x22 + } + if len(m.GroupName) > 0 { + i -= len(m.GroupName) + copy(dAtA[i:], m.GroupName) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.GroupName))) + i-- + dAtA[i] = 0x1a + } + if len(m.User) > 0 { + i -= len(m.User) + copy(dAtA[i:], m.User) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.User))) + i-- + dAtA[i] = 0x12 + } + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgAddUserToUserGroupResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgAddUserToUserGroupResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgAddUserToUserGroupResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgRemoveUserFromUserGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgRemoveUserFromUserGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRemoveUserFromUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x22 + } + if len(m.GroupName) > 0 { + i -= len(m.GroupName) + copy(dAtA[i:], m.GroupName) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.GroupName))) + i-- + dAtA[i] = 0x1a + } + if len(m.User) > 0 { + i -= len(m.User) + copy(dAtA[i:], m.User) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.User))) + i-- + dAtA[i] = 0x12 + } + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgRemoveUserFromUserGroupResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgRemoveUserFromUserGroupResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRemoveUserFromUserGroupResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgSetPermissions) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetPermissions) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetPermissions) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x22 + } + if m.Permissions != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.Permissions)) + i-- + dAtA[i] = 0x18 + } + if len(m.Target) > 0 { + i -= len(m.Target) + copy(dAtA[i:], m.Target) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Target))) + i-- + dAtA[i] = 0x12 + } + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgSetPermissionsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetPermissionsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintMsgs(dAtA []byte, offset int, v uint64) int { + offset -= sovMsgs(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgCreateSubspace) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Treasury) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + return n +} + +func (m *MsgCreateSubspaceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) + } + return n +} + +func (m *MsgEditSubspace) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ID) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Treasury) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + return n +} + +func (m *MsgEditSubspaceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgCreateUserGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) + } + l = len(m.GroupName) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + if m.DefaultPermissions != 0 { + n += 1 + sovMsgs(uint64(m.DefaultPermissions)) + } + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + return n +} + +func (m *MsgCreateUserGroupResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgDeleteUserGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) + } + l = len(m.GroupName) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + return n +} + +func (m *MsgDeleteUserGroupResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgAddUserToUserGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) + } + l = len(m.User) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.GroupName) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + return n +} + +func (m *MsgAddUserToUserGroupResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgRemoveUserFromUserGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) + } + l = len(m.User) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.GroupName) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + return n +} + +func (m *MsgRemoveUserFromUserGroupResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgSetPermissions) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) + } + l = len(m.Target) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + if m.Permissions != 0 { + n += 1 + sovMsgs(uint64(m.Permissions)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + return n +} + +func (m *MsgSetPermissionsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovMsgs(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozMsgs(x uint64) (n int) { + return sovMsgs(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgCreateSubspace) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCreateSubspace: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateSubspace: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Treasury = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCreateSubspaceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCreateSubspaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateSubspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgEditSubspace: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgEditSubspace: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Treasury = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgEditSubspaceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgEditSubspaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgEditSubspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCreateUserGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateUserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GroupName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultPermissions", wireType) + } + m.DefaultPermissions = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DefaultPermissions |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCreateUserGroupResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCreateUserGroupResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateUserGroupResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDeleteUserGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDeleteUserGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDeleteUserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GroupName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDeleteUserGroupResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDeleteUserGroupResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDeleteUserGroupResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAddUserToUserGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAddUserToUserGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAddUserToUserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.User = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GroupName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgAddUserToUserGroupResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgAddUserToUserGroupResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgAddUserToUserGroupResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRemoveUserFromUserGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgRemoveUserFromUserGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRemoveUserFromUserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.User = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GroupName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRemoveUserFromUserGroupResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgRemoveUserFromUserGroupResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRemoveUserFromUserGroupResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSetPermissions) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSetPermissions: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetPermissions: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Target = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + } + m.Permissions = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Permissions |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgSetPermissionsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgSetPermissionsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgSetPermissionsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipMsgs(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMsgs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMsgs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMsgs + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthMsgs + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupMsgs + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthMsgs + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthMsgs = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowMsgs = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupMsgs = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/subspaces/types/msgs_test.go b/x/subspaces/types/msgs_test.go new file mode 100644 index 0000000000..94c39b0046 --- /dev/null +++ b/x/subspaces/types/msgs_test.go @@ -0,0 +1,810 @@ +package types_test + +import ( + "testing" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +func TestMsgCreateSubspace_Route(t *testing.T) { + msg := types2.NewMsgCreateSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "mooncake", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ) + require.Equal(t, "subspaces", msg.Route()) +} + +func TestMsgCreateSubspace_Type(t *testing.T) { + msg := types2.NewMsgCreateSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "mooncake", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ) + require.Equal(t, "create_subspace", msg.Type()) +} + +func TestMsgCreateSubspace_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg *types2.MsgCreateSubspace + expErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types2.NewMsgCreateSubspace( + "", + "mooncake", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ), + expErr: true, + }, + { + name: "invalid subspace creator address returns error", + msg: types2.NewMsgCreateSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "mooncake", + "", + types2.SubspaceTypeOpen, + ), + expErr: true, + }, + { + name: "invalid subspace name returns error", + msg: types2.NewMsgCreateSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ), + expErr: true, + }, + { + name: "valid message returns no error", + msg: types2.NewMsgCreateSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "mooncake", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ), + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := test.msg.ValidateBasic() + if test.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgCreateSubspace_GetSignBytes(t *testing.T) { + msg := types2.NewMsgCreateSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "mooncake", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ) + expected := `{"creator":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","name":"mooncake","subspace_type":1}` + require.Equal(t, expected, string(msg.GetSignBytes())) +} + +func TestMsgCreateSubspace_GetSigners(t *testing.T) { + msg := types2.NewMsgCreateSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "mooncake", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ) + addr, _ := sdk.AccAddressFromBech32(msg.Creator) + require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +} + +func TestMsgEditSubspace_Route(t *testing.T) { + msg := types2.NewMsgEditSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "star", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ) + require.Equal(t, "subspaces", msg.Route()) +} + +func TestMsgEditSubspace_Type(t *testing.T) { + msg := types2.NewMsgEditSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "star", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ) + require.Equal(t, "edit_subspace", msg.Type()) +} + +func TestMsgEditSubspace_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg *types2.MsgEditSubspace + expErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types2.NewMsgEditSubspace( + "", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "star", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ), + expErr: true, + }, + { + name: "invalid subspace owner address returns error", + msg: types2.NewMsgEditSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "star", + "", + types2.SubspaceTypeOpen, + ), + expErr: true, + }, + { + name: "equal subspace owner and new owner addresses returns error", + msg: types2.NewMsgEditSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + "star", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ), + expErr: true, + }, + { + name: "valid message returns no error", + msg: types2.NewMsgEditSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "star", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ), + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := test.msg.ValidateBasic() + if test.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgEditSubspace_GetSignBytes(t *testing.T) { + msg := types2.NewMsgEditSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "star", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ) + expected := `{"editor":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","name":"star","owner":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","subspace_type":1}` + require.Equal(t, expected, string(msg.GetSignBytes())) +} + +func TestMsgEditSubspace_GetSigners(t *testing.T) { + msg := types2.NewMsgEditSubspace( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "star", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + types2.SubspaceTypeOpen, + ) + addr, _ := sdk.AccAddressFromBech32(msg.Editor) + require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +} + +func TestMsgAddAdmin_Route(t *testing.T) { + msg := types2.NewMsgAddAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "subspaces", msg.Route()) +} + +func TestMsgAddAdmin_Type(t *testing.T) { + msg := types2.NewMsgAddAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "add_admin", msg.Type()) +} + +func TestMsgAddAdmin_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg *types2.MsgAddAdmin + expErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types2.NewMsgAddAdmin( + "", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "equals owner and admin addresses returns error", + msg: types2.NewMsgAddAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + ), + expErr: true, + }, + { + name: "invalid subspace owner address returns error", + msg: types2.NewMsgAddAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "", + ), + expErr: true, + }, + { + name: "invalid subspace new admin address returns error", + msg: types2.NewMsgAddAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "valid message returns no error", + msg: types2.NewMsgAddAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := test.msg.ValidateBasic() + if test.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgAddAdmin_GetSignBytes(t *testing.T) { + msg := types2.NewMsgAddAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + expected := `{"admin":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","owner":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af"}` + require.Equal(t, expected, string(msg.GetSignBytes())) +} + +func TestMsgAddAdmin_GetSigners(t *testing.T) { + msg := types2.NewMsgAddAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + addr, _ := sdk.AccAddressFromBech32(msg.Owner) + require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +} + +func TestMsgRemoveAdmin_Route(t *testing.T) { + msg := types2.NewMsgRemoveAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "subspaces", msg.Route()) +} + +func TestMsgRemoveAdmin_Type(t *testing.T) { + msg := types2.NewMsgRemoveAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "remove_admin", msg.Type()) +} + +func TestMsgRemoveAdmin_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg *types2.MsgRemoveAdmin + expErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types2.NewMsgRemoveAdmin( + "", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "equals owner and admin addresses returns error", + msg: types2.NewMsgRemoveAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + ), + expErr: true, + }, + { + name: "invalid subspace owner address returns error", + msg: types2.NewMsgRemoveAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "", + ), + expErr: true, + }, + { + name: "invalid subspace admin address returns error", + msg: types2.NewMsgRemoveAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "valid message returns no error", + msg: types2.NewMsgRemoveAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := test.msg.ValidateBasic() + if test.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgRemoveAdmin_GetSignBytes(t *testing.T) { + msg := types2.NewMsgRemoveAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + expected := `{"admin":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","owner":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af"}` + require.Equal(t, expected, string(msg.GetSignBytes())) +} + +func TestMsgRemoveAdmin_GetSigners(t *testing.T) { + msg := types2.NewMsgRemoveAdmin( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + addr, _ := sdk.AccAddressFromBech32(msg.Owner) + require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +} + +func TestMsgRegisterUser_Route(t *testing.T) { + msg := types2.NewMsgRegisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "subspaces", msg.Route()) +} + +func TestMsgRegisterUser_Type(t *testing.T) { + msg := types2.NewMsgRegisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "register_user", msg.Type()) +} + +func TestMsgRegisterUser_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg *types2.MsgRegisterUser + expErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types2.NewMsgRegisterUser( + "", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "invalid subspace admin address returns error", + msg: types2.NewMsgRegisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "", + ), + expErr: true, + }, + { + name: "invalid subspace user address returns error", + msg: types2.NewMsgRegisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "valid message returns no error", + msg: types2.NewMsgRegisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := test.msg.ValidateBasic() + if test.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgRegisterUser_GetSignBytes(t *testing.T) { + msg := types2.NewMsgRegisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` + require.Equal(t, expected, string(msg.GetSignBytes())) +} + +func TestMsgRegisterUser_GetSigners(t *testing.T) { + msg := types2.NewMsgRegisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + addr, _ := sdk.AccAddressFromBech32(msg.Admin) + require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +} + +func TestMsgUnregisterUser_Route(t *testing.T) { + msg := types2.NewMsgUnregisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "subspaces", msg.Route()) +} + +func TestMsgUnregisterUser_Type(t *testing.T) { + msg := types2.NewMsgUnregisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "unregister_user", msg.Type()) +} + +func TestMsgUnregisterUser_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg *types2.MsgUnregisterUser + expErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types2.NewMsgUnregisterUser( + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "invalid subspace admin address returns error", + msg: types2.NewMsgUnregisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "", + ), + expErr: true, + }, + { + name: "invalid subspace user address returns error", + msg: types2.NewMsgUnregisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "valid message returns no error", + msg: types2.NewMsgUnregisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := test.msg.ValidateBasic() + if test.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgUnregisterUser_GetSignBytes(t *testing.T) { + msg := types2.NewMsgUnregisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` + require.Equal(t, expected, string(msg.GetSignBytes())) +} + +func TestMsgUnregisterUser_GetSigners(t *testing.T) { + msg := types2.NewMsgUnregisterUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + addr, _ := sdk.AccAddressFromBech32(msg.Admin) + require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +} + +func TestMsgBanUser_Route(t *testing.T) { + msg := types2.NewMsgBanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "subspaces", msg.Route()) +} + +func TestMsgBanUser_Type(t *testing.T) { + msg := types2.NewMsgBanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "block_user", msg.Type()) +} + +func TestMsgBanUser_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg *types2.MsgBanUser + expErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types2.NewMsgBanUser( + "", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "invalid subspace admin address returns error", + msg: types2.NewMsgBanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "", + ), + expErr: true, + }, + { + name: "invalid subspace user address returns error", + msg: types2.NewMsgBanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "valid message returns no error", + msg: types2.NewMsgBanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := test.msg.ValidateBasic() + if test.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgBanUser_GetSignBytes(t *testing.T) { + msg := types2.NewMsgBanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` + require.Equal(t, expected, string(msg.GetSignBytes())) +} + +func TestMsgBanUser_GetSigners(t *testing.T) { + msg := types2.NewMsgBanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + addr, _ := sdk.AccAddressFromBech32(msg.Admin) + require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +} + +func TestTestMsgUnbanUser_Route(t *testing.T) { + msg := types2.NewMsgUnbanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "subspaces", msg.Route()) +} + +func TestTestMsgUnbanUser_Type(t *testing.T) { + msg := types2.NewMsgUnbanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + require.Equal(t, "unblock_user", msg.Type()) +} + +func TestTestMsgUnbanUser_ValidateBasic(t *testing.T) { + tests := []struct { + name string + msg *types2.MsgUnbanUser + expErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types2.NewMsgUnbanUser( + "", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "invalid subspace admin address returns error", + msg: types2.NewMsgUnbanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "", + ), + expErr: true, + }, + { + name: "invalid subspace user address returns error", + msg: types2.NewMsgUnbanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: true, + }, + { + name: "valid message returns no error", + msg: types2.NewMsgUnbanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ), + expErr: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := test.msg.ValidateBasic() + if test.expErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestTestMsgUnbanUser_GetSignBytes(t *testing.T) { + msg := types2.NewMsgUnbanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` + require.Equal(t, expected, string(msg.GetSignBytes())) +} + +func TestTestMsgUnbanUser_GetSigners(t *testing.T) { + msg := types2.NewMsgUnbanUser( + "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", + "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", + "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", + ) + addr, _ := sdk.AccAddressFromBech32(msg.Admin) + require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +} diff --git a/x/subspaces/types/query.go b/x/subspaces/types/query.go new file mode 100644 index 0000000000..a8567a036d --- /dev/null +++ b/x/subspaces/types/query.go @@ -0,0 +1,41 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/types/query" +) + +// NewQuerySubspaceRequest returns a new QuerySubspaceRequest instance +func NewQuerySubspaceRequest(subspaceID string) *QuerySubspaceRequest { + return &QuerySubspaceRequest{SubspaceId: subspaceID} +} + +// NewQuerySubspacesRequest returns a new QuerySubspacesRequest instance +func NewQuerySubspacesRequest(pagination *query.PageRequest) *QuerySubspacesRequest { + return &QuerySubspacesRequest{ + Pagination: pagination, + } +} + +// NewQueryAdminsRequest returns a new QuerySubspaceAdminsRequest instance +func NewQueryAdminsRequest(subspaceID string, pagination *query.PageRequest) *QueryAdminsRequest { + return &QueryAdminsRequest{ + SubspaceId: subspaceID, + Pagination: pagination, + } +} + +// NewQueryRegisteredUsersRequest returns a new QuerySubspaceRegisteredUsersRequest instance +func NewQueryRegisteredUsersRequest(subspaceID string, pagination *query.PageRequest) *QueryRegisteredUsersRequest { + return &QueryRegisteredUsersRequest{ + SubspaceId: subspaceID, + Pagination: pagination, + } +} + +// NewQueryBannedUsersRequest returns a new QuerySubspaceBannedUsersRequest instance +func NewQueryBannedUsersRequest(subspaceID string, pagination *query.PageRequest) *QueryBannedUsersRequest { + return &QueryBannedUsersRequest{ + SubspaceId: subspaceID, + Pagination: pagination, + } +} diff --git a/x/subspaces/types/query.pb.go b/x/subspaces/types/query.pb.go new file mode 100644 index 0000000000..d040a92635 --- /dev/null +++ b/x/subspaces/types/query.pb.go @@ -0,0 +1,2494 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: desmos/subspaces/v1/query.proto + +package types + +import ( + context "context" + fmt "fmt" + query "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// QuerySubspace is the request type for the Query/Subspace RPC method +type QuerySubspaceRequest struct { + SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` +} + +func (m *QuerySubspaceRequest) Reset() { *m = QuerySubspaceRequest{} } +func (m *QuerySubspaceRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySubspaceRequest) ProtoMessage() {} +func (*QuerySubspaceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{0} +} +func (m *QuerySubspaceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySubspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySubspaceRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySubspaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySubspaceRequest.Merge(m, src) +} +func (m *QuerySubspaceRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySubspaceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySubspaceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySubspaceRequest proto.InternalMessageInfo + +// QuerySubspaceResponse is the response type for the Query/Subspace method +type QuerySubspaceResponse struct { + Subspace Subspace `protobuf:"bytes,1,opt,name=subspace,proto3" json:"subspace"` +} + +func (m *QuerySubspaceResponse) Reset() { *m = QuerySubspaceResponse{} } +func (m *QuerySubspaceResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySubspaceResponse) ProtoMessage() {} +func (*QuerySubspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{1} +} +func (m *QuerySubspaceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySubspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySubspaceResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySubspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySubspaceResponse.Merge(m, src) +} +func (m *QuerySubspaceResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySubspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySubspaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySubspaceResponse proto.InternalMessageInfo + +func (m *QuerySubspaceResponse) GetSubspace() Subspace { + if m != nil { + return m.Subspace + } + return Subspace{} +} + +// QuerySubspacesRequest is the request type for the Query/Subspaces RPC method +type QuerySubspacesRequest struct { + // pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QuerySubspacesRequest) Reset() { *m = QuerySubspacesRequest{} } +func (m *QuerySubspacesRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySubspacesRequest) ProtoMessage() {} +func (*QuerySubspacesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{2} +} +func (m *QuerySubspacesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySubspacesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySubspacesRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySubspacesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySubspacesRequest.Merge(m, src) +} +func (m *QuerySubspacesRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySubspacesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySubspacesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySubspacesRequest proto.InternalMessageInfo + +func (m *QuerySubspacesRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// QuerySubspacesResponse is the response type for the Query/Subspaces RPC +// method +type QuerySubspacesResponse struct { + Subspaces []Subspace `protobuf:"bytes,1,rep,name=subspaces,proto3" json:"subspaces"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QuerySubspacesResponse) Reset() { *m = QuerySubspacesResponse{} } +func (m *QuerySubspacesResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySubspacesResponse) ProtoMessage() {} +func (*QuerySubspacesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{3} +} +func (m *QuerySubspacesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySubspacesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySubspacesResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySubspacesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySubspacesResponse.Merge(m, src) +} +func (m *QuerySubspacesResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySubspacesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySubspacesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySubspacesResponse proto.InternalMessageInfo + +func (m *QuerySubspacesResponse) GetSubspaces() []Subspace { + if m != nil { + return m.Subspaces + } + return nil +} + +func (m *QuerySubspacesResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +// QueryUserGroupsRequest is the request type for the Query/UserGroups RPC +// method +type QueryUserGroupsRequest struct { + SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + // pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryUserGroupsRequest) Reset() { *m = QueryUserGroupsRequest{} } +func (m *QueryUserGroupsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUserGroupsRequest) ProtoMessage() {} +func (*QueryUserGroupsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{4} +} +func (m *QueryUserGroupsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUserGroupsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUserGroupsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUserGroupsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUserGroupsRequest.Merge(m, src) +} +func (m *QueryUserGroupsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryUserGroupsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUserGroupsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUserGroupsRequest proto.InternalMessageInfo + +func (m *QueryUserGroupsRequest) GetSubspaceId() uint64 { + if m != nil { + return m.SubspaceId + } + return 0 +} + +func (m *QueryUserGroupsRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// QueryUserGroupsResponse is the response type for the Query/UserGroups RPC +// method +type QueryUserGroupsResponse struct { + Groups []string `protobuf:"bytes,1,rep,name=groups,proto3" json:"groups,omitempty"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryUserGroupsResponse) Reset() { *m = QueryUserGroupsResponse{} } +func (m *QueryUserGroupsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUserGroupsResponse) ProtoMessage() {} +func (*QueryUserGroupsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{5} +} +func (m *QueryUserGroupsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUserGroupsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUserGroupsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUserGroupsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUserGroupsResponse.Merge(m, src) +} +func (m *QueryUserGroupsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryUserGroupsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUserGroupsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUserGroupsResponse proto.InternalMessageInfo + +func (m *QueryUserGroupsResponse) GetGroups() []string { + if m != nil { + return m.Groups + } + return nil +} + +func (m *QueryUserGroupsResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +// QueryUserGroupMembersRequest is the request type for the +// Query/UserGroupMembers RPC method +type QueryUserGroupMembersRequest struct { + SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` + // pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryUserGroupMembersRequest) Reset() { *m = QueryUserGroupMembersRequest{} } +func (m *QueryUserGroupMembersRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUserGroupMembersRequest) ProtoMessage() {} +func (*QueryUserGroupMembersRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{6} +} +func (m *QueryUserGroupMembersRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUserGroupMembersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUserGroupMembersRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUserGroupMembersRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUserGroupMembersRequest.Merge(m, src) +} +func (m *QueryUserGroupMembersRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryUserGroupMembersRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUserGroupMembersRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUserGroupMembersRequest proto.InternalMessageInfo + +func (m *QueryUserGroupMembersRequest) GetSubspaceId() uint64 { + if m != nil { + return m.SubspaceId + } + return 0 +} + +func (m *QueryUserGroupMembersRequest) GetGroupName() string { + if m != nil { + return m.GroupName + } + return "" +} + +func (m *QueryUserGroupMembersRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// QueryUserGroupMembersResponse is the response type for the +// Query/UserGroupMembers RPC method +type QueryUserGroupMembersResponse struct { + Members []string `protobuf:"bytes,1,rep,name=members,proto3" json:"members,omitempty"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryUserGroupMembersResponse) Reset() { *m = QueryUserGroupMembersResponse{} } +func (m *QueryUserGroupMembersResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUserGroupMembersResponse) ProtoMessage() {} +func (*QueryUserGroupMembersResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{7} +} +func (m *QueryUserGroupMembersResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUserGroupMembersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUserGroupMembersResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUserGroupMembersResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUserGroupMembersResponse.Merge(m, src) +} +func (m *QueryUserGroupMembersResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryUserGroupMembersResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUserGroupMembersResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUserGroupMembersResponse proto.InternalMessageInfo + +func (m *QueryUserGroupMembersResponse) GetMembers() []string { + if m != nil { + return m.Members + } + return nil +} + +func (m *QueryUserGroupMembersResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +// QuerySubspace is the request type for the Query/Subspace RPC method +type QueryPermissionsRequest struct { + SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + Target string `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty" yaml:"target"` +} + +func (m *QueryPermissionsRequest) Reset() { *m = QueryPermissionsRequest{} } +func (m *QueryPermissionsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryPermissionsRequest) ProtoMessage() {} +func (*QueryPermissionsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{8} +} +func (m *QueryPermissionsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPermissionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPermissionsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryPermissionsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPermissionsRequest.Merge(m, src) +} +func (m *QueryPermissionsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryPermissionsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPermissionsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPermissionsRequest proto.InternalMessageInfo + +// QuerySubspaceResponse is the response type for the Query/Subspace method +type QueryPermissionsResponse struct { + Permissions []byte `protobuf:"bytes,1,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` +} + +func (m *QueryPermissionsResponse) Reset() { *m = QueryPermissionsResponse{} } +func (m *QueryPermissionsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryPermissionsResponse) ProtoMessage() {} +func (*QueryPermissionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{9} +} +func (m *QueryPermissionsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryPermissionsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryPermissionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryPermissionsResponse.Merge(m, src) +} +func (m *QueryPermissionsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryPermissionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryPermissionsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryPermissionsResponse proto.InternalMessageInfo + +func (m *QueryPermissionsResponse) GetPermissions() []byte { + if m != nil { + return m.Permissions + } + return nil +} + +func init() { + proto.RegisterType((*QuerySubspaceRequest)(nil), "desmos.subspaces.v1.QuerySubspaceRequest") + proto.RegisterType((*QuerySubspaceResponse)(nil), "desmos.subspaces.v1.QuerySubspaceResponse") + proto.RegisterType((*QuerySubspacesRequest)(nil), "desmos.subspaces.v1.QuerySubspacesRequest") + proto.RegisterType((*QuerySubspacesResponse)(nil), "desmos.subspaces.v1.QuerySubspacesResponse") + proto.RegisterType((*QueryUserGroupsRequest)(nil), "desmos.subspaces.v1.QueryUserGroupsRequest") + proto.RegisterType((*QueryUserGroupsResponse)(nil), "desmos.subspaces.v1.QueryUserGroupsResponse") + proto.RegisterType((*QueryUserGroupMembersRequest)(nil), "desmos.subspaces.v1.QueryUserGroupMembersRequest") + proto.RegisterType((*QueryUserGroupMembersResponse)(nil), "desmos.subspaces.v1.QueryUserGroupMembersResponse") + proto.RegisterType((*QueryPermissionsRequest)(nil), "desmos.subspaces.v1.QueryPermissionsRequest") + proto.RegisterType((*QueryPermissionsResponse)(nil), "desmos.subspaces.v1.QueryPermissionsResponse") +} + +func init() { proto.RegisterFile("desmos/subspaces/v1/query.proto", fileDescriptor_883a12b013a133fc) } + +var fileDescriptor_883a12b013a133fc = []byte{ + // 741 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0x4f, 0x4f, 0x13, 0x4f, + 0x18, 0xc7, 0x3b, 0xc0, 0xaf, 0x3f, 0xfa, 0x54, 0x13, 0x19, 0x01, 0x9b, 0x0d, 0xec, 0x92, 0x8d, + 0x41, 0x01, 0xd9, 0x49, 0xab, 0x09, 0xca, 0x41, 0xb4, 0x07, 0x88, 0x89, 0x1a, 0x5c, 0x35, 0x51, + 0x2f, 0x64, 0x17, 0x26, 0x6b, 0x13, 0xb6, 0xbb, 0xec, 0x6c, 0x1b, 0x91, 0x70, 0xe1, 0xa2, 0x07, + 0x4d, 0x4c, 0x3c, 0xe9, 0x89, 0x83, 0x37, 0xcf, 0xbe, 0x00, 0x6f, 0x1c, 0x49, 0x8c, 0x89, 0xa7, + 0xc6, 0x80, 0x07, 0xcf, 0xbc, 0x02, 0xd3, 0xd9, 0x99, 0x76, 0xfb, 0x47, 0x58, 0x81, 0x5b, 0x67, + 0xe6, 0xfb, 0x3c, 0xcf, 0x67, 0xbe, 0xd3, 0xe7, 0x69, 0x41, 0x5b, 0xa1, 0xcc, 0xf5, 0x18, 0x61, + 0x15, 0x9b, 0xf9, 0xd6, 0x32, 0x65, 0xa4, 0x9a, 0x27, 0x6b, 0x15, 0x1a, 0xac, 0x1b, 0x7e, 0xe0, + 0x85, 0x1e, 0x3e, 0x1f, 0x09, 0x8c, 0x86, 0xc0, 0xa8, 0xe6, 0x95, 0x41, 0xc7, 0x73, 0x3c, 0x7e, + 0x4e, 0xea, 0x9f, 0x22, 0xa9, 0x32, 0xe2, 0x78, 0x9e, 0xb3, 0x4a, 0x89, 0xe5, 0x97, 0x88, 0x55, + 0x2e, 0x7b, 0xa1, 0x15, 0x96, 0xbc, 0x32, 0x13, 0xa7, 0x7a, 0xb7, 0x4a, 0x72, 0x21, 0x34, 0x93, + 0xcb, 0x1e, 0xd7, 0xd8, 0x16, 0xa3, 0x11, 0x05, 0xa9, 0xe6, 0x6d, 0x1a, 0x5a, 0x79, 0xe2, 0x5b, + 0x4e, 0xa9, 0xcc, 0x13, 0x46, 0x5a, 0xfd, 0x29, 0x0c, 0x3e, 0xa8, 0x2b, 0x1e, 0x8a, 0x14, 0x26, + 0x5d, 0xab, 0x50, 0x16, 0xe2, 0x19, 0xc8, 0xca, 0xac, 0x4b, 0xa5, 0x95, 0x1c, 0x1a, 0x43, 0x97, + 0xfb, 0x8a, 0xc3, 0x07, 0x35, 0x0d, 0xaf, 0x5b, 0xee, 0xea, 0xac, 0x1e, 0x3b, 0xd4, 0x4d, 0x90, + 0xab, 0x3b, 0x2b, 0xb3, 0xfd, 0xaf, 0xb7, 0xb5, 0xd4, 0xef, 0x6d, 0x2d, 0xa5, 0x3f, 0x81, 0xa1, + 0xb6, 0xd4, 0xcc, 0xf7, 0xca, 0x8c, 0xe2, 0x39, 0xe8, 0x97, 0x01, 0x3c, 0x71, 0xb6, 0x30, 0x6a, + 0x74, 0xf1, 0xc7, 0x90, 0x81, 0xc5, 0xbe, 0x9d, 0x9a, 0x96, 0x32, 0x1b, 0x41, 0xfa, 0x52, 0x5b, + 0x66, 0x26, 0xa9, 0xe7, 0x01, 0x9a, 0x37, 0x14, 0xb9, 0xc7, 0x8d, 0xc8, 0x0e, 0xa3, 0x6e, 0x87, + 0x11, 0x3d, 0x8a, 0xb0, 0xc3, 0x58, 0xb4, 0x1c, 0x79, 0x63, 0x33, 0x16, 0xa9, 0x7f, 0x42, 0x30, + 0xdc, 0x5e, 0x41, 0xc0, 0xdf, 0x86, 0x4c, 0x03, 0x32, 0x87, 0xc6, 0x7a, 0x93, 0xd2, 0x37, 0xa3, + 0xf0, 0x42, 0x0b, 0x65, 0x0f, 0xa7, 0xbc, 0x74, 0x24, 0x65, 0x54, 0xbf, 0x05, 0xf3, 0x83, 0xc4, + 0x7c, 0xcc, 0x68, 0xb0, 0x10, 0x78, 0x15, 0x9f, 0x9d, 0xf4, 0xfd, 0xda, 0x2c, 0xec, 0x39, 0xb6, + 0x85, 0x2f, 0xe1, 0x42, 0x07, 0x9a, 0xb0, 0x70, 0x18, 0xd2, 0x0e, 0xdf, 0xe1, 0xfe, 0x65, 0x4c, + 0xb1, 0x3a, 0x3d, 0x5f, 0xbe, 0x23, 0x18, 0x69, 0x2d, 0x7e, 0x8f, 0xba, 0x36, 0x0d, 0x4e, 0xee, + 0xce, 0x35, 0x00, 0x0e, 0xbb, 0x54, 0xb6, 0x5c, 0xca, 0x11, 0x33, 0xc5, 0xa1, 0x83, 0x9a, 0x36, + 0x10, 0xc5, 0x35, 0xcf, 0x74, 0x33, 0xc3, 0x17, 0xf7, 0x2d, 0x97, 0xb6, 0x79, 0xda, 0x7b, 0x6c, + 0x4f, 0xb7, 0x10, 0x8c, 0xfe, 0xe5, 0x5e, 0xc2, 0xda, 0x1c, 0xfc, 0xef, 0x46, 0x5b, 0xc2, 0x5b, + 0xb9, 0x3c, 0x3d, 0x73, 0x5f, 0x21, 0xf1, 0xb2, 0x8b, 0x34, 0x70, 0x4b, 0x8c, 0xd5, 0x87, 0xd3, + 0x89, 0x7d, 0x9d, 0x80, 0x74, 0x68, 0x05, 0x0e, 0x0d, 0x85, 0xa7, 0x03, 0x07, 0x35, 0xed, 0x6c, + 0x14, 0x13, 0xed, 0xeb, 0xa6, 0x10, 0xc4, 0x06, 0xcc, 0x23, 0xc8, 0x75, 0x82, 0x08, 0x23, 0xae, + 0x43, 0xd6, 0x6f, 0x6e, 0x73, 0x92, 0x33, 0x71, 0x92, 0xd8, 0xa1, 0x6e, 0xc6, 0xa5, 0x85, 0x2f, + 0x69, 0xf8, 0x8f, 0xa7, 0xc5, 0x6f, 0x11, 0xf4, 0xcb, 0x2e, 0xc6, 0x13, 0x5d, 0x9b, 0xbc, 0xdb, + 0xec, 0x54, 0x26, 0x93, 0x48, 0x23, 0x4e, 0x7d, 0x72, 0xeb, 0xdb, 0xaf, 0xf7, 0x3d, 0x17, 0xb1, + 0x4e, 0xba, 0x0d, 0xf6, 0x8d, 0x98, 0x61, 0x9b, 0xf8, 0x0d, 0x82, 0x4c, 0x63, 0x20, 0xe1, 0x04, + 0x55, 0xe4, 0xbb, 0x28, 0x53, 0x89, 0xb4, 0x02, 0x69, 0x9c, 0x23, 0x8d, 0x61, 0x95, 0x1c, 0xf6, + 0x5b, 0xc3, 0xf0, 0x47, 0x04, 0xd0, 0xec, 0x6e, 0x7c, 0x48, 0x8d, 0x8e, 0xf1, 0xa4, 0x5c, 0x49, + 0x26, 0x16, 0x44, 0x79, 0x4e, 0x34, 0x85, 0x27, 0x8e, 0x36, 0x89, 0x88, 0x59, 0xf2, 0x15, 0xc1, + 0xb9, 0xf6, 0x2e, 0xc1, 0xf9, 0x04, 0x55, 0x5b, 0x27, 0x85, 0x52, 0xf8, 0x97, 0x10, 0x81, 0x3b, + 0xcf, 0x71, 0x6f, 0xe1, 0x9b, 0x89, 0x71, 0xc9, 0x46, 0x73, 0x72, 0x6c, 0x12, 0xd9, 0xb2, 0x9f, + 0x11, 0x64, 0x63, 0xdf, 0x6d, 0x7c, 0x88, 0x69, 0x9d, 0xbd, 0xa8, 0x4c, 0x27, 0x54, 0x0b, 0xe8, + 0x39, 0x0e, 0x7d, 0x03, 0xcf, 0x24, 0x80, 0x8e, 0xb5, 0x0b, 0xd9, 0x88, 0xda, 0x72, 0xb3, 0x78, + 0x77, 0x67, 0x4f, 0x45, 0xbb, 0x7b, 0x2a, 0xfa, 0xb9, 0xa7, 0xa2, 0x77, 0xfb, 0x6a, 0x6a, 0x77, + 0x5f, 0x4d, 0xfd, 0xd8, 0x57, 0x53, 0xcf, 0x0a, 0x4e, 0x29, 0x7c, 0x5e, 0xb1, 0x8d, 0x65, 0xcf, + 0x15, 0xc9, 0xa7, 0x57, 0x2d, 0x9b, 0xc9, 0x42, 0xd5, 0x02, 0x79, 0x11, 0xab, 0x16, 0xae, 0xfb, + 0x94, 0xd9, 0x69, 0xfe, 0xf7, 0xe4, 0xea, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x75, 0x05, 0x78, + 0xdc, 0x5a, 0x09, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // Subspace queries all the information about the subspace with the given id + Subspace(ctx context.Context, in *QuerySubspaceRequest, opts ...grpc.CallOption) (*QuerySubspaceResponse, error) + // Subspaces queries all the subspaces inside Desmos + Subspaces(ctx context.Context, in *QuerySubspacesRequest, opts ...grpc.CallOption) (*QuerySubspacesResponse, error) + // UserGroups queries all the groups that are present inside the subspace with + // the given id + UserGroups(ctx context.Context, in *QueryUserGroupsRequest, opts ...grpc.CallOption) (*QueryUserGroupsResponse, error) + // UserGroupMembers queries all the members of a given user group + UserGroupMembers(ctx context.Context, in *QueryUserGroupMembersRequest, opts ...grpc.CallOption) (*QueryUserGroupMembersResponse, error) + // Permissions queries the permissions for the given target (user address or + // group name) + Permissions(ctx context.Context, in *QueryPermissionsRequest, opts ...grpc.CallOption) (*QueryPermissionsResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Subspace(ctx context.Context, in *QuerySubspaceRequest, opts ...grpc.CallOption) (*QuerySubspaceResponse, error) { + out := new(QuerySubspaceResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/Subspace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Subspaces(ctx context.Context, in *QuerySubspacesRequest, opts ...grpc.CallOption) (*QuerySubspacesResponse, error) { + out := new(QuerySubspacesResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/Subspaces", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) UserGroups(ctx context.Context, in *QueryUserGroupsRequest, opts ...grpc.CallOption) (*QueryUserGroupsResponse, error) { + out := new(QueryUserGroupsResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/UserGroups", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) UserGroupMembers(ctx context.Context, in *QueryUserGroupMembersRequest, opts ...grpc.CallOption) (*QueryUserGroupMembersResponse, error) { + out := new(QueryUserGroupMembersResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/UserGroupMembers", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) Permissions(ctx context.Context, in *QueryPermissionsRequest, opts ...grpc.CallOption) (*QueryPermissionsResponse, error) { + out := new(QueryPermissionsResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/Permissions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Subspace queries all the information about the subspace with the given id + Subspace(context.Context, *QuerySubspaceRequest) (*QuerySubspaceResponse, error) + // Subspaces queries all the subspaces inside Desmos + Subspaces(context.Context, *QuerySubspacesRequest) (*QuerySubspacesResponse, error) + // UserGroups queries all the groups that are present inside the subspace with + // the given id + UserGroups(context.Context, *QueryUserGroupsRequest) (*QueryUserGroupsResponse, error) + // UserGroupMembers queries all the members of a given user group + UserGroupMembers(context.Context, *QueryUserGroupMembersRequest) (*QueryUserGroupMembersResponse, error) + // Permissions queries the permissions for the given target (user address or + // group name) + Permissions(context.Context, *QueryPermissionsRequest) (*QueryPermissionsResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Subspace(ctx context.Context, req *QuerySubspaceRequest) (*QuerySubspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Subspace not implemented") +} +func (*UnimplementedQueryServer) Subspaces(ctx context.Context, req *QuerySubspacesRequest) (*QuerySubspacesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Subspaces not implemented") +} +func (*UnimplementedQueryServer) UserGroups(ctx context.Context, req *QueryUserGroupsRequest) (*QueryUserGroupsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UserGroups not implemented") +} +func (*UnimplementedQueryServer) UserGroupMembers(ctx context.Context, req *QueryUserGroupMembersRequest) (*QueryUserGroupMembersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UserGroupMembers not implemented") +} +func (*UnimplementedQueryServer) Permissions(ctx context.Context, req *QueryPermissionsRequest) (*QueryPermissionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Permissions not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Subspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySubspaceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Subspace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Query/Subspace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Subspace(ctx, req.(*QuerySubspaceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Subspaces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySubspacesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Subspaces(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Query/Subspaces", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Subspaces(ctx, req.(*QuerySubspacesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_UserGroups_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUserGroupsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).UserGroups(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Query/UserGroups", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).UserGroups(ctx, req.(*QueryUserGroupsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_UserGroupMembers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUserGroupMembersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).UserGroupMembers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Query/UserGroupMembers", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).UserGroupMembers(ctx, req.(*QueryUserGroupMembersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_Permissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryPermissionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Permissions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Query/Permissions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Permissions(ctx, req.(*QueryPermissionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "desmos.subspaces.v1.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Subspace", + Handler: _Query_Subspace_Handler, + }, + { + MethodName: "Subspaces", + Handler: _Query_Subspaces_Handler, + }, + { + MethodName: "UserGroups", + Handler: _Query_UserGroups_Handler, + }, + { + MethodName: "UserGroupMembers", + Handler: _Query_UserGroupMembers_Handler, + }, + { + MethodName: "Permissions", + Handler: _Query_Permissions_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "desmos/subspaces/v1/query.proto", +} + +func (m *QuerySubspaceRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySubspaceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySubspaceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SubspaceId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SubspaceId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QuerySubspaceResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySubspaceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySubspaceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Subspace.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QuerySubspacesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySubspacesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySubspacesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QuerySubspacesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySubspacesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySubspacesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Subspaces) > 0 { + for iNdEx := len(m.Subspaces) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Subspaces[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryUserGroupsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUserGroupsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUserGroupsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.SubspaceId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SubspaceId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryUserGroupsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUserGroupsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUserGroupsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Groups) > 0 { + for iNdEx := len(m.Groups) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Groups[iNdEx]) + copy(dAtA[i:], m.Groups[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Groups[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryUserGroupMembersRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUserGroupMembersRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUserGroupMembersRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.GroupName) > 0 { + i -= len(m.GroupName) + copy(dAtA[i:], m.GroupName) + i = encodeVarintQuery(dAtA, i, uint64(len(m.GroupName))) + i-- + dAtA[i] = 0x12 + } + if m.SubspaceId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SubspaceId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryUserGroupMembersResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryUserGroupMembersResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryUserGroupMembersResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Members) > 0 { + for iNdEx := len(m.Members) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Members[iNdEx]) + copy(dAtA[i:], m.Members[iNdEx]) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Members[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryPermissionsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryPermissionsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPermissionsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Target) > 0 { + i -= len(m.Target) + copy(dAtA[i:], m.Target) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Target))) + i-- + dAtA[i] = 0x12 + } + if m.SubspaceId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SubspaceId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *QueryPermissionsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryPermissionsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Permissions) > 0 { + i -= len(m.Permissions) + copy(dAtA[i:], m.Permissions) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Permissions))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QuerySubspaceRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceId != 0 { + n += 1 + sovQuery(uint64(m.SubspaceId)) + } + return n +} + +func (m *QuerySubspaceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Subspace.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QuerySubspacesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySubspacesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Subspaces) > 0 { + for _, e := range m.Subspaces { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryUserGroupsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceId != 0 { + n += 1 + sovQuery(uint64(m.SubspaceId)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryUserGroupsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Groups) > 0 { + for _, s := range m.Groups { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryUserGroupMembersRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceId != 0 { + n += 1 + sovQuery(uint64(m.SubspaceId)) + } + l = len(m.GroupName) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryUserGroupMembersResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Members) > 0 { + for _, s := range m.Members { + l = len(s) + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryPermissionsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceId != 0 { + n += 1 + sovQuery(uint64(m.SubspaceId)) + } + l = len(m.Target) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryPermissionsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Permissions) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QuerySubspaceRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySubspaceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySubspaceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceId", wireType) + } + m.SubspaceId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySubspaceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySubspaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySubspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Subspace.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySubspacesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySubspacesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySubspacesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QuerySubspacesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySubspacesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySubspacesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subspaces", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subspaces = append(m.Subspaces, Subspace{}) + if err := m.Subspaces[len(m.Subspaces)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryUserGroupsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUserGroupsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUserGroupsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceId", wireType) + } + m.SubspaceId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryUserGroupsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUserGroupsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUserGroupsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Groups", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Groups = append(m.Groups, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryUserGroupMembersRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUserGroupMembersRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUserGroupMembersRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceId", wireType) + } + m.SubspaceId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.GroupName = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryUserGroupMembersResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryUserGroupMembersResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryUserGroupMembersResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Members", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Members = append(m.Members, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryPermissionsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryPermissionsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPermissionsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceId", wireType) + } + m.SubspaceId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Target = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryPermissionsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryPermissionsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryPermissionsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Permissions = append(m.Permissions[:0], dAtA[iNdEx:postIndex]...) + if m.Permissions == nil { + m.Permissions = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQuery + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/subspaces/types/query.pb.gw.go b/x/subspaces/types/query.pb.gw.go new file mode 100644 index 0000000000..844c4da071 --- /dev/null +++ b/x/subspaces/types/query.pb.gw.go @@ -0,0 +1,638 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: desmos/subspaces/v1/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage + +func request_Query_Subspace_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySubspaceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + + msg, err := client.Subspace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Subspace_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySubspaceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + + msg, err := server.Subspace(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_Subspaces_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_Subspaces_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySubspacesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Subspaces_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Subspaces(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Subspaces_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySubspacesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Subspaces_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Subspaces(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_UserGroups_0 = &utilities.DoubleArray{Encoding: map[string]int{"subspace_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_Query_UserGroups_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserGroupsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UserGroups_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UserGroups(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_UserGroups_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserGroupsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UserGroups_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UserGroups(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_UserGroupMembers_0 = &utilities.DoubleArray{Encoding: map[string]int{"subspace_id": 0, "group_name": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} +) + +func request_Query_UserGroupMembers_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserGroupMembersRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + + val, ok = pathParams["group_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "group_name") + } + + protoReq.GroupName, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "group_name", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UserGroupMembers_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.UserGroupMembers(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_UserGroupMembers_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserGroupMembersRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + + val, ok = pathParams["group_name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "group_name") + } + + protoReq.GroupName, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "group_name", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UserGroupMembers_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.UserGroupMembers(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_Permissions_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPermissionsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + + val, ok = pathParams["target"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "target") + } + + protoReq.Target, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "target", err) + } + + msg, err := client.Permissions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Permissions_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryPermissionsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + + val, ok = pathParams["target"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "target") + } + + protoReq.Target, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "target", err) + } + + msg, err := server.Permissions(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Subspace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Subspace_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Subspace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Subspaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Subspaces_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Subspaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_UserGroups_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_UserGroups_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UserGroups_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_UserGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_UserGroupMembers_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UserGroupMembers_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Permissions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Permissions_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Permissions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Subspace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Subspace_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Subspace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Subspaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Subspaces_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Subspaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_UserGroups_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_UserGroups_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UserGroups_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_UserGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_UserGroupMembers_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UserGroupMembers_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_Permissions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Permissions_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Permissions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Subspace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"desmos", "subspaces", "v1", "subspace_id"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_Subspaces_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1}, []string{"desmos", "subspaces", "v1"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_UserGroups_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"desmos", "subspaces", "v1", "subspace_id", "groups"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_UserGroupMembers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"desmos", "subspaces", "v1", "subspace_id", "groups", "group_name", "members"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_Permissions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"desmos", "subspaces", "v1", "subspace_id", "permissions", "target"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Query_Subspace_0 = runtime.ForwardResponseMessage + + forward_Query_Subspaces_0 = runtime.ForwardResponseMessage + + forward_Query_UserGroups_0 = runtime.ForwardResponseMessage + + forward_Query_UserGroupMembers_0 = runtime.ForwardResponseMessage + + forward_Query_Permissions_0 = runtime.ForwardResponseMessage +) diff --git a/x/subspaces/types/subspace.go b/x/subspaces/types/subspace.go new file mode 100644 index 0000000000..2261d8f555 --- /dev/null +++ b/x/subspaces/types/subspace.go @@ -0,0 +1,99 @@ +package types + +import ( + "fmt" + "strings" + "time" +) + +// NewSubspace is a constructor for the Subspace type +func NewSubspace(subspaceID, name, owner, creator string, subspaceType SubspaceType, creationTime time.Time) Subspace { + return Subspace{ + ID: subspaceID, + Name: name, + Owner: owner, + Creator: creator, + CreationTime: creationTime, + Type: subspaceType, + } +} + +// WithName is a decorator that will replace the subspace name with a new one +func (sub Subspace) WithName(name string) Subspace { + if strings.TrimSpace(name) != "" { + sub.Name = name + } + return sub +} + +// WithOwner is a decorator that will replace the subspace owner with a new one +func (sub Subspace) WithOwner(owner string) Subspace { + if strings.TrimSpace(owner) != "" { + sub.Owner = owner + } + return sub +} + +// WithSubspaceType is a decorator that will replace the subspace type with a new one +func (sub Subspace) WithSubspaceType(subspaceType SubspaceType) Subspace { + sub.Type = subspaceType + return sub +} + +// Validate will perform some checks to ensure the subspace validity +func (sub Subspace) Validate() error { + if !IsValidSubspace(sub.ID) { + return fmt.Errorf("invalid subspace id: %s it must be a valid SHA-256 hash", sub.ID) + } + + if strings.TrimSpace(sub.Name) == "" { + return fmt.Errorf("subspace name cannot be empty or blank") + } + + if sub.Owner == "" { + return fmt.Errorf("invalid subspace owner: %s", sub.Owner) + } + + if sub.Creator == "" { + return fmt.Errorf("invalid subspace creator: %s", sub.Creator) + } + + if sub.CreationTime.IsZero() { + return fmt.Errorf("invalid subspace creation time: %s", sub.CreationTime) + } + + if !IsValidSubspaceType(sub.Type) { + return fmt.Errorf("invalid subspace type: %s", sub.Type) + } + + return nil +} + +// SubspaceTypeFromString convert a string in the corresponding SubspaceType +func SubspaceTypeFromString(subType string) (SubspaceType, error) { + subspaceType, ok := SubspaceType_value[subType] + if !ok { + return SubspaceTypeUnspecified, fmt.Errorf("'%s' is not a valid subspace type", subType) + } + return SubspaceType(subspaceType), nil +} + +// NormalizeSubspaceType - normalize user specified subspace type +func NormalizeSubspaceType(subType string) string { + switch strings.ToLower(subType) { + case "open": + return SubspaceTypeOpen.String() + case "close": + return SubspaceTypeClosed.String() + default: + return subType + } +} + +// IsValidSubspaceType checks if the subspaceType given correspond to one of the valid ones +func IsValidSubspaceType(subspaceType SubspaceType) bool { + if subspaceType == SubspaceTypeOpen || subspaceType == SubspaceTypeClosed { + return true + } + return false +} diff --git a/x/subspaces/types/subspace.pb.go b/x/subspaces/types/subspace.pb.go new file mode 100644 index 0000000000..5290e4edff --- /dev/null +++ b/x/subspaces/types/subspace.pb.go @@ -0,0 +1,678 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: desmos/subspaces/v1/subspace.proto + +package types + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + _ "google.golang.org/protobuf/types/known/timestamppb" + io "io" + math "math" + math_bits "math/bits" + time "time" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Subspace contains all the data of a Desmos subspace +type Subspace struct { + // Unique SHA-256 string that identifies the subspace + ID uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` + // Human-readable name of the subspace + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` + // Optional description of this subspace + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` + // Address of the user that owns the subspace + Owner string `protobuf:"bytes,4,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` + // Address of the subspace creator + Creator string `protobuf:"bytes,5,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` + // Represents the account that is associated with the subspace and + // should be used to connect external applications to verify this subspace + Treasury string `protobuf:"bytes,6,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + // the creation time of the subspace + CreationTime time.Time `protobuf:"bytes,7,opt,name=creation_time,json=creationTime,proto3,stdtime" json:"creation_time" yaml:"creation_time"` +} + +func (m *Subspace) Reset() { *m = Subspace{} } +func (m *Subspace) String() string { return proto.CompactTextString(m) } +func (*Subspace) ProtoMessage() {} +func (*Subspace) Descriptor() ([]byte, []int) { + return fileDescriptor_64b466175177a54c, []int{0} +} +func (m *Subspace) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Subspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Subspace.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Subspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_Subspace.Merge(m, src) +} +func (m *Subspace) XXX_Size() int { + return m.Size() +} +func (m *Subspace) XXX_DiscardUnknown() { + xxx_messageInfo_Subspace.DiscardUnknown(m) +} + +var xxx_messageInfo_Subspace proto.InternalMessageInfo + +func (m *Subspace) GetID() uint64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *Subspace) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Subspace) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *Subspace) GetOwner() string { + if m != nil { + return m.Owner + } + return "" +} + +func (m *Subspace) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *Subspace) GetTreasury() string { + if m != nil { + return m.Treasury + } + return "" +} + +func (m *Subspace) GetCreationTime() time.Time { + if m != nil { + return m.CreationTime + } + return time.Time{} +} + +func init() { + proto.RegisterType((*Subspace)(nil), "desmos.subspaces.v1.Subspace") +} + +func init() { + proto.RegisterFile("desmos/subspaces/v1/subspace.proto", fileDescriptor_64b466175177a54c) +} + +var fileDescriptor_64b466175177a54c = []byte{ + // 407 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x92, 0x31, 0x8f, 0xd3, 0x30, + 0x1c, 0xc5, 0xeb, 0x5e, 0xef, 0xae, 0xe7, 0x1e, 0x1c, 0x72, 0x4f, 0x28, 0xea, 0x10, 0x57, 0x3e, + 0x09, 0x75, 0x80, 0x58, 0x57, 0x16, 0x74, 0x63, 0xc5, 0x82, 0xc4, 0x14, 0x98, 0x58, 0x90, 0x93, + 0x98, 0x60, 0xa9, 0x89, 0xa3, 0xd8, 0x29, 0x74, 0xe5, 0x13, 0xdc, 0xc8, 0x78, 0x1f, 0xe7, 0xc6, + 0x8e, 0x4c, 0x06, 0xa5, 0x0b, 0x73, 0x3e, 0xc1, 0x29, 0x76, 0x53, 0x65, 0xfb, 0xff, 0xdf, 0xfb, + 0xbd, 0xe8, 0xaf, 0x17, 0x43, 0x92, 0x70, 0x95, 0x49, 0x45, 0x55, 0x15, 0xa9, 0x82, 0xc5, 0x5c, + 0xd1, 0xcd, 0xed, 0x71, 0x09, 0x8a, 0x52, 0x6a, 0x89, 0xa6, 0x8e, 0x09, 0x8e, 0x4c, 0xb0, 0xb9, + 0x9d, 0x5d, 0xa7, 0x32, 0x95, 0xd6, 0xa7, 0xed, 0xe4, 0xd0, 0x19, 0x4e, 0xa5, 0x4c, 0xd7, 0x9c, + 0xda, 0x2d, 0xaa, 0xbe, 0x51, 0x2d, 0x32, 0xae, 0x34, 0xcb, 0x0a, 0x07, 0x90, 0x5f, 0x27, 0x70, + 0xfc, 0xe9, 0xf0, 0x1d, 0x74, 0x03, 0x87, 0x22, 0xf1, 0xc0, 0x1c, 0x2c, 0x46, 0xab, 0x69, 0x6d, + 0xf0, 0xf0, 0xc3, 0xfb, 0xc6, 0xe0, 0x8b, 0x2d, 0xcb, 0xd6, 0x77, 0x44, 0x24, 0x24, 0x1c, 0x8a, + 0x04, 0xdd, 0xc0, 0x51, 0xce, 0x32, 0xee, 0x0d, 0xe7, 0x60, 0x71, 0xb1, 0xba, 0x6a, 0x0c, 0x9e, + 0x38, 0xa0, 0x55, 0x49, 0x68, 0x4d, 0xf4, 0x0e, 0x4e, 0x12, 0xae, 0xe2, 0x52, 0x14, 0x5a, 0xc8, + 0xdc, 0x3b, 0xb1, 0xec, 0xcb, 0xc6, 0x60, 0xe4, 0xd8, 0x9e, 0x49, 0xc2, 0x3e, 0x8a, 0x5e, 0xc1, + 0x53, 0xf9, 0x23, 0xe7, 0xa5, 0x37, 0xb2, 0x99, 0x17, 0x8d, 0xc1, 0x97, 0x2e, 0x63, 0x65, 0x12, + 0x3a, 0x1b, 0xbd, 0x86, 0xe7, 0x71, 0xc9, 0x99, 0x96, 0xa5, 0x77, 0x6a, 0x49, 0xd4, 0x18, 0xfc, + 0xdc, 0x91, 0x07, 0x83, 0x84, 0x1d, 0x82, 0x28, 0x1c, 0xeb, 0x92, 0x33, 0x55, 0x95, 0x5b, 0xef, + 0xcc, 0xe2, 0xd3, 0xc6, 0xe0, 0x2b, 0x87, 0x77, 0x0e, 0x09, 0x8f, 0x10, 0x62, 0xf0, 0x99, 0xcd, + 0x0a, 0x99, 0x7f, 0x6d, 0x3b, 0xf3, 0xce, 0xe7, 0x60, 0x31, 0x59, 0xce, 0x02, 0x57, 0x68, 0xd0, + 0x15, 0x1a, 0x7c, 0xee, 0x0a, 0x5d, 0xcd, 0x1f, 0x0d, 0x1e, 0x34, 0x06, 0x5f, 0xf7, 0x8e, 0xe8, + 0xe2, 0xe4, 0xfe, 0x2f, 0x06, 0xe1, 0x65, 0xa7, 0xb5, 0xa1, 0xbb, 0xf1, 0xef, 0x07, 0x0c, 0xfe, + 0x3f, 0x60, 0xb0, 0xfa, 0xf8, 0x58, 0xfb, 0x60, 0x57, 0xfb, 0xe0, 0x5f, 0xed, 0x83, 0xfb, 0xbd, + 0x3f, 0xd8, 0xed, 0xfd, 0xc1, 0x9f, 0xbd, 0x3f, 0xf8, 0xb2, 0x4c, 0x85, 0xfe, 0x5e, 0x45, 0x41, + 0x2c, 0x33, 0xea, 0xfe, 0xfa, 0x9b, 0x35, 0x8b, 0xd4, 0x61, 0xa6, 0x9b, 0x25, 0xfd, 0xd9, 0x7b, + 0x2a, 0x7a, 0x5b, 0x70, 0x15, 0x9d, 0xd9, 0xdb, 0xde, 0x3e, 0x05, 0x00, 0x00, 0xff, 0xff, 0x57, + 0xc9, 0xd6, 0x66, 0x4b, 0x02, 0x00, 0x00, +} + +func (this *Subspace) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Subspace) + if !ok { + that2, ok := that.(Subspace) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.ID != that1.ID { + return false + } + if this.Name != that1.Name { + return false + } + if this.Description != that1.Description { + return false + } + if this.Owner != that1.Owner { + return false + } + if this.Creator != that1.Creator { + return false + } + if this.Treasury != that1.Treasury { + return false + } + if !this.CreationTime.Equal(that1.CreationTime) { + return false + } + return true +} +func (m *Subspace) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Subspace) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Subspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreationTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreationTime):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintSubspace(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x3a + if len(m.Treasury) > 0 { + i -= len(m.Treasury) + copy(dAtA[i:], m.Treasury) + i = encodeVarintSubspace(dAtA, i, uint64(len(m.Treasury))) + i-- + dAtA[i] = 0x32 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintSubspace(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0x2a + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintSubspace(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0x22 + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintSubspace(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x1a + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintSubspace(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if m.ID != 0 { + i = encodeVarintSubspace(dAtA, i, uint64(m.ID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintSubspace(dAtA []byte, offset int, v uint64) int { + offset -= sovSubspace(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Subspace) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ID != 0 { + n += 1 + sovSubspace(uint64(m.ID)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovSubspace(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovSubspace(uint64(l)) + } + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovSubspace(uint64(l)) + } + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovSubspace(uint64(l)) + } + l = len(m.Treasury) + if l > 0 { + n += 1 + l + sovSubspace(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.CreationTime) + n += 1 + l + sovSubspace(uint64(l)) + return n +} + +func sovSubspace(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozSubspace(x uint64) (n int) { + return sovSubspace(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Subspace) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubspace + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Subspace: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Subspace: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubspace + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubspace + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubspace + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubspace + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubspace + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubspace + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubspace + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubspace + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubspace + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubspace + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubspace + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubspace + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubspace + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubspace + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthSubspace + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSubspace + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Treasury = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreationTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSubspace + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSubspace + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSubspace + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.CreationTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSubspace(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSubspace + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSubspace(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSubspace + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSubspace + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowSubspace + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthSubspace + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupSubspace + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthSubspace + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthSubspace = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSubspace = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupSubspace = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/subspaces/types/subspace_test.go b/x/subspaces/types/subspace_test.go new file mode 100644 index 0000000000..c592fa4b39 --- /dev/null +++ b/x/subspaces/types/subspace_test.go @@ -0,0 +1,236 @@ +package types_test + +import ( + "fmt" + "testing" + "time" + + types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + "github.com/stretchr/testify/require" +) + +func TestSubspace_WithName(t *testing.T) { + sub := types2.NewSubspace( + "123", + "name", + "", + "", + types2.SubspaceTypeOpen, + time.Unix(1, 2), + ).WithName("sub") + require.Equal(t, "sub", sub.Name) +} + +func TestSubspace_WithOwner(t *testing.T) { + sub := types2.NewSubspace( + "123", + "name", + "", + "", + types2.SubspaceTypeOpen, + time.Unix(1, 2), + ).WithOwner("owner") + require.Equal(t, "owner", sub.Owner) +} + +func TestSubspace_WithSubspaceType(t *testing.T) { + sub := types2.NewSubspace( + "123", + "name", + "", + "", + types2.SubspaceTypeOpen, + time.Unix(1, 2), + ).WithSubspaceType(types2.SubspaceTypeClosed) + require.Equal(t, types2.SubspaceTypeClosed, sub.Type) +} + +func TestSubspace_Validate(t *testing.T) { + date := time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC) + tests := []struct { + name string + subspace types2.Subspace + expError bool + }{ + { + name: "Invalid ID returns error", + subspace: types2.NewSubspace( + "123", + "", + "", + "", + types2.SubspaceTypeOpen, + time.Time{}, + ), + expError: true, + }, + { + name: "Invalid name returns error", + subspace: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "", + "", + "", + types2.SubspaceTypeOpen, + time.Time{}, + ), + expError: true, + }, + { + name: "Invalid owner returns error", + subspace: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "", + "", + types2.SubspaceTypeOpen, + time.Time{}, + ), + expError: true, + }, + { + name: "Invalid creator returns error", + subspace: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "", + types2.SubspaceTypeOpen, + time.Time{}, + ), + expError: true, + }, + { + name: "Invalid creation time returns error", + subspace: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + time.Time{}, + ), + expError: true, + }, + { + name: "Valid subspace returns no error", + subspace: types2.NewSubspace( + "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + "test", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", + types2.SubspaceTypeOpen, + date, + ), + expError: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + err := test.subspace.Validate() + if test.expError { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func Test_IsValidSubspaceType(t *testing.T) { + tests := []struct { + name string + subType types2.SubspaceType + expValid bool + }{ + { + name: "valid open type returns true", + subType: types2.SubspaceTypeOpen, + expValid: true, + }, + { + name: "valid close type returns true", + subType: types2.SubspaceTypeClosed, + expValid: true, + }, + { + name: "invalid type returns false", + subType: types2.SubspaceTypeUnspecified, + expValid: false, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + require.Equal(t, test.expValid, types2.IsValidSubspaceType(test.subType)) + }) + } +} + +func Test_NormalizeSubspaceType(t *testing.T) { + tests := []struct { + name string + subType string + expSubType string + }{ + { + name: "Valid Open subspace Type", + subType: "open", + expSubType: types2.SubspaceTypeOpen.String(), + }, + { + name: "Valid Close subspace type", + subType: "Close", + expSubType: types2.SubspaceTypeClosed.String(), + }, + { + name: "Invalid subspace type", + subType: "Invalid", + expSubType: "Invalid", + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + + subspaceType := types2.NormalizeSubspaceType(test.subType) + require.Equal(t, test.expSubType, subspaceType) + }) + } +} + +func Test_SubspaceTypeFromString(t *testing.T) { + tests := []struct { + name string + subType string + expSubType types2.SubspaceType + expError error + }{ + { + name: "Invalid subspace type", + subType: "invalid", + expSubType: types2.SubspaceTypeUnspecified, + expError: fmt.Errorf("'invalid' is not a valid subspace type"), + }, + { + name: "Valid subspace type", + subType: types2.SubspaceTypeOpen.String(), + expSubType: types2.SubspaceTypeOpen, + expError: nil, + }, + } + + for _, test := range tests { + test := test + t.Run(test.name, func(t *testing.T) { + res, err := types2.SubspaceTypeFromString(test.subType) + require.Equal(t, test.expError, err) + require.Equal(t, test.expSubType, res) + }) + } +} diff --git a/x/subspaces/types/utils.go b/x/subspaces/types/utils.go new file mode 100644 index 0000000000..7400a2b2fa --- /dev/null +++ b/x/subspaces/types/utils.go @@ -0,0 +1,12 @@ +package types + +import "regexp" + +var ( + subspaceRegEx = regexp.MustCompile(`^[a-fA-F0-9]{64}$`) +) + +// IsValidSubspace tells whether the given value is a valid subspace or not +func IsValidSubspace(value string) bool { + return subspaceRegEx.MatchString(value) +} From ed8e4747e7d18cc5250fbc323bf07cf22fe43082 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 17 Jan 2022 16:02:53 +0100 Subject: [PATCH 04/47] started working on the implementation of the message server methods Signed-off-by: Riccardo Montagnin --- proto/desmos/subspaces/v1/msgs.proto | 4 +- x/subspaces/keeper/groups.go | 60 + x/subspaces/keeper/keeper.go | 203 ---- x/subspaces/keeper/msg_server.go | 290 +++-- x/subspaces/keeper/permissions.go | 49 + x/subspaces/keeper/subspaces.go | 50 + x/subspaces/types/codec.go | 6 +- x/subspaces/types/errors.go | 1 + x/subspaces/types/events.go | 26 +- x/subspaces/types/genesis.go | 59 +- x/subspaces/types/genesis_test.go | 389 +++--- x/subspaces/types/keys.go | 53 +- x/subspaces/types/msgs.pb.go | 140 +-- x/subspaces/types/msgs_test.go | 1617 +++++++++++++------------ x/subspaces/types/permissions.go | 50 + x/subspaces/types/permissions_test.go | 78 ++ x/subspaces/types/query.go | 26 +- x/subspaces/types/subspace.go | 119 +- x/subspaces/types/subspace_test.go | 469 +++---- x/subspaces/types/utils.go | 12 - 20 files changed, 1909 insertions(+), 1792 deletions(-) create mode 100644 x/subspaces/keeper/groups.go create mode 100644 x/subspaces/keeper/permissions.go create mode 100644 x/subspaces/keeper/subspaces.go create mode 100644 x/subspaces/types/permissions.go create mode 100644 x/subspaces/types/permissions_test.go delete mode 100644 x/subspaces/types/utils.go diff --git a/proto/desmos/subspaces/v1/msgs.proto b/proto/desmos/subspaces/v1/msgs.proto index a745428a3e..d995609585 100644 --- a/proto/desmos/subspaces/v1/msgs.proto +++ b/proto/desmos/subspaces/v1/msgs.proto @@ -63,8 +63,8 @@ message MsgEditSubspace { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; - string id = 1 [ - (gogoproto.customname) = "ID", + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; diff --git a/x/subspaces/keeper/groups.go b/x/subspaces/keeper/groups.go new file mode 100644 index 0000000000..7ed05baed7 --- /dev/null +++ b/x/subspaces/keeper/groups.go @@ -0,0 +1,60 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// HasGroup returns whether the given subspace has a group with the specified name or not +func (k Keeper) HasGroup(ctx sdk.Context, subspaceID uint64, groupName string) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.GroupStoreKey(subspaceID, groupName)) +} + +// SaveUserGroup saves within the subspace having the given id the group with the specified name and permissions +func (k Keeper) SaveUserGroup(ctx sdk.Context, subspaceID uint64, groupName string, permissions types.Permission) { + store := ctx.KVStore(k.storeKey) + + store.Set(types.GroupStoreKey(subspaceID, groupName), []byte{0x01}) + k.SetPermissions(ctx, subspaceID, groupName, permissions) +} + +// DeleteUserGroup deletes the group with the given name from the subspace with the provided id +func (k Keeper) DeleteUserGroup(ctx sdk.Context, subspaceID uint64, groupName string) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.GroupStoreKey(subspaceID, groupName)) +} + +// IsMemberOfGroup returns whether the given user is part of the group with +// the specified name inside the provided subspace +func (k Keeper) IsMemberOfGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.GroupMemberStoreKey(subspaceID, groupName, user.String())) + +} + +// AddUserToGroup adds the given user to the group having the provided name inside the specified subspace. +// If the group does not exist inside the subspace, it returns an error. +func (k Keeper) AddUserToGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) error { + if !k.HasGroup(ctx, subspaceID, groupName) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidVersion, "group with name %s does not exist", groupName) + } + + store := ctx.KVStore(k.storeKey) + store.Set(types.GroupMemberStoreKey(subspaceID, groupName, user.String()), []byte{0x01}) + return nil +} + +// RemoveUserFromGroup removes the specified user from the subspace group having the given name. +// If the group does not exist inside the subspace, it returns an error. +func (k Keeper) RemoveUserFromGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) error { + if !k.HasGroup(ctx, subspaceID, groupName) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidVersion, "group with name %s does not exist", groupName) + } + + store := ctx.KVStore(k.storeKey) + store.Delete(types.GroupMemberStoreKey(subspaceID, groupName, user.String())) + return nil +} diff --git a/x/subspaces/keeper/keeper.go b/x/subspaces/keeper/keeper.go index 22f417d003..3c73377256 100644 --- a/x/subspaces/keeper/keeper.go +++ b/x/subspaces/keeper/keeper.go @@ -3,7 +3,6 @@ package keeper import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/tendermint/tendermint/libs/log" "github.com/desmos-labs/desmos/v2/x/subspaces/types" @@ -26,205 +25,3 @@ func NewKeeper(storeKey sdk.StoreKey, cdc codec.BinaryCodec) Keeper { func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/"+types.ModuleName) } - -// SaveSubspace saves the given subspace inside the current context. -func (k Keeper) SaveSubspace(ctx sdk.Context, subspace types.Subspace, user string) error { - err := subspace.Validate() - if err != nil { - return err - } - - storedSubspace, found := k.GetSubspace(ctx, subspace.ID) - - // Check the editor when the user is trying to edit the subspace - if found && storedSubspace.Owner != user { - return sdkerrors.Wrapf(types.ErrInvalidSubspaceOwner, user) - } - - store := ctx.KVStore(k.storeKey) - key := types.SubspaceStoreKey(subspace.ID) - store.Set(key, k.cdc.MustMarshal(&subspace)) - - k.Logger(ctx).Info("saved subspace", "id", subspace.ID, "owner", subspace.Owner) - return nil -} - -// DoesSubspaceExist checks if the subspace with the given id exists. -func (k Keeper) DoesSubspaceExist(ctx sdk.Context, subspaceID string) bool { - store := ctx.KVStore(k.storeKey) - return store.Has(types.SubspaceStoreKey(subspaceID)) -} - -// GetSubspace returns the subspace associated with the given ID. -// If there is no subspace associated with the given ID the function will return an empty subspace and false. -func (k Keeper) GetSubspace(ctx sdk.Context, subspaceID string) (subspace types.Subspace, found bool) { - if !k.DoesSubspaceExist(ctx, subspaceID) { - return types.Subspace{}, false - } - - store := ctx.KVStore(k.storeKey) - k.cdc.MustUnmarshal(store.Get(types.SubspaceStoreKey(subspaceID)), &subspace) - return subspace, true -} - -// IsAdmin returns true iff the given user is an admin of the subspace with the given id -func (k Keeper) IsAdmin(ctx sdk.Context, subspaceID string, user string) bool { - store := ctx.KVStore(k.storeKey) - return store.Has(types.SubspaceAdminKey(subspaceID, user)) -} - -// AddAdminToSubspace sets the given user as an admin of the subspace having the given id. -// Returns an error if the user is already an admin or the subspace does not exist. -func (k Keeper) AddAdminToSubspace(ctx sdk.Context, subspaceID, user, owner string) error { - // Check if the subspace exists and the owner is valid - err := k.checkSubspaceOwner(ctx, subspaceID, owner) - if err != nil { - return err - } - - // Check if the user we want to set as admin is already an admin - if k.IsAdmin(ctx, subspaceID, user) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "the user with address %s is already an admin", user) - } - - // Store the admin - store := ctx.KVStore(k.storeKey) - store.Set(types.SubspaceAdminKey(subspaceID, user), []byte(user)) - - k.Logger(ctx).Info("added admin", "subspace-id", subspaceID, "admin", user) - return nil -} - -// RemoveAdminFromSubspace removes the given user from the admin set of the subspace having the given id. -// It returns an error if the user was not an admin or the subspace does not exist. -func (k Keeper) RemoveAdminFromSubspace(ctx sdk.Context, subspaceID, user, owner string) error { - // Check if the subspace exists and the owner is valid - err := k.checkSubspaceOwner(ctx, subspaceID, owner) - if err != nil { - return err - } - - // Check if the user is not an admin - if !k.IsAdmin(ctx, subspaceID, user) { - return sdkerrors.Wrapf(types.ErrInvalidSubspaceAdmin, user) - } - - // Delete the admin - store := ctx.KVStore(k.storeKey) - store.Delete(types.SubspaceAdminKey(subspaceID, user)) - - k.Logger(ctx).Info("removed admin", "subspace-id", subspaceID, "admin", user) - return nil -} - -// IsRegistered returns true iff the given user is registered inside the subspace with the given id -func (k Keeper) IsRegistered(ctx sdk.Context, subspaceID, user string) bool { - store := ctx.KVStore(k.storeKey) - return store.Has(types.SubspaceRegisteredUserKey(subspaceID, user)) -} - -// RegisterUserInSubspace registers the given user inside the subspace with the given ID. -// It returns error if the user is already registered or the subspace does not exist. -func (k Keeper) RegisterUserInSubspace(ctx sdk.Context, subspaceID, user, admin string) error { - // Check if the subspace exists and the admin is an actual admin - err := k.checkSubspaceAdmin(ctx, subspaceID, admin) - if err != nil { - return err - } - - // Check if the user is already registered inside the subspace - if k.IsRegistered(ctx, subspaceID, user) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user already registered") - } - - // Store the new user - store := ctx.KVStore(k.storeKey) - store.Set(types.SubspaceRegisteredUserKey(subspaceID, user), []byte(user)) - return nil -} - -// UnregisterUserFromSubspace unregisters the given user from the subspace with the given ID. -// It returns error if the user is not registered or the subspace does not exist. -func (k Keeper) UnregisterUserFromSubspace(ctx sdk.Context, subspaceID, user, admin string) error { - // Check if the subspace exists and the admin is an actual admin - err := k.checkSubspaceAdmin(ctx, subspaceID, admin) - if err != nil { - return err - } - - // Check if the user is already registered inside the subspace - if !k.IsRegistered(ctx, subspaceID, user) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, - "the user with address : %s is not registered inside the subspace: %s", user, subspaceID) - } - - // Remove the user - store := ctx.KVStore(k.storeKey) - store.Delete(types.SubspaceRegisteredUserKey(subspaceID, user)) - return nil -} - -// IsBanned returns true iff the given user is banned inside the subspace with the given id -func (k Keeper) IsBanned(ctx sdk.Context, subspaceID, user string) bool { - store := ctx.KVStore(k.storeKey) - return store.Has(types.SubspaceBannedUserKey(subspaceID, user)) -} - -// BanUserInSubspace bans the given user inside the subspace with the given ID. -// It returns and error if the user is already blocked inside the subspace or the subspace does not exist. -func (k Keeper) BanUserInSubspace(ctx sdk.Context, subspaceID, user, admin string) error { - // Check if the subspace exists and the admin is an actual admin - err := k.checkSubspaceAdmin(ctx, subspaceID, admin) - if err != nil { - return err - } - - // Check if the user is already banned inside the subspace - if k.IsBanned(ctx, subspaceID, user) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user already banned") - } - - // Store the banned user - store := ctx.KVStore(k.storeKey) - store.Set(types.SubspaceBannedUserKey(subspaceID, user), []byte(user)) - return nil -} - -// UnbanUserInSubspace unbans the given user inside the subspace with the given ID. -// It returns error if the user is not banned inside the subspace or the subspace does not exist. -func (k Keeper) UnbanUserInSubspace(ctx sdk.Context, subspaceID, user, admin string) error { - // Check if the subspace exists and the admin is an actual admin - err := k.checkSubspaceAdmin(ctx, subspaceID, admin) - if err != nil { - return err - } - - // Check if the user is already banned inside the subspace - if !k.IsBanned(ctx, subspaceID, user) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "the user is not blocked inside the subspace") - } - - // Remove the banned user - store := ctx.KVStore(k.storeKey) - store.Delete(types.SubspaceBannedUserKey(subspaceID, user)) - return nil -} - -// CheckSubspaceUserPermission checks the permission of the given user inside the subspace with the -// given id to make sure they are able to perform operations inside it -func (k Keeper) CheckSubspaceUserPermission(ctx sdk.Context, subspaceID string, user string) error { - subspace, found := k.GetSubspace(ctx, subspaceID) - if !found { - return sdkerrors.Wrapf(types.ErrInvalidSubspaceID, subspaceID) - } - - if k.IsBanned(ctx, subspaceID, user) { - return sdkerrors.Wrapf(types.ErrPermissionDenied, user) - } - - if subspace.Type == types.SubspaceTypeClosed && !k.IsRegistered(ctx, subspaceID, user) { - return sdkerrors.Wrapf(types.ErrPermissionDenied, user) - } - - return nil -} diff --git a/x/subspaces/keeper/msg_server.go b/x/subspaces/keeper/msg_server.go index 2e125ba311..3b51699852 100644 --- a/x/subspaces/keeper/msg_server.go +++ b/x/subspaces/keeper/msg_server.go @@ -2,9 +2,10 @@ package keeper import ( "context" + "fmt" "time" - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -16,171 +17,254 @@ type msgServer struct { // NewMsgServerImpl returns an implementation of the stored MsgServer interface // for the provided keeper -func NewMsgServerImpl(keeper Keeper) types2.MsgServer { +func NewMsgServerImpl(keeper Keeper) types.MsgServer { return &msgServer{Keeper: keeper} } -var _ types2.MsgServer = msgServer{} +var _ types.MsgServer = msgServer{} -func (k msgServer) CreateSubspace(goCtx context.Context, msg *types2.MsgCreateSubspace) (*types2.MsgCreateSubspaceResponse, error) { +func (k msgServer) CreateSubspace(goCtx context.Context, msg *types.MsgCreateSubspace) (*types.MsgCreateSubspaceResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // Check the if the subspace already exists - if k.DoesSubspaceExist(ctx, msg.SubspaceID) { - return nil, - sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "the subspaces with id %s already exists", msg.SubspaceID) + // Get the next subspace ID + subspaceID, err := k.GetSubspaceID(ctx) + if err != nil { + return nil, err } - // Create and store the new subspaces - creationTime := ctx.BlockTime() - subspace := types2.NewSubspace(msg.SubspaceID, msg.Name, msg.Creator, msg.Creator, msg.SubspaceType, creationTime) - - // Validate the subspace + // Create and validate the subspace + subspace := types.NewSubspace(subspaceID, msg.Name, msg.Description, msg.Owner, msg.Creator, msg.Treasury, ctx.BlockTime()) if err := subspace.Validate(); err != nil { return nil, err } - _ = k.SaveSubspace(ctx, subspace, subspace.Owner) - - ctx.EventManager().EmitEvent(sdk.NewEvent( - types2.EventTypeCreateSubspace, - sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), - sdk.NewAttribute(types2.AttributeKeySubspaceName, msg.Name), - sdk.NewAttribute(types2.AttributeKeySubspaceCreator, msg.Creator), - sdk.NewAttribute(types2.AttributeKeyCreationTime, creationTime.Format(time.RFC3339)), - )) + // Save the subspace + err = k.SaveSubspace(ctx, subspace) + if err != nil { + return nil, err + } - return &types2.MsgCreateSubspaceResponse{}, nil + // Update the id for the next subspace + k.SetSubspaceID(ctx, subspace.ID+1) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator), + ), + sdk.NewEvent( + types.EventTypeCreateSubspace, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", subspaceID)), + sdk.NewAttribute(types.AttributeKeySubspaceName, subspace.Name), + sdk.NewAttribute(types.AttributeKeySubspaceCreator, subspace.Creator), + sdk.NewAttribute(types.AttributeKeyCreationTime, subspace.CreationTime.Format(time.RFC3339)), + ), + }) + + return &types.MsgCreateSubspaceResponse{ + SubspaceID: subspaceID, + }, nil } -func (k msgServer) EditSubspace(goCtx context.Context, msg *types2.MsgEditSubspace) (*types2.MsgEditSubspaceResponse, error) { +func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspace) (*types.MsgEditSubspaceResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // Check the if the subspace exists - subspace, exist := k.GetSubspace(ctx, msg.ID) - if !exist { - return nil, - sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "the subspaces with id %s doesn't exists", msg.ID) + // Check the permission to edit + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionChangeInfo) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot edit this subspace") } - editedSubspace := subspace. - WithName(msg.Name). - WithOwner(msg.Owner). - WithSubspaceType(msg.SubspaceType) + // Check the if the subspace exists + subspace, exists := k.GetSubspace(ctx, msg.SubspaceID) + if !exists { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %s not found", msg.SubspaceID) + } - // Validate the subspace - if err := editedSubspace.Validate(); err != nil { - return nil, err + // Update the subspace and validate it + updated := subspace.Update(types.NewSubspaceUpdate(msg.Name, msg.Description, msg.Owner, msg.Treasury)) + err := updated.Validate() + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) } - if err := k.SaveSubspace(ctx, editedSubspace, msg.Editor); err != nil { + // Save the subspace + err = k.SaveSubspace(ctx, updated) + if err != nil { return nil, err } - ctx.EventManager().EmitEvent(sdk.NewEvent( - types2.EventTypeEditSubspace, - sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.ID), - sdk.NewAttribute(types2.AttributeKeyNewOwner, editedSubspace.Owner), - sdk.NewAttribute(types2.AttributeKeySubspaceName, editedSubspace.Name), - )) - - return &types2.MsgEditSubspaceResponse{}, nil + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), + ), + sdk.NewEvent( + types.EventTypeEditSubspace, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", updated.ID)), + ), + }) + + return &types.MsgEditSubspaceResponse{}, nil } -func (k msgServer) AddAdmin(goCtx context.Context, msg *types2.MsgAddAdmin) (*types2.MsgAddAdminResponse, error) { +func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUserGroup) (*types.MsgCreateUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - err := k.AddAdminToSubspace(ctx, msg.SubspaceID, msg.Admin, msg.Owner) - if err != nil { - return nil, err + // Check the permission first + if !k.HasPermission(ctx, msg.SubspaceID, msg.Creator, types.PermissionSetPermissions) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot create user groups in this subspace") } - ctx.EventManager().EmitEvent(sdk.NewEvent( - types2.EventTypeAddAdmin, - sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), - sdk.NewAttribute(types2.AttributeKeySubspaceNewAdmin, msg.Admin), - )) + // Check if there is another group + if k.HasGroup(ctx, msg.SubspaceID, msg.GroupName) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group with name %s already exists", msg.GroupName) + } - return &types2.MsgAddAdminResponse{}, nil + // Store the group + k.SaveUserGroup(ctx, msg.SubspaceID, msg.GroupName, msg.DefaultPermissions) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator), + ), + sdk.NewEvent( + types.EventTypeCreateUserGroup, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), + sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), + ), + }) + + return &types.MsgCreateUserGroupResponse{}, nil } -func (k msgServer) RemoveAdmin(goCtx context.Context, msg *types2.MsgRemoveAdmin) (*types2.MsgRemoveAdminResponse, error) { +func (k msgServer) DeleteUserGroup(goCtx context.Context, msg *types.MsgDeleteUserGroup) (*types.MsgDeleteUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - err := k.RemoveAdminFromSubspace(ctx, msg.SubspaceID, msg.Admin, msg.Owner) - if err != nil { - return nil, err + // Check for permissions + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot delete user groups in this subspace") } - ctx.EventManager().EmitEvent(sdk.NewEvent( - types2.EventTypeRemoveAdmin, - sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), - sdk.NewAttribute(types2.AttributeKeySubspaceRemovedAdmin, msg.Admin), - )) + // Check if the group exists + if !k.HasGroup(ctx, msg.SubspaceID, msg.GroupName) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %s could not be found", msg.GroupName) + } - return &types2.MsgRemoveAdminResponse{}, nil + // Delete the group + k.Keeper.DeleteUserGroup(ctx, msg.SubspaceID, msg.GroupName) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), + ), + sdk.NewEvent( + types.EventTypeDeleteUserGroup, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), + sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), + ), + }) + + return &types.MsgDeleteUserGroupResponse{}, nil } -func (k msgServer) RegisterUser(goCtx context.Context, msg *types2.MsgRegisterUser) (*types2.MsgRegisterUserResponse, error) { +func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUserToUserGroup) (*types.MsgAddUserToUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if err := k.RegisterUserInSubspace(ctx, msg.SubspaceID, msg.User, msg.Admin); err != nil { - return nil, err + // Check the permissions + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage user group members in this subspace") } - ctx.EventManager().EmitEvent(sdk.NewEvent( - types2.EventTypeRegisterUser, - sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), - sdk.NewAttribute(types2.AttributeKeyRegisteredUser, msg.User), - )) - - return &types2.MsgRegisterUserResponse{}, nil -} + user, err := sdk.AccAddressFromBech32(msg.User) + if err != nil { + return nil, err + } -func (k msgServer) UnregisterUser(goCtx context.Context, msg *types2.MsgUnregisterUser) (*types2.MsgUnregisterUserResponse, error) { - ctx := sdk.UnwrapSDKContext(goCtx) + // Check if the user is already part of the group + if k.IsMemberOfGroup(ctx, msg.SubspaceID, msg.GroupName, user) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user is already part of group %s", msg.GroupName) + } - if err := k.UnregisterUserFromSubspace(ctx, msg.SubspaceID, msg.User, msg.Admin); err != nil { + // Set the user group + err = k.AddUserToGroup(ctx, msg.SubspaceID, msg.GroupName, user) + if err != nil { return nil, err } - ctx.EventManager().EmitEvent(sdk.NewEvent( - types2.EventTypeUnregisterUser, - sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), - sdk.NewAttribute(types2.AttributeKeyUnregisteredUser, msg.User), - )) - - return &types2.MsgUnregisterUserResponse{}, nil + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), + ), + sdk.NewEvent( + types.EventTypeEditSubspace, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), + sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), + sdk.NewAttribute(types.AttributeKeyUser, msg.User), + ), + }) + + return &types.MsgAddUserToUserGroupResponse{}, nil } -func (k msgServer) BanUser(goCtx context.Context, msg *types2.MsgBanUser) (*types2.MsgBanUserResponse, error) { +func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.MsgRemoveUserFromUserGroup) (*types.MsgRemoveUserFromUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if err := k.BanUserInSubspace(ctx, msg.SubspaceID, msg.User, msg.Admin); err != nil { + // Check the permissions + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage user group members in this subspace") + } + + user, err := sdk.AccAddressFromBech32(msg.User) + if err != nil { return nil, err } - ctx.EventManager().EmitEvent(sdk.NewEvent( - types2.EventTypeBanUser, - sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), - sdk.NewAttribute(types2.AttributeKeyBanUser, msg.User), - )) + // Check if the user is already part of the group + if !k.IsMemberOfGroup(ctx, msg.SubspaceID, msg.GroupName, user) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user is not part of group %s", msg.GroupName) + } - return &types2.MsgBanUserResponse{}, nil + // Set the user group + err = k.RemoveUserFromGroup(ctx, msg.SubspaceID, msg.GroupName, user) + if err != nil { + return nil, err + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), + ), + sdk.NewEvent( + types.EventTypeEditSubspace, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), + sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), + sdk.NewAttribute(types.AttributeKeyUser, msg.User), + ), + }) + + return &types.MsgRemoveUserFromUserGroupResponse{}, nil } -func (k msgServer) UnbanUser(goCtx context.Context, msg *types2.MsgUnbanUser) (*types2.MsgUnbanUserResponse, error) { +func (k msgServer) SetPermissions(goCtx context.Context, msg *types.MsgSetPermissions) (*types.MsgSetPermissionsResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - if err := k.UnbanUserInSubspace(ctx, msg.SubspaceID, msg.User, msg.Admin); err != nil { - return nil, err + // Check the permissions + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + return nil, sdkerrors.Wrapf(types.ErrPermissionDenied, "you cannot set other users permissions") } - ctx.EventManager().EmitEvent(sdk.NewEvent( - types2.EventTypeUnbanUser, - sdk.NewAttribute(types2.AttributeKeySubspaceID, msg.SubspaceID), - sdk.NewAttribute(types2.AttributeKeyUnbannedUser, msg.User), - )) + // Set the permissions + k.Keeper.SetPermissions(ctx, msg.SubspaceID, msg.Target, msg.Permissions) - return &types2.MsgUnbanUserResponse{}, nil + return &types.MsgSetPermissionsResponse{}, nil } diff --git a/x/subspaces/keeper/permissions.go b/x/subspaces/keeper/permissions.go new file mode 100644 index 0000000000..94f67d8e91 --- /dev/null +++ b/x/subspaces/keeper/permissions.go @@ -0,0 +1,49 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// GetPermissions returns the permissions that are currently set inside +// the subspace with the given id for the given target +func (k Keeper) GetPermissions(ctx sdk.Context, subspaceID uint64, target string) types.Permission { + store := ctx.KVStore(k.storeKey) + return types.UnmarshalPermission(store.Get(types.PermissionStoreKey(subspaceID, target))) +} + +// GetGroupsInheritedPermissions returns the permissions that the specified target +// has inherited from all the groups that they are part of. +func (k Keeper) GetGroupsInheritedPermissions(ctx sdk.Context, subspaceID uint64, target string) types.Permission { + // TODO + return 0 +} + +// HasPermission checks whether the specific target has the given permission inside a specific subspace +func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, target string, permission types.Permission) (bool, error) { + store := ctx.KVStore(k.storeKey) + + // TODO: Check if the target is the current owner + subspace, found := k.GetSubspace(ctx, subspaceID) + if !found { + return false, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d does not exist", subspaceID) + } + + var defaultPermission = types.PermissionNothing + + // If the target is the owner of the subspace, they should have all the permission + if subspace.Owner == target { + defaultPermission = types.PermissionEverything + } + + // TODO: Check if the target is a user and is part of a group + return (k.GetPermissions(ctx, subspaceID, target) & permission) == permission, nil +} + +// SetPermissions sets the given permission for the specific target inside a single subspace +func (k Keeper) SetPermissions(ctx sdk.Context, subspaceID uint64, target string, permissions uint32) { + store := ctx.KVStore(k.storeKey) + store.Set(types.PermissionStoreKey(subspaceID, target), types.MarshalPermission(permissions)) +} diff --git a/x/subspaces/keeper/subspaces.go b/x/subspaces/keeper/subspaces.go new file mode 100644 index 0000000000..82492d3c50 --- /dev/null +++ b/x/subspaces/keeper/subspaces.go @@ -0,0 +1,50 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// GetSubspaceID gets the highest subspace id +func (k Keeper) GetSubspaceID(ctx sdk.Context) (subspaceID uint64, err error) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.SubspaceIDKey) + if bz == nil { + return 0, sdkerrors.Wrap(types.ErrInvalidGenesis, "initial subspace ID hasn't been set") + } + + subspaceID = types.GetSubspaceIDFromBytes(bz) + return subspaceID, nil +} + +// SetSubspaceID sets the new subspace id to the store +func (k Keeper) SetSubspaceID(ctx sdk.Context, subspaceID uint64) { + store := ctx.KVStore(k.storeKey) + store.Set(types.SubspaceIDKey, types.GetSubspaceIDBytes(subspaceID)) +} + +// SaveSubspace saves the given subspace inside the current context. +func (k Keeper) SaveSubspace(ctx sdk.Context, subspace types.Subspace) error { + store := ctx.KVStore(k.storeKey) + store.Set(types.SubspaceKey(subspace.ID), k.cdc.MustMarshal(&subspace)) + + k.Logger(ctx).Info("subspace saved", "id", subspace.ID) + + return nil +} + +// GetSubspace returns the subspace associated with the given id. +// If there is no subspace associated with the given id the function will return an empty subspace and false. +func (k Keeper) GetSubspace(ctx sdk.Context, subspaceID uint64) (subspace types.Subspace, found bool) { + store := ctx.KVStore(k.storeKey) + + key := types.SubspaceKey(subspaceID) + if !store.Has(key) { + return types.Subspace{}, false + } + + k.cdc.MustUnmarshal(store.Get(key), &subspace) + return subspace, true +} diff --git a/x/subspaces/types/codec.go b/x/subspaces/types/codec.go index 8ac6ec1602..894b3ecf19 100644 --- a/x/subspaces/types/codec.go +++ b/x/subspaces/types/codec.go @@ -12,10 +12,9 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(MsgEditSubspace{}, "desmos/MsgEditSubspace", nil) cdc.RegisterConcrete(MsgCreateUserGroup{}, "desmos/MsgCreateUserGroup", nil) cdc.RegisterConcrete(MsgDeleteUserGroup{}, "desmos/MsgDeleteUserGroup", nil) - cdc.RegisterConcrete(MsgSetUserGroupPermissions{}, "desmos/MsgSetUserGroupPermissions", nil) cdc.RegisterConcrete(MsgAddUserToUserGroup{}, "desmos/MsgAddUserToUserGroup", nil) cdc.RegisterConcrete(MsgRemoveUserFromUserGroup{}, "desmos/MsgRemoveUserFromUserGroup", nil) - cdc.RegisterConcrete(MsgSetUserPermissions{}, "desmos/MsgSetUserPermissions", nil) + cdc.RegisterConcrete(MsgSetPermissions{}, "desmos/MsgSetPermissions", nil) } func RegisterInterfaces(registry types.InterfaceRegistry) { @@ -24,10 +23,9 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &MsgEditSubspace{}, &MsgCreateUserGroup{}, &MsgDeleteUserGroup{}, - &MsgSetUserGroupPermissions{}, &MsgAddUserToUserGroup{}, &MsgRemoveUserFromUserGroup{}, - &MsgSetUserPermissions{}, + &MsgSetPermissions{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/subspaces/types/errors.go b/x/subspaces/types/errors.go index 4ca43b6da0..3b5714886e 100644 --- a/x/subspaces/types/errors.go +++ b/x/subspaces/types/errors.go @@ -7,4 +7,5 @@ import ( var ( // ErrPermissionDenied is returned if a user cannot perform a specific action inside a subspace ErrPermissionDenied = sdkerrors.Register(ModuleName, 1, "permission denied for user") + ErrInvalidGenesis = sdkerrors.Register(ModuleName, 2, "invalid genesis state") ) diff --git a/x/subspaces/types/events.go b/x/subspaces/types/events.go index 3d57983314..ce7953ea12 100644 --- a/x/subspaces/types/events.go +++ b/x/subspaces/types/events.go @@ -2,18 +2,18 @@ package types // Subspaces module event types const ( - EventTypeCreateSubspace = "create_subspace" - EventTypeEditSubspace = "edit_subspace" + EventTypeCreateSubspace = "create_subspace" + EventTypeEditSubspace = "edit_subspace" + EventTypeCreateUserGroup = "create_user_group" + EventTypeDeleteUserGroup = "delete_user_group" + EventTypeAddUserToGroup = "add_group_member" + EventTypeRemoveUserFromGroup = "delete_group_member" - AttributeKeySubspaceID = "subspace_id" - AttributeKeySubspaceName = "subspace_name" - AttributeKeySubspaceCreator = "subspace_creator" - AttributeKeyCreationTime = "creation_date" - AttributeKeySubspaceNewAdmin = "new_admin" - AttributeKeySubspaceRemovedAdmin = "removed_admin" - AttributeKeyRegisteredUser = "registered_user" - AttributeKeyUnregisteredUser = "unregistered_user" - AttributeKeyBanUser = "banned_user" - AttributeKeyUnbannedUser = "unbanned_user" - AttributeKeyNewOwner = "new_owner" + AttributeValueCategory = ModuleName + AttributeKeySubspaceID = "subspace_id" + AttributeKeySubspaceName = "subspace_name" + AttributeKeySubspaceCreator = "subspace_creator" + AttributeKeyCreationTime = "creation_date" + AttributeKeyUserGroupName = "user_group_name" + AttributeKeyUser = "user" ) diff --git a/x/subspaces/types/genesis.go b/x/subspaces/types/genesis.go index c2de5538ee..a3ad7c0bf6 100644 --- a/x/subspaces/types/genesis.go +++ b/x/subspaces/types/genesis.go @@ -27,45 +27,11 @@ func ValidateGenesis(data *GenesisState) error { for _, subspace := range data.Subspaces { if containsDuplicatedSubspace(data.Subspaces, subspace) { - return fmt.Errorf("duplicated subspace: %s", subspace.ID) + return fmt.Errorf("duplicated subspace: %d", subspace.ID) } } - for _, entry := range data.Admins { - if isEntryDuplicated(data.Admins, entry) { - return fmt.Errorf("duplicated admins entry for subspace with id %s", entry.SubspaceID) - } - - for _, admin := range entry.Users { - if containsDuplicatedValue(entry.Users, admin) { - return fmt.Errorf("duplicated admin for subspace with id %s: %s", entry.SubspaceID, admin) - } - } - } - - for _, entry := range data.RegisteredUsers { - if isEntryDuplicated(data.RegisteredUsers, entry) { - return fmt.Errorf("duplicated registered users entry for subspace with id %s", entry.SubspaceID) - } - - for _, user := range entry.Users { - if containsDuplicatedValue(entry.Users, user) { - return fmt.Errorf("duplicated registered user for subspace with id %s: %s", entry.SubspaceID, user) - } - } - } - - for _, entry := range data.BannedUsers { - if isEntryDuplicated(data.BannedUsers, entry) { - return fmt.Errorf("duplicated banned users entry for subspace with id %s", entry.SubspaceID) - } - - for _, user := range entry.Users { - if containsDuplicatedValue(entry.Users, user) { - return fmt.Errorf("duplicated banned user for subspace with id %s: %s", entry.SubspaceID, user) - } - } - } + // TODO return nil } @@ -80,24 +46,3 @@ func containsDuplicatedSubspace(subspaces []Subspace, subspace Subspace) bool { } return count > 1 } - -func isEntryDuplicated(entries []UsersEntry, entry UsersEntry) bool { - var count = 0 - for _, e := range entries { - if e.SubspaceID == entry.SubspaceID { - count++ - } - } - return count > 1 -} - -// containsDuplicatedValue tells whether the given entries slice contains duplicates of the provided value -func containsDuplicatedValue(slice []string, value string) bool { - var count = 0 - for _, e := range slice { - if e == value { - count++ - } - } - return count > 1 -} diff --git a/x/subspaces/types/genesis_test.go b/x/subspaces/types/genesis_test.go index bde7c656ee..846349ec1a 100644 --- a/x/subspaces/types/genesis_test.go +++ b/x/subspaces/types/genesis_test.go @@ -1,196 +1,197 @@ package types_test -import ( - "testing" - "time" - - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - "github.com/stretchr/testify/require" -) - -func TestValidateGenesis(t *testing.T) { - date, err := time.Parse(time.RFC3339, "2050-01-01T15:15:00.000Z") - require.NoError(t, err) - - tests := []struct { - name string - genesis *types2.GenesisState - shouldErr bool - }{ - { - name: "Default genesis does not error", - genesis: types2.DefaultGenesisState(), - shouldErr: false, - }, - { - name: "Genesis with invalid subspaces returns error", - genesis: types2.NewGenesisState( - []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "", - "", - "", - types2.SubspaceTypeOpen, - time.Time{}, - ), - }, - nil, - nil, - nil, - ), - shouldErr: true, - }, - { - name: "Genesis with duplicated subspaces returns error", - genesis: types2.NewGenesisState( - []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "name", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - date, - ), - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "name", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - date, - ), - }, - nil, - nil, - nil, - ), - shouldErr: true, - }, - { - name: "Genesis with duplicated admins entry returns error", - genesis: types2.NewGenesisState( - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, - ), - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, - ), - }, - nil, - nil, - ), - shouldErr: true, - }, - { - name: "Genesis with duplicated admins returns error", - genesis: types2.NewGenesisState( - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{ - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - }, - ), - }, - nil, - nil, - ), - shouldErr: true, - }, - { - name: "Genesis with duplicated registered users entry returns error", - genesis: types2.NewGenesisState( - nil, - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, - ), - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, - ), - }, - nil, - ), - shouldErr: true, - }, - { - name: "Genesis with duplicated registered users returns error", - genesis: types2.NewGenesisState( - nil, - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{ - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - }, - ), - }, - nil, - ), - shouldErr: true, - }, - { - name: "Genesis with duplicated banned users entry returns error", - genesis: types2.NewGenesisState( - nil, - nil, - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, - ), - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, - ), - }, - ), - shouldErr: true, - }, - { - name: "Genesis with duplicated banned users returns error", - genesis: types2.NewGenesisState( - nil, - nil, - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{ - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - }, - ), - }, - ), - shouldErr: true, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err = types2.ValidateGenesis(test.genesis) - if test.shouldErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} +// +//import ( +// "testing" +// "time" +// +// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" +// +// "github.com/stretchr/testify/require" +//) +// +//func TestValidateGenesis(t *testing.T) { +// date, err := time.Parse(time.RFC3339, "2050-01-01T15:15:00.000Z") +// require.NoError(t, err) +// +// tests := []struct { +// name string +// genesis *types2.GenesisState +// shouldErr bool +// }{ +// { +// name: "Default genesis does not error", +// genesis: types2.DefaultGenesisState(), +// shouldErr: false, +// }, +// { +// name: "Genesis with invalid subspaces returns error", +// genesis: types2.NewGenesisState( +// []types2.Subspace{ +// types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "", +// "", +// "", +// types2.SubspaceTypeOpen, +// time.Time{}, +// ), +// }, +// nil, +// nil, +// nil, +// ), +// shouldErr: true, +// }, +// { +// name: "Genesis with duplicated subspaces returns error", +// genesis: types2.NewGenesisState( +// []types2.Subspace{ +// types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "name", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// types2.SubspaceTypeOpen, +// date, +// ), +// types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "name", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// types2.SubspaceTypeOpen, +// date, +// ), +// }, +// nil, +// nil, +// nil, +// ), +// shouldErr: true, +// }, +// { +// name: "Genesis with duplicated admins entry returns error", +// genesis: types2.NewGenesisState( +// nil, +// []types2.UsersEntry{ +// types2.NewUsersEntry( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, +// ), +// types2.NewUsersEntry( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, +// ), +// }, +// nil, +// nil, +// ), +// shouldErr: true, +// }, +// { +// name: "Genesis with duplicated admins returns error", +// genesis: types2.NewGenesisState( +// nil, +// []types2.UsersEntry{ +// types2.NewUsersEntry( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// []string{ +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// }, +// ), +// }, +// nil, +// nil, +// ), +// shouldErr: true, +// }, +// { +// name: "Genesis with duplicated registered users entry returns error", +// genesis: types2.NewGenesisState( +// nil, +// nil, +// []types2.UsersEntry{ +// types2.NewUsersEntry( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, +// ), +// types2.NewUsersEntry( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, +// ), +// }, +// nil, +// ), +// shouldErr: true, +// }, +// { +// name: "Genesis with duplicated registered users returns error", +// genesis: types2.NewGenesisState( +// nil, +// nil, +// []types2.UsersEntry{ +// types2.NewUsersEntry( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// []string{ +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// }, +// ), +// }, +// nil, +// ), +// shouldErr: true, +// }, +// { +// name: "Genesis with duplicated banned users entry returns error", +// genesis: types2.NewGenesisState( +// nil, +// nil, +// nil, +// []types2.UsersEntry{ +// types2.NewUsersEntry( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, +// ), +// types2.NewUsersEntry( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, +// ), +// }, +// ), +// shouldErr: true, +// }, +// { +// name: "Genesis with duplicated banned users returns error", +// genesis: types2.NewGenesisState( +// nil, +// nil, +// nil, +// []types2.UsersEntry{ +// types2.NewUsersEntry( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// []string{ +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// }, +// ), +// }, +// ), +// shouldErr: true, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err = types2.ValidateGenesis(test.genesis) +// if test.shouldErr { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} diff --git a/x/subspaces/types/keys.go b/x/subspaces/types/keys.go index 0c8cccc89b..719dcdf0b7 100644 --- a/x/subspaces/types/keys.go +++ b/x/subspaces/types/keys.go @@ -1,5 +1,7 @@ package types +import "encoding/binary" + // DONTCOVER const ( @@ -16,13 +18,56 @@ const ( ActionSetPermissions = "set_permissions" QuerierRoute = ModuleName + + DoNotModify = "[do-not-modify]" ) var ( - SubspaceStorePrefix = []byte("subspace") + SubspacePrefix = []byte{0x00} + SubspaceIDKey = []byte{0x01} + ACLStorePrefix = []byte{0x02} + GroupsStorePrefix = []byte{0x03} + GroupMembersStorePrefix = []byte{0x4} ) -// SubspaceStoreKey turns an id to a key used to store a subspace into the subspaces store -func SubspaceStoreKey(id string) []byte { - return append(SubspaceStorePrefix, []byte(id)...) +// GetSubspaceIDBytes returns the byte representation of the subspaceID +func GetSubspaceIDBytes(subspaceID uint64) (subspaceIDBz []byte) { + subspaceIDBz = make([]byte, 8) + binary.BigEndian.PutUint64(subspaceIDBz, subspaceID) + return +} + +// GetSubspaceIDFromBytes returns subspaceID in uint64 format from a byte array +func GetSubspaceIDFromBytes(bz []byte) (subspaceID uint64) { + return binary.BigEndian.Uint64(bz) +} + +// SubspaceKey returns the key for a specific subspace +func SubspaceKey(subspaceID uint64) []byte { + return append(SubspacePrefix, GetSubspaceIDBytes(subspaceID)...) +} + +func ACLStoreKey(subspaceID uint64) []byte { + return append(ACLStorePrefix, GetSubspaceIDBytes(subspaceID)...) +} + +func PermissionStoreKey(subspaceID uint64, target string) []byte { + return append(ACLStoreKey(subspaceID), []byte(target)...) +} + +func GroupsStoreKey(subspaceID uint64) []byte { + return append(GroupsStorePrefix, GetSubspaceIDBytes(subspaceID)...) +} + +// GroupStoreKey returns the key used to store a group for a subspace +func GroupStoreKey(subspaceID uint64, groupName string) []byte { + return append(GroupsStoreKey(subspaceID), []byte(groupName)...) +} + +func GroupMembersStoreKey(subspaceID uint64, groupName string) []byte { + return append(append(GroupMembersStorePrefix, GetSubspaceIDBytes(subspaceID)...), []byte(groupName)...) +} + +func GroupMemberStoreKey(subspaceID uint64, groupName string, user string) []byte { + return append(GroupStoreKey(subspaceID, groupName), []byte(user)...) } diff --git a/x/subspaces/types/msgs.pb.go b/x/subspaces/types/msgs.pb.go index 7351655d78..aac9e20208 100644 --- a/x/subspaces/types/msgs.pb.go +++ b/x/subspaces/types/msgs.pb.go @@ -117,7 +117,7 @@ func (m *MsgCreateSubspaceResponse) GetSubspaceID() uint64 { // MsgEditSubspace represents the message used to edit a subspace fields type MsgEditSubspace struct { - ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"subspace_id"` + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` Owner string `protobuf:"bytes,4,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` @@ -743,58 +743,58 @@ func init() { func init() { proto.RegisterFile("desmos/subspaces/v1/msgs.proto", fileDescriptor_c16a431ff9a3b35b) } var fileDescriptor_c16a431ff9a3b35b = []byte{ - // 814 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0xcd, 0x6e, 0xd3, 0x4a, - 0x14, 0xc7, 0x63, 0x27, 0xcd, 0x6d, 0x4f, 0x3f, 0x72, 0xeb, 0xde, 0xde, 0xa6, 0xa6, 0xd8, 0x68, - 0x5a, 0x15, 0x8a, 0x4a, 0xac, 0x06, 0x24, 0x50, 0x77, 0x84, 0x16, 0x54, 0x89, 0x00, 0x72, 0x61, - 0xc3, 0xa6, 0x72, 0xe2, 0xc1, 0xb5, 0x88, 0xe3, 0xc8, 0xe3, 0x04, 0xba, 0xee, 0x86, 0x65, 0x25, - 0x5e, 0xa0, 0x0f, 0xc0, 0x23, 0xf0, 0x00, 0x2c, 0xbb, 0x64, 0x65, 0xa1, 0x94, 0x05, 0xb0, 0xf4, - 0x13, 0x20, 0x8f, 0x3f, 0xe2, 0x38, 0x31, 0x4d, 0x50, 0x17, 0x88, 0x9d, 0x7d, 0xce, 0x6f, 0xce, - 0xf8, 0xfc, 0xcf, 0xcc, 0x39, 0x06, 0x41, 0xc5, 0xc4, 0x30, 0x89, 0x44, 0xda, 0x35, 0xd2, 0x52, - 0xea, 0x98, 0x48, 0x9d, 0x2d, 0xc9, 0x20, 0x1a, 0x29, 0xb5, 0x2c, 0xd3, 0x36, 0xb9, 0x05, 0xdf, - 0x5f, 0x8a, 0xfc, 0xa5, 0xce, 0x16, 0xff, 0x9f, 0x66, 0x6a, 0x26, 0xf5, 0x4b, 0xde, 0x93, 0x8f, - 0xf2, 0x68, 0x58, 0xa8, 0xf0, 0xc5, 0x67, 0xd0, 0x31, 0x0b, 0xf3, 0x55, 0xa2, 0x3d, 0xb0, 0xb0, - 0x62, 0xe3, 0xfd, 0xc0, 0xc7, 0xad, 0x42, 0xae, 0xa9, 0x18, 0xb8, 0xc8, 0x5c, 0x63, 0x6e, 0x4c, - 0x55, 0x0a, 0xae, 0x23, 0x4e, 0x1f, 0x29, 0x46, 0x63, 0x1b, 0x79, 0x56, 0x24, 0x53, 0x27, 0x77, - 0x0f, 0xa6, 0x55, 0x4c, 0xea, 0x96, 0xde, 0xb2, 0x75, 0xb3, 0x59, 0x64, 0x29, 0xfb, 0xbf, 0xeb, - 0x88, 0x9c, 0xcf, 0xc6, 0x9c, 0x48, 0x8e, 0xa3, 0xdc, 0x3a, 0x4c, 0x98, 0x6f, 0x9a, 0xd8, 0x2a, - 0x66, 0xe9, 0x9a, 0x7f, 0x5d, 0x47, 0x9c, 0xf1, 0xd7, 0x50, 0x33, 0x92, 0x7d, 0x37, 0x27, 0xc1, - 0xa4, 0x6d, 0x61, 0x85, 0xb4, 0xad, 0xa3, 0x62, 0x8e, 0xa2, 0x0b, 0xae, 0x23, 0x16, 0x7c, 0x34, - 0xf4, 0x20, 0x39, 0x82, 0xb8, 0x4d, 0xf8, 0xa7, 0xee, 0x65, 0x62, 0x5a, 0xc5, 0x09, 0xca, 0x73, - 0xae, 0x23, 0xce, 0xf9, 0x7c, 0xe0, 0x40, 0x72, 0x88, 0x6c, 0x4f, 0xbe, 0x3b, 0x15, 0x33, 0xdf, - 0x4e, 0xc5, 0x0c, 0xaa, 0xc1, 0xf2, 0x80, 0x08, 0x32, 0x26, 0x2d, 0xb3, 0x49, 0x30, 0xb7, 0x0b, - 0xd3, 0xa1, 0x68, 0x07, 0xba, 0x4a, 0x35, 0xc9, 0x55, 0xd6, 0xba, 0x8e, 0x08, 0x21, 0xba, 0xb7, - 0xd3, 0xcb, 0x3a, 0x86, 0x22, 0x19, 0xc2, 0xb7, 0x3d, 0x15, 0x7d, 0x60, 0xa1, 0x50, 0x25, 0xda, - 0xae, 0xaa, 0xdb, 0x91, 0xce, 0x9b, 0xc0, 0x06, 0x11, 0xa7, 0x2a, 0x2b, 0x5d, 0x47, 0x64, 0x53, - 0x23, 0xb1, 0xba, 0x1a, 0x55, 0x85, 0x1d, 0xa3, 0x2a, 0xd9, 0xdf, 0xa8, 0x4a, 0x6e, 0xf4, 0xaa, - 0x4c, 0x8c, 0x52, 0x95, 0x0d, 0xc8, 0x13, 0x5d, 0xf3, 0x22, 0xe7, 0x29, 0x3e, 0xef, 0x3a, 0xe2, - 0x6c, 0x90, 0x23, 0xb5, 0x23, 0x39, 0x00, 0x62, 0x25, 0x59, 0x86, 0xa5, 0x84, 0x5a, 0x61, 0x41, - 0xd0, 0x09, 0x0b, 0x5c, 0x54, 0xae, 0x17, 0x04, 0x5b, 0x8f, 0x2c, 0xb3, 0xdd, 0xba, 0xa4, 0x3a, - 0x71, 0x77, 0x00, 0x34, 0x2f, 0xde, 0x41, 0x4c, 0xeb, 0x45, 0xd7, 0x11, 0xe7, 0xfd, 0x75, 0x3d, - 0x1f, 0x92, 0xa7, 0xe8, 0xcb, 0x13, 0x4f, 0xf6, 0xa7, 0xb0, 0xa0, 0xe2, 0x57, 0x4a, 0xbb, 0x61, - 0x1f, 0xb4, 0xb0, 0x65, 0xe8, 0x84, 0xe8, 0x66, 0x93, 0x50, 0xf9, 0x67, 0x2b, 0x82, 0xeb, 0x88, - 0x7c, 0x28, 0xff, 0x00, 0x84, 0x64, 0x2e, 0xb0, 0x3e, 0xeb, 0x19, 0xe3, 0x47, 0x39, 0x77, 0xe1, - 0x51, 0x46, 0x2b, 0xc0, 0x0f, 0x2a, 0x12, 0x09, 0xf6, 0x91, 0xa1, 0x82, 0xed, 0xe0, 0x06, 0xfe, - 0x63, 0x04, 0xeb, 0x1d, 0x8a, 0xec, 0x05, 0x87, 0x22, 0x48, 0x2e, 0xf1, 0xf5, 0x51, 0x72, 0x5f, - 0x19, 0x58, 0xac, 0x12, 0xed, 0xbe, 0xaa, 0x7a, 0xbe, 0xe7, 0xe6, 0xa5, 0xe7, 0xb7, 0x0a, 0xb9, - 0x36, 0xc1, 0xd6, 0xe0, 0xb5, 0xf3, 0xac, 0x48, 0xa6, 0xce, 0x84, 0x08, 0xd9, 0xb1, 0x45, 0xc8, - 0x5d, 0x24, 0x82, 0x08, 0x57, 0x87, 0x66, 0x19, 0xe9, 0xf0, 0x9d, 0xa1, 0x32, 0xc9, 0xd8, 0x30, - 0x3b, 0x54, 0xa6, 0x87, 0x96, 0x69, 0xfc, 0xa5, 0x62, 0xac, 0x01, 0x4a, 0x4f, 0x35, 0x52, 0xe4, - 0x07, 0x43, 0x67, 0xdb, 0x3e, 0xee, 0xbb, 0x58, 0x97, 0x24, 0xc4, 0x06, 0xe4, 0x6d, 0xc5, 0xd2, - 0xb0, 0x1d, 0x48, 0x11, 0xfb, 0x5a, 0xdf, 0x8e, 0xe4, 0x00, 0xf0, 0x5a, 0xf2, 0x60, 0x4f, 0x88, - 0xb5, 0xe4, 0xbe, 0x5e, 0x10, 0x47, 0xc7, 0x91, 0xe4, 0x0a, 0x1d, 0x61, 0xfd, 0xb9, 0x86, 0x4a, - 0x94, 0xdf, 0xe7, 0x21, 0x5b, 0x25, 0x1a, 0x77, 0x08, 0x73, 0x89, 0x49, 0xbf, 0x5e, 0x1a, 0xf2, - 0x3f, 0x51, 0x1a, 0x18, 0x86, 0x7c, 0x69, 0x34, 0x2e, 0x1a, 0x9a, 0x35, 0x98, 0xe9, 0x9b, 0x74, - 0x6b, 0x69, 0xeb, 0xe3, 0x14, 0xbf, 0x39, 0x0a, 0x15, 0xed, 0xf1, 0x1a, 0x0a, 0xc9, 0x19, 0x70, - 0xfd, 0xd7, 0x9f, 0x19, 0x81, 0xbc, 0x34, 0x22, 0x18, 0xdf, 0x2c, 0xd9, 0x3f, 0x53, 0x37, 0x4b, - 0x80, 0xe9, 0x9b, 0xa5, 0xf4, 0x34, 0xce, 0x06, 0x6e, 0x48, 0x3f, 0xbb, 0x99, 0x16, 0x66, 0x90, - 0xe5, 0xcb, 0xa3, 0xb3, 0xd1, 0xae, 0xc7, 0x0c, 0x2c, 0xa5, 0xb5, 0x8f, 0xd4, 0x14, 0x52, 0x16, - 0xf0, 0x77, 0xc7, 0x5c, 0x10, 0x7d, 0xc5, 0x21, 0xcc, 0x25, 0x6e, 0x6c, 0xea, 0x19, 0xed, 0xe7, - 0xd2, 0xcf, 0xe8, 0xf0, 0x5b, 0x51, 0x79, 0xfc, 0xa9, 0x2b, 0x30, 0x67, 0x5d, 0x81, 0xf9, 0xd2, - 0x15, 0x98, 0x93, 0x73, 0x21, 0x73, 0x76, 0x2e, 0x64, 0x3e, 0x9f, 0x0b, 0x99, 0x97, 0x65, 0x4d, - 0xb7, 0x0f, 0xdb, 0xb5, 0x52, 0xdd, 0x34, 0x24, 0x3f, 0xe6, 0xad, 0x86, 0x52, 0x23, 0xc1, 0xb3, - 0xd4, 0x29, 0x4b, 0x6f, 0x63, 0x7f, 0xd5, 0xf6, 0x51, 0x0b, 0x93, 0x5a, 0x9e, 0xfe, 0x50, 0xdf, - 0xfe, 0x19, 0x00, 0x00, 0xff, 0xff, 0xe6, 0xa0, 0xbf, 0x5e, 0xc1, 0x0b, 0x00, 0x00, + // 803 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0xcf, 0x6f, 0xd3, 0x48, + 0x14, 0xc7, 0xe3, 0x24, 0xcd, 0xb6, 0xaf, 0x3f, 0xb2, 0x75, 0xb7, 0xdb, 0xd4, 0xbb, 0x6b, 0xaf, + 0xa6, 0x55, 0x77, 0xbb, 0xea, 0xc6, 0x6a, 0x76, 0x25, 0x50, 0x6f, 0x84, 0x16, 0x54, 0x89, 0x00, + 0x72, 0xe1, 0xc2, 0xa5, 0x72, 0xe2, 0xc1, 0xb5, 0x88, 0x33, 0x91, 0xc7, 0x09, 0xf4, 0xdc, 0x0b, + 0xc7, 0x4a, 0xfc, 0x03, 0xfd, 0x43, 0xb8, 0x22, 0x71, 0xec, 0x91, 0x93, 0x85, 0x52, 0x0e, 0xc0, + 0xd1, 0x7f, 0x01, 0xf2, 0xf8, 0x47, 0x1c, 0x27, 0xa6, 0x09, 0xca, 0x01, 0x71, 0xb3, 0xdf, 0xfb, + 0xcc, 0x8f, 0xf7, 0x7d, 0x33, 0xef, 0x0d, 0x88, 0x1a, 0xa6, 0x26, 0xa1, 0x32, 0xed, 0xd4, 0x69, + 0x5b, 0x6d, 0x60, 0x2a, 0x77, 0x77, 0x65, 0x93, 0xea, 0xb4, 0xdc, 0xb6, 0x88, 0x4d, 0xf8, 0x15, + 0xdf, 0x5f, 0x8e, 0xfc, 0xe5, 0xee, 0xae, 0xf0, 0x8b, 0x4e, 0x74, 0xc2, 0xfc, 0xb2, 0xf7, 0xe5, + 0xa3, 0x02, 0x1a, 0x35, 0x55, 0xf8, 0xe3, 0x33, 0xe8, 0x2c, 0x0b, 0xcb, 0x35, 0xaa, 0xdf, 0xb6, + 0xb0, 0x6a, 0xe3, 0xa3, 0xc0, 0xc7, 0x6f, 0x40, 0xbe, 0xa5, 0x9a, 0xb8, 0xc4, 0xfd, 0xc9, 0xfd, + 0x3d, 0x57, 0x2d, 0xba, 0x8e, 0x34, 0x7f, 0xaa, 0x9a, 0xcd, 0x3d, 0xe4, 0x59, 0x91, 0xc2, 0x9c, + 0xfc, 0x4d, 0x98, 0xd7, 0x30, 0x6d, 0x58, 0x46, 0xdb, 0x36, 0x48, 0xab, 0x94, 0x65, 0xec, 0xaf, + 0xae, 0x23, 0xf1, 0x3e, 0x1b, 0x73, 0x22, 0x25, 0x8e, 0xf2, 0x5b, 0x30, 0x43, 0x9e, 0xb7, 0xb0, + 0x55, 0xca, 0xb1, 0x31, 0x3f, 0xbb, 0x8e, 0xb4, 0xe0, 0x8f, 0x61, 0x66, 0xa4, 0xf8, 0x6e, 0x5e, + 0x86, 0x59, 0xdb, 0xc2, 0x2a, 0xed, 0x58, 0xa7, 0xa5, 0x3c, 0x43, 0x57, 0x5c, 0x47, 0x2a, 0xfa, + 0x68, 0xe8, 0x41, 0x4a, 0x04, 0xf1, 0x3b, 0xf0, 0x53, 0xc3, 0x8b, 0x84, 0x58, 0xa5, 0x19, 0xc6, + 0xf3, 0xae, 0x23, 0x2d, 0xf9, 0x7c, 0xe0, 0x40, 0x4a, 0x88, 0xec, 0xcd, 0xbe, 0xbc, 0x90, 0x32, + 0x1f, 0x2f, 0xa4, 0x0c, 0xaa, 0xc3, 0xfa, 0x90, 0x08, 0x0a, 0xa6, 0x6d, 0xd2, 0xa2, 0x98, 0x3f, + 0x80, 0xf9, 0x50, 0xb4, 0x63, 0x43, 0x63, 0x9a, 0xe4, 0xab, 0x9b, 0x3d, 0x47, 0x82, 0x10, 0x3d, + 0xdc, 0xef, 0x47, 0x1d, 0x43, 0x91, 0x02, 0xe1, 0xdf, 0xa1, 0x86, 0xde, 0x64, 0xa1, 0x58, 0xa3, + 0xfa, 0x81, 0x66, 0xd8, 0x91, 0xce, 0xd3, 0x99, 0x3a, 0x4a, 0x57, 0x76, 0x82, 0x74, 0xe5, 0xbe, + 0x21, 0x5d, 0xf9, 0xf1, 0xd3, 0x35, 0x33, 0x4e, 0xba, 0xb6, 0xa1, 0x40, 0x0d, 0xdd, 0x9b, 0xb9, + 0xc0, 0xf0, 0x65, 0xd7, 0x91, 0x16, 0x83, 0x58, 0x99, 0x1d, 0x29, 0x01, 0x10, 0xcb, 0xd5, 0x3a, + 0xac, 0x25, 0x64, 0x0c, 0x33, 0x85, 0xce, 0xb3, 0xc0, 0x47, 0x79, 0x7c, 0x4c, 0xb1, 0x75, 0xd7, + 0x22, 0x9d, 0xf6, 0xb4, 0x54, 0xfe, 0x1f, 0x40, 0xf7, 0xe6, 0x3b, 0x8e, 0x69, 0xbd, 0xea, 0x3a, + 0xd2, 0xb2, 0x3f, 0xae, 0xef, 0x43, 0xca, 0x1c, 0xfb, 0xb9, 0xef, 0xc9, 0xfe, 0x00, 0x56, 0x34, + 0xfc, 0x54, 0xed, 0x34, 0xed, 0xe3, 0x36, 0xb6, 0x4c, 0x83, 0x52, 0x83, 0xb4, 0x28, 0x93, 0x7f, + 0xb1, 0x2a, 0xba, 0x8e, 0x24, 0x84, 0xf2, 0x0f, 0x41, 0x48, 0xe1, 0x03, 0xeb, 0xc3, 0xbe, 0x31, + 0x7e, 0xc6, 0xf3, 0xd7, 0x9e, 0x71, 0xf4, 0x3b, 0x08, 0xc3, 0x8a, 0x44, 0x82, 0xbd, 0xe6, 0x98, + 0x60, 0xfb, 0xb8, 0x89, 0xbf, 0x1b, 0xc1, 0xfa, 0x87, 0x22, 0x77, 0xcd, 0xa1, 0x08, 0x82, 0x4b, + 0xec, 0x3e, 0x0a, 0xee, 0x03, 0x07, 0xab, 0x35, 0xaa, 0xdf, 0xd2, 0x34, 0xcf, 0xf7, 0x88, 0x4c, + 0x3d, 0xbe, 0x0d, 0xc8, 0x77, 0x28, 0xb6, 0x86, 0xaf, 0x9d, 0x67, 0x45, 0x0a, 0x73, 0x26, 0x44, + 0xc8, 0x4d, 0x2c, 0x42, 0xfe, 0x3a, 0x11, 0x24, 0xf8, 0x63, 0x64, 0x94, 0x91, 0x0e, 0x9f, 0x38, + 0x26, 0x93, 0x82, 0x4d, 0xd2, 0x65, 0x32, 0xdd, 0xb1, 0x88, 0xf9, 0x83, 0x8a, 0xb1, 0x09, 0x28, + 0x3d, 0xd4, 0x48, 0x91, 0xcf, 0x1c, 0x6b, 0x7a, 0x47, 0x78, 0xe0, 0x62, 0x4d, 0x49, 0x88, 0x6d, + 0x28, 0xd8, 0xaa, 0xa5, 0x63, 0x3b, 0x90, 0x22, 0xb6, 0x5b, 0xdf, 0x8e, 0x94, 0x00, 0xf0, 0x4a, + 0xf2, 0x70, 0x4d, 0x88, 0x95, 0xe4, 0x81, 0x5a, 0x10, 0x47, 0x27, 0x91, 0xe4, 0x37, 0xd6, 0xdb, + 0x06, 0x63, 0x0d, 0x95, 0xa8, 0xbc, 0x2a, 0x40, 0xae, 0x46, 0x75, 0xfe, 0x04, 0x96, 0x12, 0x4f, + 0x80, 0xad, 0xf2, 0x88, 0x87, 0x46, 0x79, 0xa8, 0x4b, 0x0a, 0xe5, 0xf1, 0xb8, 0xa8, 0x9b, 0xd6, + 0x61, 0x61, 0xa0, 0x05, 0x6e, 0xa6, 0x8d, 0x8f, 0x53, 0xc2, 0xce, 0x38, 0x54, 0xb4, 0xc6, 0x33, + 0x28, 0x26, 0x7b, 0xc0, 0x5f, 0x5f, 0xdf, 0x66, 0x04, 0x0a, 0xf2, 0x98, 0x60, 0x7c, 0xb1, 0x64, + 0xfd, 0x4c, 0x5d, 0x2c, 0x01, 0xa6, 0x2f, 0x96, 0x52, 0xd3, 0x78, 0x1b, 0xf8, 0x11, 0xf5, 0xec, + 0x9f, 0xb4, 0x69, 0x86, 0x59, 0xa1, 0x32, 0x3e, 0x1b, 0xad, 0x7a, 0xc6, 0xc1, 0x5a, 0x5a, 0xf9, + 0x48, 0x0d, 0x21, 0x65, 0x80, 0x70, 0x63, 0xc2, 0x01, 0xd1, 0x2e, 0x4e, 0x60, 0x29, 0x71, 0x63, + 0x53, 0xcf, 0xe8, 0x20, 0x97, 0x7e, 0x46, 0x47, 0xdf, 0x8a, 0xea, 0xbd, 0xb7, 0x3d, 0x91, 0xbb, + 0xec, 0x89, 0xdc, 0xfb, 0x9e, 0xc8, 0x9d, 0x5f, 0x89, 0x99, 0xcb, 0x2b, 0x31, 0xf3, 0xee, 0x4a, + 0xcc, 0x3c, 0xa9, 0xe8, 0x86, 0x7d, 0xd2, 0xa9, 0x97, 0x1b, 0xc4, 0x94, 0xfd, 0x39, 0xff, 0x6d, + 0xaa, 0x75, 0x1a, 0x7c, 0xcb, 0xdd, 0x8a, 0xfc, 0x22, 0xf6, 0xdc, 0xb6, 0x4f, 0xdb, 0x98, 0xd6, + 0x0b, 0xec, 0xa5, 0xfd, 0xdf, 0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0x70, 0x2c, 0x71, 0x68, 0xda, + 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1250,12 +1250,10 @@ func (m *MsgEditSubspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - if len(m.ID) > 0 { - i -= len(m.ID) - copy(dAtA[i:], m.ID) - i = encodeVarintMsgs(dAtA, i, uint64(len(m.ID))) + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x8 } return len(dAtA) - i, nil } @@ -1690,9 +1688,8 @@ func (m *MsgEditSubspace) Size() (n int) { } var l int _ = l - l = len(m.ID) - if l > 0 { - n += 1 + l + sovMsgs(uint64(l)) + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) } l = len(m.Name) if l > 0 { @@ -2200,10 +2197,10 @@ func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) } - var stringLen uint64 + m.SubspaceID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgs @@ -2213,24 +2210,11 @@ func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.SubspaceID |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgs - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgs - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.ID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) diff --git a/x/subspaces/types/msgs_test.go b/x/subspaces/types/msgs_test.go index 94c39b0046..36f6981a0e 100644 --- a/x/subspaces/types/msgs_test.go +++ b/x/subspaces/types/msgs_test.go @@ -1,810 +1,811 @@ package types_test -import ( - "testing" - - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/stretchr/testify/require" -) - -func TestMsgCreateSubspace_Route(t *testing.T) { - msg := types2.NewMsgCreateSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "mooncake", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ) - require.Equal(t, "subspaces", msg.Route()) -} - -func TestMsgCreateSubspace_Type(t *testing.T) { - msg := types2.NewMsgCreateSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "mooncake", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ) - require.Equal(t, "create_subspace", msg.Type()) -} - -func TestMsgCreateSubspace_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg *types2.MsgCreateSubspace - expErr bool - }{ - { - name: "invalid subspace id returns error", - msg: types2.NewMsgCreateSubspace( - "", - "mooncake", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ), - expErr: true, - }, - { - name: "invalid subspace creator address returns error", - msg: types2.NewMsgCreateSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "mooncake", - "", - types2.SubspaceTypeOpen, - ), - expErr: true, - }, - { - name: "invalid subspace name returns error", - msg: types2.NewMsgCreateSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ), - expErr: true, - }, - { - name: "valid message returns no error", - msg: types2.NewMsgCreateSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "mooncake", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ), - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := test.msg.ValidateBasic() - if test.expErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestMsgCreateSubspace_GetSignBytes(t *testing.T) { - msg := types2.NewMsgCreateSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "mooncake", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ) - expected := `{"creator":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","name":"mooncake","subspace_type":1}` - require.Equal(t, expected, string(msg.GetSignBytes())) -} - -func TestMsgCreateSubspace_GetSigners(t *testing.T) { - msg := types2.NewMsgCreateSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "mooncake", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ) - addr, _ := sdk.AccAddressFromBech32(msg.Creator) - require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -} - -func TestMsgEditSubspace_Route(t *testing.T) { - msg := types2.NewMsgEditSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "star", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ) - require.Equal(t, "subspaces", msg.Route()) -} - -func TestMsgEditSubspace_Type(t *testing.T) { - msg := types2.NewMsgEditSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "star", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ) - require.Equal(t, "edit_subspace", msg.Type()) -} - -func TestMsgEditSubspace_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg *types2.MsgEditSubspace - expErr bool - }{ - { - name: "invalid subspace id returns error", - msg: types2.NewMsgEditSubspace( - "", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "star", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ), - expErr: true, - }, - { - name: "invalid subspace owner address returns error", - msg: types2.NewMsgEditSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "star", - "", - types2.SubspaceTypeOpen, - ), - expErr: true, - }, - { - name: "equal subspace owner and new owner addresses returns error", - msg: types2.NewMsgEditSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "star", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ), - expErr: true, - }, - { - name: "valid message returns no error", - msg: types2.NewMsgEditSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "star", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ), - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := test.msg.ValidateBasic() - if test.expErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestMsgEditSubspace_GetSignBytes(t *testing.T) { - msg := types2.NewMsgEditSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "star", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ) - expected := `{"editor":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","name":"star","owner":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","subspace_type":1}` - require.Equal(t, expected, string(msg.GetSignBytes())) -} - -func TestMsgEditSubspace_GetSigners(t *testing.T) { - msg := types2.NewMsgEditSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "star", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ) - addr, _ := sdk.AccAddressFromBech32(msg.Editor) - require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -} - -func TestMsgAddAdmin_Route(t *testing.T) { - msg := types2.NewMsgAddAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "subspaces", msg.Route()) -} - -func TestMsgAddAdmin_Type(t *testing.T) { - msg := types2.NewMsgAddAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "add_admin", msg.Type()) -} - -func TestMsgAddAdmin_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg *types2.MsgAddAdmin - expErr bool - }{ - { - name: "invalid subspace id returns error", - msg: types2.NewMsgAddAdmin( - "", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "equals owner and admin addresses returns error", - msg: types2.NewMsgAddAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - ), - expErr: true, - }, - { - name: "invalid subspace owner address returns error", - msg: types2.NewMsgAddAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "", - ), - expErr: true, - }, - { - name: "invalid subspace new admin address returns error", - msg: types2.NewMsgAddAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "valid message returns no error", - msg: types2.NewMsgAddAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := test.msg.ValidateBasic() - if test.expErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestMsgAddAdmin_GetSignBytes(t *testing.T) { - msg := types2.NewMsgAddAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - expected := `{"admin":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","owner":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af"}` - require.Equal(t, expected, string(msg.GetSignBytes())) -} - -func TestMsgAddAdmin_GetSigners(t *testing.T) { - msg := types2.NewMsgAddAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - addr, _ := sdk.AccAddressFromBech32(msg.Owner) - require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -} - -func TestMsgRemoveAdmin_Route(t *testing.T) { - msg := types2.NewMsgRemoveAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "subspaces", msg.Route()) -} - -func TestMsgRemoveAdmin_Type(t *testing.T) { - msg := types2.NewMsgRemoveAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "remove_admin", msg.Type()) -} - -func TestMsgRemoveAdmin_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg *types2.MsgRemoveAdmin - expErr bool - }{ - { - name: "invalid subspace id returns error", - msg: types2.NewMsgRemoveAdmin( - "", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "equals owner and admin addresses returns error", - msg: types2.NewMsgRemoveAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - ), - expErr: true, - }, - { - name: "invalid subspace owner address returns error", - msg: types2.NewMsgRemoveAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "", - ), - expErr: true, - }, - { - name: "invalid subspace admin address returns error", - msg: types2.NewMsgRemoveAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "valid message returns no error", - msg: types2.NewMsgRemoveAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := test.msg.ValidateBasic() - if test.expErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestMsgRemoveAdmin_GetSignBytes(t *testing.T) { - msg := types2.NewMsgRemoveAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - expected := `{"admin":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","owner":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af"}` - require.Equal(t, expected, string(msg.GetSignBytes())) -} - -func TestMsgRemoveAdmin_GetSigners(t *testing.T) { - msg := types2.NewMsgRemoveAdmin( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - addr, _ := sdk.AccAddressFromBech32(msg.Owner) - require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -} - -func TestMsgRegisterUser_Route(t *testing.T) { - msg := types2.NewMsgRegisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "subspaces", msg.Route()) -} - -func TestMsgRegisterUser_Type(t *testing.T) { - msg := types2.NewMsgRegisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "register_user", msg.Type()) -} - -func TestMsgRegisterUser_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg *types2.MsgRegisterUser - expErr bool - }{ - { - name: "invalid subspace id returns error", - msg: types2.NewMsgRegisterUser( - "", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "invalid subspace admin address returns error", - msg: types2.NewMsgRegisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "", - ), - expErr: true, - }, - { - name: "invalid subspace user address returns error", - msg: types2.NewMsgRegisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "valid message returns no error", - msg: types2.NewMsgRegisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := test.msg.ValidateBasic() - if test.expErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestMsgRegisterUser_GetSignBytes(t *testing.T) { - msg := types2.NewMsgRegisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` - require.Equal(t, expected, string(msg.GetSignBytes())) -} - -func TestMsgRegisterUser_GetSigners(t *testing.T) { - msg := types2.NewMsgRegisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - addr, _ := sdk.AccAddressFromBech32(msg.Admin) - require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -} - -func TestMsgUnregisterUser_Route(t *testing.T) { - msg := types2.NewMsgUnregisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "subspaces", msg.Route()) -} - -func TestMsgUnregisterUser_Type(t *testing.T) { - msg := types2.NewMsgUnregisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "unregister_user", msg.Type()) -} - -func TestMsgUnregisterUser_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg *types2.MsgUnregisterUser - expErr bool - }{ - { - name: "invalid subspace id returns error", - msg: types2.NewMsgUnregisterUser( - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "invalid subspace admin address returns error", - msg: types2.NewMsgUnregisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "", - ), - expErr: true, - }, - { - name: "invalid subspace user address returns error", - msg: types2.NewMsgUnregisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "valid message returns no error", - msg: types2.NewMsgUnregisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := test.msg.ValidateBasic() - if test.expErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestMsgUnregisterUser_GetSignBytes(t *testing.T) { - msg := types2.NewMsgUnregisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` - require.Equal(t, expected, string(msg.GetSignBytes())) -} - -func TestMsgUnregisterUser_GetSigners(t *testing.T) { - msg := types2.NewMsgUnregisterUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - addr, _ := sdk.AccAddressFromBech32(msg.Admin) - require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -} - -func TestMsgBanUser_Route(t *testing.T) { - msg := types2.NewMsgBanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "subspaces", msg.Route()) -} - -func TestMsgBanUser_Type(t *testing.T) { - msg := types2.NewMsgBanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "block_user", msg.Type()) -} - -func TestMsgBanUser_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg *types2.MsgBanUser - expErr bool - }{ - { - name: "invalid subspace id returns error", - msg: types2.NewMsgBanUser( - "", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "invalid subspace admin address returns error", - msg: types2.NewMsgBanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "", - ), - expErr: true, - }, - { - name: "invalid subspace user address returns error", - msg: types2.NewMsgBanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "valid message returns no error", - msg: types2.NewMsgBanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := test.msg.ValidateBasic() - if test.expErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestMsgBanUser_GetSignBytes(t *testing.T) { - msg := types2.NewMsgBanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` - require.Equal(t, expected, string(msg.GetSignBytes())) -} - -func TestMsgBanUser_GetSigners(t *testing.T) { - msg := types2.NewMsgBanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - addr, _ := sdk.AccAddressFromBech32(msg.Admin) - require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -} - -func TestTestMsgUnbanUser_Route(t *testing.T) { - msg := types2.NewMsgUnbanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "subspaces", msg.Route()) -} - -func TestTestMsgUnbanUser_Type(t *testing.T) { - msg := types2.NewMsgUnbanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - require.Equal(t, "unblock_user", msg.Type()) -} - -func TestTestMsgUnbanUser_ValidateBasic(t *testing.T) { - tests := []struct { - name string - msg *types2.MsgUnbanUser - expErr bool - }{ - { - name: "invalid subspace id returns error", - msg: types2.NewMsgUnbanUser( - "", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "invalid subspace admin address returns error", - msg: types2.NewMsgUnbanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "", - ), - expErr: true, - }, - { - name: "invalid subspace user address returns error", - msg: types2.NewMsgUnbanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "valid message returns no error", - msg: types2.NewMsgUnbanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := test.msg.ValidateBasic() - if test.expErr { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func TestTestMsgUnbanUser_GetSignBytes(t *testing.T) { - msg := types2.NewMsgUnbanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` - require.Equal(t, expected, string(msg.GetSignBytes())) -} - -func TestTestMsgUnbanUser_GetSigners(t *testing.T) { - msg := types2.NewMsgUnbanUser( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ) - addr, _ := sdk.AccAddressFromBech32(msg.Admin) - require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -} +// +//import ( +// "testing" +// +// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" +// +// sdk "github.com/cosmos/cosmos-sdk/types" +// "github.com/stretchr/testify/require" +//) +// +//func TestMsgCreateSubspace_Route(t *testing.T) { +// msg := types2.NewMsgCreateSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "mooncake", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ) +// require.Equal(t, "subspaces", msg.Route()) +//} +// +//func TestMsgCreateSubspace_Type(t *testing.T) { +// msg := types2.NewMsgCreateSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "mooncake", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ) +// require.Equal(t, "create_subspace", msg.Type()) +//} +// +//func TestMsgCreateSubspace_ValidateBasic(t *testing.T) { +// tests := []struct { +// name string +// msg *types2.MsgCreateSubspace +// expErr bool +// }{ +// { +// name: "invalid subspace id returns error", +// msg: types2.NewMsgCreateSubspace( +// "", +// "mooncake", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace creator address returns error", +// msg: types2.NewMsgCreateSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "mooncake", +// "", +// types2.SubspaceTypeOpen, +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace name returns error", +// msg: types2.NewMsgCreateSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ), +// expErr: true, +// }, +// { +// name: "valid message returns no error", +// msg: types2.NewMsgCreateSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "mooncake", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ), +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err := test.msg.ValidateBasic() +// if test.expErr { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} +// +//func TestMsgCreateSubspace_GetSignBytes(t *testing.T) { +// msg := types2.NewMsgCreateSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "mooncake", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ) +// expected := `{"creator":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","name":"mooncake","subspace_type":1}` +// require.Equal(t, expected, string(msg.GetSignBytes())) +//} +// +//func TestMsgCreateSubspace_GetSigners(t *testing.T) { +// msg := types2.NewMsgCreateSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "mooncake", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ) +// addr, _ := sdk.AccAddressFromBech32(msg.Creator) +// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +//} +// +//func TestMsgEditSubspace_Route(t *testing.T) { +// msg := types2.NewMsgEditSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "star", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ) +// require.Equal(t, "subspaces", msg.Route()) +//} +// +//func TestMsgEditSubspace_Type(t *testing.T) { +// msg := types2.NewMsgEditSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "star", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ) +// require.Equal(t, "edit_subspace", msg.Type()) +//} +// +//func TestMsgEditSubspace_ValidateBasic(t *testing.T) { +// tests := []struct { +// name string +// msg *types2.MsgEditSubspace +// expErr bool +// }{ +// { +// name: "invalid subspace id returns error", +// msg: types2.NewMsgEditSubspace( +// "", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "star", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace owner address returns error", +// msg: types2.NewMsgEditSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "star", +// "", +// types2.SubspaceTypeOpen, +// ), +// expErr: true, +// }, +// { +// name: "equal subspace owner and new owner addresses returns error", +// msg: types2.NewMsgEditSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "star", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ), +// expErr: true, +// }, +// { +// name: "valid message returns no error", +// msg: types2.NewMsgEditSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "star", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ), +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err := test.msg.ValidateBasic() +// if test.expErr { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} +// +//func TestMsgEditSubspace_GetSignBytes(t *testing.T) { +// msg := types2.NewMsgEditSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "star", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ) +// expected := `{"editor":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","name":"star","owner":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","subspace_type":1}` +// require.Equal(t, expected, string(msg.GetSignBytes())) +//} +// +//func TestMsgEditSubspace_GetSigners(t *testing.T) { +// msg := types2.NewMsgEditSubspace( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "star", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// ) +// addr, _ := sdk.AccAddressFromBech32(msg.Editor) +// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +//} +// +//func TestMsgAddAdmin_Route(t *testing.T) { +// msg := types2.NewMsgAddAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "subspaces", msg.Route()) +//} +// +//func TestMsgAddAdmin_Type(t *testing.T) { +// msg := types2.NewMsgAddAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "add_admin", msg.Type()) +//} +// +//func TestMsgAddAdmin_ValidateBasic(t *testing.T) { +// tests := []struct { +// name string +// msg *types2.MsgAddAdmin +// expErr bool +// }{ +// { +// name: "invalid subspace id returns error", +// msg: types2.NewMsgAddAdmin( +// "", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "equals owner and admin addresses returns error", +// msg: types2.NewMsgAddAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace owner address returns error", +// msg: types2.NewMsgAddAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace new admin address returns error", +// msg: types2.NewMsgAddAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "valid message returns no error", +// msg: types2.NewMsgAddAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: false, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err := test.msg.ValidateBasic() +// if test.expErr { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} +// +//func TestMsgAddAdmin_GetSignBytes(t *testing.T) { +// msg := types2.NewMsgAddAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// expected := `{"admin":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","owner":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af"}` +// require.Equal(t, expected, string(msg.GetSignBytes())) +//} +// +//func TestMsgAddAdmin_GetSigners(t *testing.T) { +// msg := types2.NewMsgAddAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// addr, _ := sdk.AccAddressFromBech32(msg.Owner) +// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +//} +// +//func TestMsgRemoveAdmin_Route(t *testing.T) { +// msg := types2.NewMsgRemoveAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "subspaces", msg.Route()) +//} +// +//func TestMsgRemoveAdmin_Type(t *testing.T) { +// msg := types2.NewMsgRemoveAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "remove_admin", msg.Type()) +//} +// +//func TestMsgRemoveAdmin_ValidateBasic(t *testing.T) { +// tests := []struct { +// name string +// msg *types2.MsgRemoveAdmin +// expErr bool +// }{ +// { +// name: "invalid subspace id returns error", +// msg: types2.NewMsgRemoveAdmin( +// "", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "equals owner and admin addresses returns error", +// msg: types2.NewMsgRemoveAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace owner address returns error", +// msg: types2.NewMsgRemoveAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace admin address returns error", +// msg: types2.NewMsgRemoveAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "valid message returns no error", +// msg: types2.NewMsgRemoveAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: false, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err := test.msg.ValidateBasic() +// if test.expErr { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} +// +//func TestMsgRemoveAdmin_GetSignBytes(t *testing.T) { +// msg := types2.NewMsgRemoveAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// expected := `{"admin":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","owner":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af"}` +// require.Equal(t, expected, string(msg.GetSignBytes())) +//} +// +//func TestMsgRemoveAdmin_GetSigners(t *testing.T) { +// msg := types2.NewMsgRemoveAdmin( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// addr, _ := sdk.AccAddressFromBech32(msg.Owner) +// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +//} +// +//func TestMsgRegisterUser_Route(t *testing.T) { +// msg := types2.NewMsgRegisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "subspaces", msg.Route()) +//} +// +//func TestMsgRegisterUser_Type(t *testing.T) { +// msg := types2.NewMsgRegisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "register_user", msg.Type()) +//} +// +//func TestMsgRegisterUser_ValidateBasic(t *testing.T) { +// tests := []struct { +// name string +// msg *types2.MsgRegisterUser +// expErr bool +// }{ +// { +// name: "invalid subspace id returns error", +// msg: types2.NewMsgRegisterUser( +// "", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace admin address returns error", +// msg: types2.NewMsgRegisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace user address returns error", +// msg: types2.NewMsgRegisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "valid message returns no error", +// msg: types2.NewMsgRegisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: false, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err := test.msg.ValidateBasic() +// if test.expErr { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} +// +//func TestMsgRegisterUser_GetSignBytes(t *testing.T) { +// msg := types2.NewMsgRegisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` +// require.Equal(t, expected, string(msg.GetSignBytes())) +//} +// +//func TestMsgRegisterUser_GetSigners(t *testing.T) { +// msg := types2.NewMsgRegisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// addr, _ := sdk.AccAddressFromBech32(msg.Admin) +// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +//} +// +//func TestMsgUnregisterUser_Route(t *testing.T) { +// msg := types2.NewMsgUnregisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "subspaces", msg.Route()) +//} +// +//func TestMsgUnregisterUser_Type(t *testing.T) { +// msg := types2.NewMsgUnregisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "unregister_user", msg.Type()) +//} +// +//func TestMsgUnregisterUser_ValidateBasic(t *testing.T) { +// tests := []struct { +// name string +// msg *types2.MsgUnregisterUser +// expErr bool +// }{ +// { +// name: "invalid subspace id returns error", +// msg: types2.NewMsgUnregisterUser( +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace admin address returns error", +// msg: types2.NewMsgUnregisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace user address returns error", +// msg: types2.NewMsgUnregisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "valid message returns no error", +// msg: types2.NewMsgUnregisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: false, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err := test.msg.ValidateBasic() +// if test.expErr { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} +// +//func TestMsgUnregisterUser_GetSignBytes(t *testing.T) { +// msg := types2.NewMsgUnregisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` +// require.Equal(t, expected, string(msg.GetSignBytes())) +//} +// +//func TestMsgUnregisterUser_GetSigners(t *testing.T) { +// msg := types2.NewMsgUnregisterUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// addr, _ := sdk.AccAddressFromBech32(msg.Admin) +// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +//} +// +//func TestMsgBanUser_Route(t *testing.T) { +// msg := types2.NewMsgBanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "subspaces", msg.Route()) +//} +// +//func TestMsgBanUser_Type(t *testing.T) { +// msg := types2.NewMsgBanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "block_user", msg.Type()) +//} +// +//func TestMsgBanUser_ValidateBasic(t *testing.T) { +// tests := []struct { +// name string +// msg *types2.MsgBanUser +// expErr bool +// }{ +// { +// name: "invalid subspace id returns error", +// msg: types2.NewMsgBanUser( +// "", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace admin address returns error", +// msg: types2.NewMsgBanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace user address returns error", +// msg: types2.NewMsgBanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "valid message returns no error", +// msg: types2.NewMsgBanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: false, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err := test.msg.ValidateBasic() +// if test.expErr { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} +// +//func TestMsgBanUser_GetSignBytes(t *testing.T) { +// msg := types2.NewMsgBanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` +// require.Equal(t, expected, string(msg.GetSignBytes())) +//} +// +//func TestMsgBanUser_GetSigners(t *testing.T) { +// msg := types2.NewMsgBanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// addr, _ := sdk.AccAddressFromBech32(msg.Admin) +// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +//} +// +//func TestTestMsgUnbanUser_Route(t *testing.T) { +// msg := types2.NewMsgUnbanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "subspaces", msg.Route()) +//} +// +//func TestTestMsgUnbanUser_Type(t *testing.T) { +// msg := types2.NewMsgUnbanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// require.Equal(t, "unblock_user", msg.Type()) +//} +// +//func TestTestMsgUnbanUser_ValidateBasic(t *testing.T) { +// tests := []struct { +// name string +// msg *types2.MsgUnbanUser +// expErr bool +// }{ +// { +// name: "invalid subspace id returns error", +// msg: types2.NewMsgUnbanUser( +// "", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace admin address returns error", +// msg: types2.NewMsgUnbanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "", +// ), +// expErr: true, +// }, +// { +// name: "invalid subspace user address returns error", +// msg: types2.NewMsgUnbanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: true, +// }, +// { +// name: "valid message returns no error", +// msg: types2.NewMsgUnbanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ), +// expErr: false, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err := test.msg.ValidateBasic() +// if test.expErr { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} +// +//func TestTestMsgUnbanUser_GetSignBytes(t *testing.T) { +// msg := types2.NewMsgUnbanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` +// require.Equal(t, expected, string(msg.GetSignBytes())) +//} +// +//func TestTestMsgUnbanUser_GetSigners(t *testing.T) { +// msg := types2.NewMsgUnbanUser( +// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", +// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// ) +// addr, _ := sdk.AccAddressFromBech32(msg.Admin) +// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) +//} diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go new file mode 100644 index 0000000000..629a20dca3 --- /dev/null +++ b/x/subspaces/types/permissions.go @@ -0,0 +1,50 @@ +package types + +import "encoding/binary" + +// Permission represents a permission that can be set to a user or user group +type Permission = uint32 + +const ( + // PermissionNothing represents hte permission to do nothing + PermissionNothing = Permission(0b000000) + + // PermissionWrite identifies users that can create content inside the subspace + PermissionWrite = Permission(0b000001) + + // PermissionModerateContent allows users to moderate contents of other users (e.g. deleting it) + PermissionModerateContent = Permission(0b000010) + + // PermissionAddLink allows to add a link for this subspace + PermissionAddLink = Permission(0b000100) + + // PermissionChangeInfo allows to change the information of the subspace + PermissionChangeInfo = Permission(0b001000) + + // PermissionSetPermissions allows to set other users' permissions (except PermissionSetPermissions). + // This includes managing user groups and the associated permissions + PermissionSetPermissions = Permission(0b010000) + + // PermissionEverything allows to do everything. + // This should usually be reserved only to the owner (which has it by default) + PermissionEverything = Permission(0b111111) +) + +// MarshalPermission marshals the given permission to a byte array +func MarshalPermission(permission Permission) (permissionBytes []byte) { + permissionBytes = make([]byte, 4) + binary.BigEndian.PutUint32(permissionBytes, permission) + return +} + +// UnmarshalPermission reads the given byte array as a Permission object +func UnmarshalPermission(bz []byte) (permission Permission) { + if len(bz) < 4 { + return PermissionNothing + } + return binary.BigEndian.Uint32(bz) +} + +func CombinePermissions(permissions ...Permission) Permission { + // TODO +} diff --git a/x/subspaces/types/permissions_test.go b/x/subspaces/types/permissions_test.go new file mode 100644 index 0000000000..11db1e1305 --- /dev/null +++ b/x/subspaces/types/permissions_test.go @@ -0,0 +1,78 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +func TestMarshalPermission(t *testing.T) { + testCases := []struct { + name string + permission types.Permission + expected []byte + }{ + { + name: "zero permission", + permission: types.PermissionNothing, + expected: []byte{0, 0, 0, 0}, + }, + { + name: "non-zero permission", + permission: types.PermissionAddLink, + expected: []byte{0, 0, 0, 4}, + }, + { + name: "high permission", + permission: types.PermissionSetPermissions, + expected: []byte{0, 0, 0, 16}, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + bz := types.MarshalPermission(tc.permission) + require.Equal(t, tc.expected, bz) + }) + } +} + +func TestUnmarshalPermission(t *testing.T) { + testCases := []struct { + name string + bz []byte + expected types.Permission + }{ + { + name: "empty byte array", + bz: []byte{}, + expected: types.PermissionNothing, + }, + { + name: "nil bytes array", + bz: nil, + expected: types.PermissionNothing, + }, + { + name: "zero permission", + bz: []byte{0, 0, 0, 0}, + expected: types.PermissionNothing, + }, + { + name: "non-zero permission", + bz: []byte{0, 0, 0, 8}, + expected: types.PermissionChangeInfo, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + permission := types.UnmarshalPermission(tc.bz) + require.Equal(t, tc.expected, permission) + }) + } +} diff --git a/x/subspaces/types/query.go b/x/subspaces/types/query.go index a8567a036d..cef6250862 100644 --- a/x/subspaces/types/query.go +++ b/x/subspaces/types/query.go @@ -5,7 +5,7 @@ import ( ) // NewQuerySubspaceRequest returns a new QuerySubspaceRequest instance -func NewQuerySubspaceRequest(subspaceID string) *QuerySubspaceRequest { +func NewQuerySubspaceRequest(subspaceID uint64) *QuerySubspaceRequest { return &QuerySubspaceRequest{SubspaceId: subspaceID} } @@ -15,27 +15,3 @@ func NewQuerySubspacesRequest(pagination *query.PageRequest) *QuerySubspacesRequ Pagination: pagination, } } - -// NewQueryAdminsRequest returns a new QuerySubspaceAdminsRequest instance -func NewQueryAdminsRequest(subspaceID string, pagination *query.PageRequest) *QueryAdminsRequest { - return &QueryAdminsRequest{ - SubspaceId: subspaceID, - Pagination: pagination, - } -} - -// NewQueryRegisteredUsersRequest returns a new QuerySubspaceRegisteredUsersRequest instance -func NewQueryRegisteredUsersRequest(subspaceID string, pagination *query.PageRequest) *QueryRegisteredUsersRequest { - return &QueryRegisteredUsersRequest{ - SubspaceId: subspaceID, - Pagination: pagination, - } -} - -// NewQueryBannedUsersRequest returns a new QuerySubspaceBannedUsersRequest instance -func NewQueryBannedUsersRequest(subspaceID string, pagination *query.PageRequest) *QueryBannedUsersRequest { - return &QueryBannedUsersRequest{ - SubspaceId: subspaceID, - Pagination: pagination, - } -} diff --git a/x/subspaces/types/subspace.go b/x/subspaces/types/subspace.go index 2261d8f555..ed99dbd358 100644 --- a/x/subspaces/types/subspace.go +++ b/x/subspaces/types/subspace.go @@ -4,96 +4,105 @@ import ( "fmt" "strings" "time" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // NewSubspace is a constructor for the Subspace type -func NewSubspace(subspaceID, name, owner, creator string, subspaceType SubspaceType, creationTime time.Time) Subspace { +func NewSubspace(subspaceID uint64, name, description, owner, creator, treasury string, creationTime time.Time) Subspace { return Subspace{ ID: subspaceID, Name: name, + Description: description, Owner: owner, Creator: creator, + Treasury: treasury, CreationTime: creationTime, - Type: subspaceType, - } -} - -// WithName is a decorator that will replace the subspace name with a new one -func (sub Subspace) WithName(name string) Subspace { - if strings.TrimSpace(name) != "" { - sub.Name = name } - return sub -} - -// WithOwner is a decorator that will replace the subspace owner with a new one -func (sub Subspace) WithOwner(owner string) Subspace { - if strings.TrimSpace(owner) != "" { - sub.Owner = owner - } - return sub -} - -// WithSubspaceType is a decorator that will replace the subspace type with a new one -func (sub Subspace) WithSubspaceType(subspaceType SubspaceType) Subspace { - sub.Type = subspaceType - return sub } // Validate will perform some checks to ensure the subspace validity func (sub Subspace) Validate() error { - if !IsValidSubspace(sub.ID) { - return fmt.Errorf("invalid subspace id: %s it must be a valid SHA-256 hash", sub.ID) + if sub.ID == 0 { + return fmt.Errorf("invalid subspace id: %d", sub.ID) } if strings.TrimSpace(sub.Name) == "" { return fmt.Errorf("subspace name cannot be empty or blank") } - if sub.Owner == "" { - return fmt.Errorf("invalid subspace owner: %s", sub.Owner) + _, err := sdk.AccAddressFromBech32(sub.Owner) + if err != nil { + return fmt.Errorf("invalid owner address: %s", sub.Owner) } - if sub.Creator == "" { - return fmt.Errorf("invalid subspace creator: %s", sub.Creator) + _, err = sdk.AccAddressFromBech32(sub.Creator) + if err != nil { + return fmt.Errorf("invalid creator address: %s", sub.Creator) } - if sub.CreationTime.IsZero() { - return fmt.Errorf("invalid subspace creation time: %s", sub.CreationTime) + if sub.Treasury != "" { + _, err = sdk.AccAddressFromBech32(sub.Treasury) + if err != nil { + return fmt.Errorf("invalid treasury address: %s", sub.Treasury) + } } - if !IsValidSubspaceType(sub.Type) { - return fmt.Errorf("invalid subspace type: %s", sub.Type) + if sub.CreationTime.IsZero() { + return fmt.Errorf("invalid subspace creation time: %s", sub.CreationTime) } return nil } -// SubspaceTypeFromString convert a string in the corresponding SubspaceType -func SubspaceTypeFromString(subType string) (SubspaceType, error) { - subspaceType, ok := SubspaceType_value[subType] - if !ok { - return SubspaceTypeUnspecified, fmt.Errorf("'%s' is not a valid subspace type", subType) - } - return SubspaceType(subspaceType), nil +// -------------------------------------------------------------------------------------------------------------------- + +// SubspaceUpdate contains all the data that can be updated about a subspace. +// When performing an update, if a field should not be edited then it must be set to types.DoNotModify +type SubspaceUpdate struct { + Name string + Description string + Owner string + Treasury string } -// NormalizeSubspaceType - normalize user specified subspace type -func NormalizeSubspaceType(subType string) string { - switch strings.ToLower(subType) { - case "open": - return SubspaceTypeOpen.String() - case "close": - return SubspaceTypeClosed.String() - default: - return subType +// NewSubspaceUpdate builds a new SubspaceUpdate instance containing the given data +func NewSubspaceUpdate(name, description, owner, treasury string) *SubspaceUpdate { + return &SubspaceUpdate{ + Name: name, + Description: description, + Owner: owner, + Treasury: treasury, } } -// IsValidSubspaceType checks if the subspaceType given correspond to one of the valid ones -func IsValidSubspaceType(subspaceType SubspaceType) bool { - if subspaceType == SubspaceTypeOpen || subspaceType == SubspaceTypeClosed { - return true +// Update updates the fields of a given subspace without validating it. +// Before storing the updated subspace, a validation with Validate() should +// be performed. +func (sub Subspace) Update(update *SubspaceUpdate) Subspace { + if update.Name == DoNotModify { + update.Name = sub.Name + } + + if update.Description == DoNotModify { + update.Description = sub.Description } - return false + + if update.Owner == DoNotModify { + update.Owner = sub.Owner + } + + if update.Treasury == DoNotModify { + update.Treasury = sub.Treasury + } + + return NewSubspace( + sub.ID, + update.Name, + update.Description, + update.Owner, + sub.Creator, + update.Treasury, + sub.CreationTime, + ) } diff --git a/x/subspaces/types/subspace_test.go b/x/subspaces/types/subspace_test.go index c592fa4b39..a9cfcf1eb8 100644 --- a/x/subspaces/types/subspace_test.go +++ b/x/subspaces/types/subspace_test.go @@ -1,236 +1,237 @@ package types_test -import ( - "fmt" - "testing" - "time" - - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - "github.com/stretchr/testify/require" -) - -func TestSubspace_WithName(t *testing.T) { - sub := types2.NewSubspace( - "123", - "name", - "", - "", - types2.SubspaceTypeOpen, - time.Unix(1, 2), - ).WithName("sub") - require.Equal(t, "sub", sub.Name) -} - -func TestSubspace_WithOwner(t *testing.T) { - sub := types2.NewSubspace( - "123", - "name", - "", - "", - types2.SubspaceTypeOpen, - time.Unix(1, 2), - ).WithOwner("owner") - require.Equal(t, "owner", sub.Owner) -} - -func TestSubspace_WithSubspaceType(t *testing.T) { - sub := types2.NewSubspace( - "123", - "name", - "", - "", - types2.SubspaceTypeOpen, - time.Unix(1, 2), - ).WithSubspaceType(types2.SubspaceTypeClosed) - require.Equal(t, types2.SubspaceTypeClosed, sub.Type) -} - -func TestSubspace_Validate(t *testing.T) { - date := time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC) - tests := []struct { - name string - subspace types2.Subspace - expError bool - }{ - { - name: "Invalid ID returns error", - subspace: types2.NewSubspace( - "123", - "", - "", - "", - types2.SubspaceTypeOpen, - time.Time{}, - ), - expError: true, - }, - { - name: "Invalid name returns error", - subspace: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "", - "", - "", - types2.SubspaceTypeOpen, - time.Time{}, - ), - expError: true, - }, - { - name: "Invalid owner returns error", - subspace: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "", - "", - types2.SubspaceTypeOpen, - time.Time{}, - ), - expError: true, - }, - { - name: "Invalid creator returns error", - subspace: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "", - types2.SubspaceTypeOpen, - time.Time{}, - ), - expError: true, - }, - { - name: "Invalid creation time returns error", - subspace: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Time{}, - ), - expError: true, - }, - { - name: "Valid subspace returns no error", - subspace: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - date, - ), - expError: false, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - err := test.subspace.Validate() - if test.expError { - require.Error(t, err) - } else { - require.NoError(t, err) - } - }) - } -} - -func Test_IsValidSubspaceType(t *testing.T) { - tests := []struct { - name string - subType types2.SubspaceType - expValid bool - }{ - { - name: "valid open type returns true", - subType: types2.SubspaceTypeOpen, - expValid: true, - }, - { - name: "valid close type returns true", - subType: types2.SubspaceTypeClosed, - expValid: true, - }, - { - name: "invalid type returns false", - subType: types2.SubspaceTypeUnspecified, - expValid: false, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - require.Equal(t, test.expValid, types2.IsValidSubspaceType(test.subType)) - }) - } -} - -func Test_NormalizeSubspaceType(t *testing.T) { - tests := []struct { - name string - subType string - expSubType string - }{ - { - name: "Valid Open subspace Type", - subType: "open", - expSubType: types2.SubspaceTypeOpen.String(), - }, - { - name: "Valid Close subspace type", - subType: "Close", - expSubType: types2.SubspaceTypeClosed.String(), - }, - { - name: "Invalid subspace type", - subType: "Invalid", - expSubType: "Invalid", - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - - subspaceType := types2.NormalizeSubspaceType(test.subType) - require.Equal(t, test.expSubType, subspaceType) - }) - } -} - -func Test_SubspaceTypeFromString(t *testing.T) { - tests := []struct { - name string - subType string - expSubType types2.SubspaceType - expError error - }{ - { - name: "Invalid subspace type", - subType: "invalid", - expSubType: types2.SubspaceTypeUnspecified, - expError: fmt.Errorf("'invalid' is not a valid subspace type"), - }, - { - name: "Valid subspace type", - subType: types2.SubspaceTypeOpen.String(), - expSubType: types2.SubspaceTypeOpen, - expError: nil, - }, - } - - for _, test := range tests { - test := test - t.Run(test.name, func(t *testing.T) { - res, err := types2.SubspaceTypeFromString(test.subType) - require.Equal(t, test.expError, err) - require.Equal(t, test.expSubType, res) - }) - } -} +// +//import ( +// "fmt" +// "testing" +// "time" +// +// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" +// +// "github.com/stretchr/testify/require" +//) +// +//func TestSubspace_WithName(t *testing.T) { +// sub := types2.NewSubspace( +// "123", +// "name", +// "", +// "", +// types2.SubspaceTypeOpen, +// time.Unix(1, 2), +// ).WithName("sub") +// require.Equal(t, "sub", sub.Name) +//} +// +//func TestSubspace_WithOwner(t *testing.T) { +// sub := types2.NewSubspace( +// "123", +// "name", +// "", +// "", +// types2.SubspaceTypeOpen, +// time.Unix(1, 2), +// ).WithOwner("owner") +// require.Equal(t, "owner", sub.Owner) +//} +// +//func TestSubspace_WithSubspaceType(t *testing.T) { +// sub := types2.NewSubspace( +// "123", +// "name", +// "", +// "", +// types2.SubspaceTypeOpen, +// time.Unix(1, 2), +// ).WithSubspaceType(types2.SubspaceTypeClosed) +// require.Equal(t, types2.SubspaceTypeClosed, sub.Type) +//} +// +//func TestSubspace_Validate(t *testing.T) { +// date := time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC) +// tests := []struct { +// name string +// subspace types2.Subspace +// expError bool +// }{ +// { +// name: "Invalid ID returns error", +// subspace: types2.NewSubspace( +// "123", +// "", +// "", +// "", +// types2.SubspaceTypeOpen, +// time.Time{}, +// ), +// expError: true, +// }, +// { +// name: "Invalid name returns error", +// subspace: types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "", +// "", +// "", +// types2.SubspaceTypeOpen, +// time.Time{}, +// ), +// expError: true, +// }, +// { +// name: "Invalid owner returns error", +// subspace: types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "", +// "", +// types2.SubspaceTypeOpen, +// time.Time{}, +// ), +// expError: true, +// }, +// { +// name: "Invalid creator returns error", +// subspace: types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// "", +// types2.SubspaceTypeOpen, +// time.Time{}, +// ), +// expError: true, +// }, +// { +// name: "Invalid creation time returns error", +// subspace: types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// types2.SubspaceTypeOpen, +// time.Time{}, +// ), +// expError: true, +// }, +// { +// name: "Valid subspace returns no error", +// subspace: types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", +// types2.SubspaceTypeOpen, +// date, +// ), +// expError: false, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// err := test.subspace.Validate() +// if test.expError { +// require.Error(t, err) +// } else { +// require.NoError(t, err) +// } +// }) +// } +//} +// +//func Test_IsValidSubspaceType(t *testing.T) { +// tests := []struct { +// name string +// subType types2.SubspaceType +// expValid bool +// }{ +// { +// name: "valid open type returns true", +// subType: types2.SubspaceTypeOpen, +// expValid: true, +// }, +// { +// name: "valid close type returns true", +// subType: types2.SubspaceTypeClosed, +// expValid: true, +// }, +// { +// name: "invalid type returns false", +// subType: types2.SubspaceTypeUnspecified, +// expValid: false, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// require.Equal(t, test.expValid, types2.IsValidSubspaceType(test.subType)) +// }) +// } +//} +// +//func Test_NormalizeSubspaceType(t *testing.T) { +// tests := []struct { +// name string +// subType string +// expSubType string +// }{ +// { +// name: "Valid Open subspace Type", +// subType: "open", +// expSubType: types2.SubspaceTypeOpen.String(), +// }, +// { +// name: "Valid Close subspace type", +// subType: "Close", +// expSubType: types2.SubspaceTypeClosed.String(), +// }, +// { +// name: "Invalid subspace type", +// subType: "Invalid", +// expSubType: "Invalid", +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// +// subspaceType := types2.NormalizeSubspaceType(test.subType) +// require.Equal(t, test.expSubType, subspaceType) +// }) +// } +//} +// +//func Test_SubspaceTypeFromString(t *testing.T) { +// tests := []struct { +// name string +// subType string +// expSubType types2.SubspaceType +// expError error +// }{ +// { +// name: "Invalid subspace type", +// subType: "invalid", +// expSubType: types2.SubspaceTypeUnspecified, +// expError: fmt.Errorf("'invalid' is not a valid subspace type"), +// }, +// { +// name: "Valid subspace type", +// subType: types2.SubspaceTypeOpen.String(), +// expSubType: types2.SubspaceTypeOpen, +// expError: nil, +// }, +// } +// +// for _, test := range tests { +// test := test +// t.Run(test.name, func(t *testing.T) { +// res, err := types2.SubspaceTypeFromString(test.subType) +// require.Equal(t, test.expError, err) +// require.Equal(t, test.expSubType, res) +// }) +// } +//} diff --git a/x/subspaces/types/utils.go b/x/subspaces/types/utils.go deleted file mode 100644 index 7400a2b2fa..0000000000 --- a/x/subspaces/types/utils.go +++ /dev/null @@ -1,12 +0,0 @@ -package types - -import "regexp" - -var ( - subspaceRegEx = regexp.MustCompile(`^[a-fA-F0-9]{64}$`) -) - -// IsValidSubspace tells whether the given value is a valid subspace or not -func IsValidSubspace(value string) bool { - return subspaceRegEx.MatchString(value) -} From b0f4f6175cd725775ca569b32c074872c91c1613 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Tue, 18 Jan 2022 14:38:35 +0100 Subject: [PATCH 05/47] more work on the handling of messages Signed-off-by: Riccardo Montagnin --- x/subspaces/keeper/alias_functions.go | 145 +++----------------------- x/subspaces/keeper/groups.go | 5 + x/subspaces/keeper/msg_server.go | 38 +++++-- x/subspaces/keeper/permissions.go | 36 ++++--- x/subspaces/types/keys.go | 16 ++- x/subspaces/types/msgs.go | 4 +- x/subspaces/types/permissions.go | 16 ++- x/subspaces/types/permissions_test.go | 79 ++++++++++++++ 8 files changed, 182 insertions(+), 157 deletions(-) diff --git a/x/subspaces/keeper/alias_functions.go b/x/subspaces/keeper/alias_functions.go index 35a3048e34..4e8f0aca3d 100644 --- a/x/subspaces/keeper/alias_functions.go +++ b/x/subspaces/keeper/alias_functions.go @@ -1,21 +1,22 @@ package keeper import ( + "bytes" + sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) // IterateSubspaces iterates through the subspaces set and performs the given function -func (k Keeper) IterateSubspaces(ctx sdk.Context, fn func(index int64, subspace types2.Subspace) (stop bool)) { +func (k Keeper) IterateSubspaces(ctx sdk.Context, fn func(index int64, subspace types.Subspace) (stop bool)) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types2.SubspaceStorePrefix) + iterator := sdk.KVStorePrefixIterator(store, types.SubspacePrefix) defer iterator.Close() i := int64(0) for ; iterator.Valid(); iterator.Next() { - var subspace types2.Subspace + var subspace types.Subspace k.cdc.MustUnmarshal(iterator.Value(), &subspace) stop := fn(i, subspace) if stop { @@ -26,9 +27,9 @@ func (k Keeper) IterateSubspaces(ctx sdk.Context, fn func(index int64, subspace } // GetAllSubspaces returns a list of all the subspaces that have been store inside the given context -func (k Keeper) GetAllSubspaces(ctx sdk.Context) []types2.Subspace { - var subspaces []types2.Subspace - k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { +func (k Keeper) GetAllSubspaces(ctx sdk.Context) []types.Subspace { + var subspaces []types.Subspace + k.IterateSubspaces(ctx, func(_ int64, subspace types.Subspace) (stop bool) { subspaces = append(subspaces, subspace) return false }) @@ -36,137 +37,21 @@ func (k Keeper) GetAllSubspaces(ctx sdk.Context) []types2.Subspace { return subspaces } -// IterateSubspaceAdmins iterates over all the admins of the subspace having the given id -func (k Keeper) IterateSubspaceAdmins(ctx sdk.Context, id string, fn func(index int64, admin string) (stop bool)) { - store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types2.SubspaceAdminsPrefix(id)) - defer iterator.Close() - - i := int64(0) - for ; iterator.Valid(); iterator.Next() { - stop := fn(i, string(iterator.Value())) - if stop { - break - } - i++ - } -} - -// GetAllAdmins returns the entries containing the data of all the admins of all the subspaces -func (k Keeper) GetAllAdmins(ctx sdk.Context) []types2.UsersEntry { - var entries []types2.UsersEntry - k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { - - var admins []string - k.IterateSubspaceAdmins(ctx, subspace.ID, func(_ int64, admin string) (stop bool) { - admins = append(admins, admin) - return false - }) - - entries = append(entries, types2.NewUsersEntry(subspace.ID, admins)) - return false - }) - - return entries -} - -// IterateSubspaceRegisteredUsers iterates over all the registered users of the subspace having the given id -func (k Keeper) IterateSubspaceRegisteredUsers(ctx sdk.Context, id string, fn func(index int64, user string) (stop bool)) { - store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types2.SubspaceRegisteredUsersPrefix(id)) - defer iterator.Close() - - i := int64(0) - for ; iterator.Valid(); iterator.Next() { - stop := fn(i, string(iterator.Value())) - if stop { - break - } - i++ - } -} - -// GetAllRegisteredUsers returns the entries containing the data of all the registered users of all the subspaces -func (k Keeper) GetAllRegisteredUsers(ctx sdk.Context) []types2.UsersEntry { - var entries []types2.UsersEntry - k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { - - var users []string - k.IterateSubspaceRegisteredUsers(ctx, subspace.ID, func(_ int64, user string) (stop bool) { - users = append(users, user) - return false - }) +// -------------------------------------------------------------------------------------------------------------------- - entries = append(entries, types2.NewUsersEntry(subspace.ID, users)) - return false - }) - - return entries -} - -// IterateSubspaceBannedUsers iterates over all the banned users of the subspace having the given id -func (k Keeper) IterateSubspaceBannedUsers(ctx sdk.Context, id string, fn func(index int64, user string) (stop bool)) { +// IterateSubspaceGroups allows iterating over all the groups that are part of the subspace having the given id +func (k Keeper) IterateSubspaceGroups(ctx sdk.Context, subspaceID uint64, fn func(index int64, groupName string) (stop bool)) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, types2.SubspaceBannedUsersPrefix(id)) + iterator := sdk.KVStorePrefixIterator(store, types.GroupsStoreKey(subspaceID)) defer iterator.Close() i := int64(0) for ; iterator.Valid(); iterator.Next() { - stop := fn(i, string(iterator.Value())) + nameBz := bytes.TrimPrefix(iterator.Key(), types.GroupsStoreKey(subspaceID)) + stop := fn(i, types.GetGroupNameFromBytes(nameBz)) if stop { break } i++ } } - -// GetAllBannedUsers returns the entries containing the data of all the banned users of all the subspaces -func (k Keeper) GetAllBannedUsers(ctx sdk.Context) []types2.UsersEntry { - var entries []types2.UsersEntry - k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { - - var users []string - k.IterateSubspaceBannedUsers(ctx, subspace.ID, func(_ int64, user string) (stop bool) { - users = append(users, user) - return false - }) - - entries = append(entries, types2.NewUsersEntry(subspace.ID, users)) - return false - }) - - return entries -} - -// checkSubspaceAdmin checks if the subspace with the given id exists and -// if the address belongs to the owner of the subspace or one of its admins. -func (k Keeper) checkSubspaceAdmin(ctx sdk.Context, id, address string) error { - subspace, found := k.GetSubspace(ctx, id) - if !found { - return sdkerrors.Wrapf(types2.ErrInvalidSubspaceID, "the subspace with id %s doesn't exist", id) - } - - if subspace.Owner != address { - store := ctx.KVStore(k.storeKey) - if !store.Has(types2.SubspaceAdminKey(subspace.ID, address)) { - return sdkerrors.Wrapf(types2.ErrInvalidSubspaceAdmin, address) - } - } - - return nil -} - -// checkSubspaceOwner checks if the subspace with the given id exists and -// if the address belongs to the owner of the subspace. -func (k Keeper) checkSubspaceOwner(ctx sdk.Context, id, address string) error { - subspace, found := k.GetSubspace(ctx, id) - if !found { - return sdkerrors.Wrapf(types2.ErrInvalidSubspaceID, "the subspace with id %s doesn't exist", id) - } - - if subspace.Owner != address { - return sdkerrors.Wrapf(types2.ErrInvalidSubspaceOwner, address) - } - - return nil -} diff --git a/x/subspaces/keeper/groups.go b/x/subspaces/keeper/groups.go index 7ed05baed7..681a626b45 100644 --- a/x/subspaces/keeper/groups.go +++ b/x/subspaces/keeper/groups.go @@ -17,6 +17,8 @@ func (k Keeper) HasGroup(ctx sdk.Context, subspaceID uint64, groupName string) b func (k Keeper) SaveUserGroup(ctx sdk.Context, subspaceID uint64, groupName string, permissions types.Permission) { store := ctx.KVStore(k.storeKey) + k.Logger(ctx).Info("group saved", "subspace_id", subspaceID, "group_name", groupName) + store.Set(types.GroupStoreKey(subspaceID, groupName), []byte{0x01}) k.SetPermissions(ctx, subspaceID, groupName, permissions) } @@ -24,6 +26,9 @@ func (k Keeper) SaveUserGroup(ctx sdk.Context, subspaceID uint64, groupName stri // DeleteUserGroup deletes the group with the given name from the subspace with the provided id func (k Keeper) DeleteUserGroup(ctx sdk.Context, subspaceID uint64, groupName string) { store := ctx.KVStore(k.storeKey) + + k.Logger(ctx).Info("group deleted", "subspace_id", subspaceID, "group_name", groupName) + store.Delete(types.GroupStoreKey(subspaceID, groupName)) } diff --git a/x/subspaces/keeper/msg_server.go b/x/subspaces/keeper/msg_server.go index 3b51699852..084dd281f1 100644 --- a/x/subspaces/keeper/msg_server.go +++ b/x/subspaces/keeper/msg_server.go @@ -71,7 +71,11 @@ func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspac ctx := sdk.UnwrapSDKContext(goCtx) // Check the permission to edit - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionChangeInfo) { + hasPermissions, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionChangeInfo) + if err != nil { + return nil, err + } + if !hasPermissions { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot edit this subspace") } @@ -83,7 +87,7 @@ func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspac // Update the subspace and validate it updated := subspace.Update(types.NewSubspaceUpdate(msg.Name, msg.Description, msg.Owner, msg.Treasury)) - err := updated.Validate() + err = updated.Validate() if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) } @@ -113,7 +117,11 @@ func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUs ctx := sdk.UnwrapSDKContext(goCtx) // Check the permission first - if !k.HasPermission(ctx, msg.SubspaceID, msg.Creator, types.PermissionSetPermissions) { + hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Creator, types.PermissionSetPermissions) + if err != nil { + return nil, err + } + if !hasPermission { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot create user groups in this subspace") } @@ -145,7 +153,11 @@ func (k msgServer) DeleteUserGroup(goCtx context.Context, msg *types.MsgDeleteUs ctx := sdk.UnwrapSDKContext(goCtx) // Check for permissions - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) + if err != nil { + return nil, err + } + if !hasPermission { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot delete user groups in this subspace") } @@ -177,7 +189,11 @@ func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUs ctx := sdk.UnwrapSDKContext(goCtx) // Check the permissions - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) + if err != nil { + return nil, err + } + if !hasPermission { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage user group members in this subspace") } @@ -218,7 +234,11 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg ctx := sdk.UnwrapSDKContext(goCtx) // Check the permissions - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) + if err != nil { + return nil, err + } + if !hasPermission { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage user group members in this subspace") } @@ -259,7 +279,11 @@ func (k msgServer) SetPermissions(goCtx context.Context, msg *types.MsgSetPermis ctx := sdk.UnwrapSDKContext(goCtx) // Check the permissions - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) + if err != nil { + return nil, err + } + if !hasPermission { return nil, sdkerrors.Wrapf(types.ErrPermissionDenied, "you cannot set other users permissions") } diff --git a/x/subspaces/keeper/permissions.go b/x/subspaces/keeper/permissions.go index 94f67d8e91..12cd439c4e 100644 --- a/x/subspaces/keeper/permissions.go +++ b/x/subspaces/keeper/permissions.go @@ -16,30 +16,42 @@ func (k Keeper) GetPermissions(ctx sdk.Context, subspaceID uint64, target string // GetGroupsInheritedPermissions returns the permissions that the specified target // has inherited from all the groups that they are part of. -func (k Keeper) GetGroupsInheritedPermissions(ctx sdk.Context, subspaceID uint64, target string) types.Permission { - // TODO - return 0 +func (k Keeper) GetGroupsInheritedPermissions(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress) types.Permission { + var permissions []types.Permission + k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, groupName string) (stop bool) { + if k.IsMemberOfGroup(ctx, subspaceID, groupName, user) { + permissions = append(permissions, k.GetPermissions(ctx, subspaceID, groupName)) + } + return false + }) + return types.CombinePermissions(permissions...) } // HasPermission checks whether the specific target has the given permission inside a specific subspace func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, target string, permission types.Permission) (bool, error) { - store := ctx.KVStore(k.storeKey) + specificPermissions := k.GetPermissions(ctx, subspaceID, target) + + userAddr, err := sdk.AccAddressFromBech32(target) + if err != nil { + return types.CheckPermission(specificPermissions, permission), nil + } - // TODO: Check if the target is the current owner + // Get the subspace to check the ownership subspace, found := k.GetSubspace(ctx, subspaceID) if !found { return false, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d does not exist", subspaceID) } - var defaultPermission = types.PermissionNothing - - // If the target is the owner of the subspace, they should have all the permission - if subspace.Owner == target { - defaultPermission = types.PermissionEverything + // The owner of the subspaces has all the permissions by default + if subspace.Owner == userAddr.String() { + return true, nil } - // TODO: Check if the target is a user and is part of a group - return (k.GetPermissions(ctx, subspaceID, target) & permission) == permission, nil + // Get the group permissions + groupPermissions := k.GetGroupsInheritedPermissions(ctx, subspaceID, userAddr) + + // Check the combination of the permissions + return types.CheckPermission(types.CombinePermissions(specificPermissions, groupPermissions), permission), nil } // SetPermissions sets the given permission for the specific target inside a single subspace diff --git a/x/subspaces/types/keys.go b/x/subspaces/types/keys.go index 719dcdf0b7..21583cc317 100644 --- a/x/subspaces/types/keys.go +++ b/x/subspaces/types/keys.go @@ -26,7 +26,7 @@ var ( SubspacePrefix = []byte{0x00} SubspaceIDKey = []byte{0x01} ACLStorePrefix = []byte{0x02} - GroupsStorePrefix = []byte{0x03} + GroupsPrefix = []byte{0x03} GroupMembersStorePrefix = []byte{0x4} ) @@ -56,16 +56,24 @@ func PermissionStoreKey(subspaceID uint64, target string) []byte { } func GroupsStoreKey(subspaceID uint64) []byte { - return append(GroupsStorePrefix, GetSubspaceIDBytes(subspaceID)...) + return append(GroupsPrefix, GetSubspaceIDBytes(subspaceID)...) +} + +func GetGroupNameBytes(groupName string) []byte { + return []byte(groupName) +} + +func GetGroupNameFromBytes(bz []byte) string { + return string(bz) } // GroupStoreKey returns the key used to store a group for a subspace func GroupStoreKey(subspaceID uint64, groupName string) []byte { - return append(GroupsStoreKey(subspaceID), []byte(groupName)...) + return append(GroupsStoreKey(subspaceID), GetGroupNameBytes(groupName)...) } func GroupMembersStoreKey(subspaceID uint64, groupName string) []byte { - return append(append(GroupMembersStorePrefix, GetSubspaceIDBytes(subspaceID)...), []byte(groupName)...) + return append(append(GroupMembersStorePrefix, GetSubspaceIDBytes(subspaceID)...), GetGroupNameBytes(groupName)...) } func GroupMemberStoreKey(subspaceID uint64, groupName string, user string) []byte { diff --git a/x/subspaces/types/msgs.go b/x/subspaces/types/msgs.go index 426efea92d..e625a03894 100644 --- a/x/subspaces/types/msgs.go +++ b/x/subspaces/types/msgs.go @@ -69,9 +69,9 @@ func (msg MsgCreateSubspace) GetSigners() []sdk.AccAddress { // -------------------------------------------------------------------------------------------------------------------- // NewMsgEditSubspace creates a new MsgEditSubspace instance -func NewMsgEditSubspace(subspaceID, name, description, owner, treasury, signer string) *MsgEditSubspace { +func NewMsgEditSubspace(subspaceID uint64, name, description, owner, treasury, signer string) *MsgEditSubspace { return &MsgEditSubspace{ - ID: subspaceID, + SubspaceID: subspaceID, Name: name, Description: description, Owner: owner, diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go index 629a20dca3..5311d67f13 100644 --- a/x/subspaces/types/permissions.go +++ b/x/subspaces/types/permissions.go @@ -1,6 +1,8 @@ package types -import "encoding/binary" +import ( + "encoding/binary" +) // Permission represents a permission that can be set to a user or user group type Permission = uint32 @@ -45,6 +47,16 @@ func UnmarshalPermission(bz []byte) (permission Permission) { return binary.BigEndian.Uint32(bz) } +// CheckPermission checks whether the given permissions contain the specified permission +func CheckPermission(permissions Permission, permission Permission) bool { + return (permissions & permission) == permission +} + +// CombinePermissions combines all the given permissions into a single Permission object using the OR operator func CombinePermissions(permissions ...Permission) Permission { - // TODO + result := PermissionNothing + for _, permission := range permissions { + result = result | permission + } + return result } diff --git a/x/subspaces/types/permissions_test.go b/x/subspaces/types/permissions_test.go index 11db1e1305..abbb9505d9 100644 --- a/x/subspaces/types/permissions_test.go +++ b/x/subspaces/types/permissions_test.go @@ -76,3 +76,82 @@ func TestUnmarshalPermission(t *testing.T) { }) } } + +func TestCheckPermission(t *testing.T) { + testCases := []struct { + name string + permissions types.Permission + permission types.Permission + expResult bool + }{ + { + name: "same permission returns true", + permissions: types.PermissionWrite, + permission: types.PermissionWrite, + expResult: true, + }, + { + name: "different permission returns false", + permissions: types.PermissionWrite, + permission: types.PermissionSetPermissions, + expResult: false, + }, + { + name: "combined permission returns true when contains", + permissions: types.PermissionWrite | types.PermissionModerateContent | types.PermissionAddLink, + permission: types.PermissionModerateContent, + expResult: true, + }, + { + name: "combined permission returns false when does not contain", + permissions: types.PermissionWrite | types.PermissionModerateContent | types.PermissionAddLink, + permission: types.PermissionSetPermissions, + expResult: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + result := types.CheckPermission(tc.permissions, tc.permission) + require.Equal(t, tc.expResult, result) + }) + } +} + +func TestCombinePermissions(t *testing.T) { + testCases := []struct { + name string + permissions []types.Permission + expResult types.Permission + }{ + { + name: "combining the same permission returns the permission itself", + permissions: []types.Permission{types.PermissionWrite, types.PermissionWrite}, + expResult: types.PermissionWrite, + }, + { + name: "combining anything with PermissionNothing returns the permission itself", + permissions: []types.Permission{types.PermissionNothing, types.PermissionWrite}, + expResult: types.PermissionWrite, + }, + { + name: "combining anything with PermissionEverything returns PermissionEverything", + permissions: []types.Permission{types.PermissionWrite, types.PermissionEverything}, + expResult: types.PermissionEverything, + }, + { + name: "combining different permissions returns the correct result", + permissions: []types.Permission{types.PermissionWrite, types.PermissionAddLink, types.PermissionSetPermissions}, + expResult: types.PermissionWrite | types.PermissionAddLink | types.PermissionSetPermissions, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + result := types.CombinePermissions(tc.permissions...) + require.Equal(t, tc.expResult, result) + }) + } +} From fca2aa92dbad4167c68fce9f53613f3d055b5f3e Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Wed, 19 Jan 2022 12:47:10 +0100 Subject: [PATCH 06/47] added unit tests for subspaces and permissions Signed-off-by: Riccardo Montagnin --- proto/desmos/subspaces/v1/query.proto | 2 +- x/subspaces/keeper/alias_functions_test.go | 411 ---------- x/subspaces/keeper/genesis.go | 147 ++-- x/subspaces/keeper/genesis_test.go | 342 -------- x/subspaces/keeper/grpc_query.go | 107 +-- x/subspaces/keeper/grpc_query_test.go | 693 ++++++++-------- x/subspaces/keeper/invariants.go | 97 +-- x/subspaces/keeper/invariants_test.go | 125 +-- x/subspaces/keeper/keeper_test.go | 908 --------------------- x/subspaces/keeper/msg_server.go | 19 +- x/subspaces/keeper/msg_server_test.go | 877 -------------------- x/subspaces/keeper/permissions.go | 12 +- x/subspaces/keeper/permissions_test.go | 342 ++++++++ x/subspaces/keeper/subspaces.go | 4 +- x/subspaces/keeper/subspaces_test.go | 231 ++++++ x/subspaces/types/keys.go | 20 +- x/subspaces/types/query.pb.go | 130 ++- 17 files changed, 1242 insertions(+), 3225 deletions(-) delete mode 100644 x/subspaces/keeper/alias_functions_test.go delete mode 100644 x/subspaces/keeper/genesis_test.go delete mode 100644 x/subspaces/keeper/keeper_test.go delete mode 100644 x/subspaces/keeper/msg_server_test.go create mode 100644 x/subspaces/keeper/permissions_test.go create mode 100644 x/subspaces/keeper/subspaces_test.go diff --git a/proto/desmos/subspaces/v1/query.proto b/proto/desmos/subspaces/v1/query.proto index c99f0df7cc..8195d67dca 100644 --- a/proto/desmos/subspaces/v1/query.proto +++ b/proto/desmos/subspaces/v1/query.proto @@ -122,5 +122,5 @@ message QueryPermissionsRequest { // QuerySubspaceResponse is the response type for the Query/Subspace method message QueryPermissionsResponse { - bytes permissions = 1 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; + uint32 permissions = 1 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; } \ No newline at end of file diff --git a/x/subspaces/keeper/alias_functions_test.go b/x/subspaces/keeper/alias_functions_test.go deleted file mode 100644 index 07f6d00f9a..0000000000 --- a/x/subspaces/keeper/alias_functions_test.go +++ /dev/null @@ -1,411 +0,0 @@ -package keeper_test - -import ( - "time" - - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (suite *KeeperTestsuite) TestKeeper_IterateSubspace() { - date, err := time.Parse(time.RFC3339, "2010-10-02T12:10:00.000Z") - suite.NoError(err) - - subspaces := []*types2.Subspace{ - { - ID: "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - Name: "mooncake", - Owner: "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - Creator: "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - CreationTime: date, - Type: types2.SubspaceTypeOpen, - }, - { - ID: "dd065b70feb810a8c6f535cf670fe6e3534085221fa964ed2660ebca93f910d1", - Name: "star", - Owner: "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - Creator: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - CreationTime: date, - Type: types2.SubspaceTypeOpen, - }, - { - ID: "e1ba4807a15d8579f79cfd90a07fc015e6125565c9271eb94aded0b2ebf86163", - Name: "bad", - Owner: "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - Creator: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - CreationTime: date, - Type: types2.SubspaceTypeOpen, - }, - } - - expSubspaces := []*types2.Subspace{ - subspaces[0], - subspaces[1], - } - - for _, subspace := range subspaces { - _ = suite.k.SaveSubspace(suite.ctx, *subspace, subspace.Owner) - } - - var validSubspaces []*types2.Subspace - suite.k.IterateSubspaces(suite.ctx, func(index int64, subspace types2.Subspace) (stop bool) { - if index == 2 { - return false - } - validSubspaces = append(validSubspaces, &subspace) - return false - }) - - suite.Len(expSubspaces, len(validSubspaces)) - suite.Equal(expSubspaces, validSubspaces) -} - -func (suite *KeeperTestsuite) TestKeeper_GetAllSubspaces() { - tests := []struct { - name string - store func(ctx sdk.Context) - expSubspaces []types2.Subspace - }{ - { - name: "Returns all the subspaces", - store: func(ctx sdk.Context) { - sub1 := types2.NewSubspace( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - err := suite.k.SaveSubspace(ctx, sub1, sub1.Owner) - suite.Require().NoError(err) - - sub2 := types2.NewSubspace( - "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", - "mooncake", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - err = suite.k.SaveSubspace(ctx, sub2, sub2.Owner) - suite.Require().NoError(err) - }, - expSubspaces: []types2.Subspace{ - types2.NewSubspace( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - types2.NewSubspace( - "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", - "mooncake", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - }, - { - name: "Returns an empty slice with no subspaces", - expSubspaces: nil, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - subspaces := suite.k.GetAllSubspaces(suite.ctx) - suite.Equal(test.expSubspaces, subspaces) - }) - } -} - -func (suite *KeeperTestsuite) TestKeeper_IterateSubspaceAdmins() { - subspace := types2.NewSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "mooncake", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ) - suite.Require().NoError(suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner)) - - admins := []string{ - "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", - } - for _, admin := range admins { - suite.Require().NoError(suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, admin, subspace.Owner)) - } - - var iterated = 0 - suite.k.IterateSubspaceAdmins(suite.ctx, subspace.ID, func(index int64, admin string) (stop bool) { - iterated++ - suite.Require().Contains(admins, admin) - return false - }) -} - -func (suite *KeeperTestsuite) TestKeeper_GetAllAdmins() { - data := map[types2.Subspace][]string{ - types2.NewSubspace( - "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", - "mooncake1", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ): { - "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", - }, - types2.NewSubspace( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - "mooncake2", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ): { - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", - }, - types2.NewSubspace( - "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", - "mooncake3", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ): {}, - } - - for subspace, admins := range data { - err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - for _, admin := range admins { - err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, admin, subspace.Owner) - suite.Require().NoError(err) - } - } - - expected := []types2.UsersEntry{ - types2.NewUsersEntry( - "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", - []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, - ), - types2.NewUsersEntry( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - []string{ - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", - }, - ), - types2.NewUsersEntry( - "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", - nil, - ), - } - - stored := suite.k.GetAllAdmins(suite.ctx) - suite.Require().Equal(expected, stored) -} - -func (suite *KeeperTestsuite) TestKeeper_IterateSubspaceRegisteredUsers() { - subspace := types2.NewSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "mooncake", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ) - suite.Require().NoError(suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner)) - - admins := []string{ - "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", - } - for _, admin := range admins { - suite.Require().NoError(suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, admin, subspace.Owner)) - } - - var iterated = 0 - suite.k.IterateSubspaceRegisteredUsers(suite.ctx, subspace.ID, func(index int64, admin string) (stop bool) { - iterated++ - suite.Require().Contains(admins, admin) - return false - }) -} - -func (suite *KeeperTestsuite) TestKeeper_GetAllRegisteredUsers() { - data := map[types2.Subspace][]string{ - types2.NewSubspace( - "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", - "mooncake1", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ): { - "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", - }, - types2.NewSubspace( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - "mooncake2", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ): { - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", - }, - types2.NewSubspace( - "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", - "mooncake3", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ): {}, - } - - for subspace, users := range data { - err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - for _, admin := range users { - err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, admin, subspace.Owner) - suite.Require().NoError(err) - } - } - - expected := []types2.UsersEntry{ - types2.NewUsersEntry( - "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", - []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, - ), - types2.NewUsersEntry( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - []string{ - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", - }, - ), - types2.NewUsersEntry( - "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", - nil, - ), - } - - stored := suite.k.GetAllRegisteredUsers(suite.ctx) - suite.Require().Equal(expected, stored) -} - -func (suite *KeeperTestsuite) TestKeeper_IterateSubspaceBannedUsers() { - subspace := types2.NewSubspace( - "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", - "mooncake", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ) - suite.Require().NoError(suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner)) - - admins := []string{ - "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", - } - for _, admin := range admins { - suite.Require().NoError(suite.k.BanUserInSubspace(suite.ctx, subspace.ID, admin, subspace.Owner)) - } - - var iterated = 0 - suite.k.IterateSubspaceBannedUsers(suite.ctx, subspace.ID, func(index int64, admin string) (stop bool) { - iterated++ - suite.Require().Contains(admins, admin) - return false - }) -} - -func (suite *KeeperTestsuite) TestKeeper_GetAllBannedUsers() { - data := map[types2.Subspace][]string{ - types2.NewSubspace( - "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", - "mooncake1", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ): { - "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", - }, - types2.NewSubspace( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - "mooncake2", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ): { - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", - }, - types2.NewSubspace( - "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", - "mooncake3", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", - types2.SubspaceTypeOpen, - time.Now(), - ): {}, - } - - for subspace, users := range data { - err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - for _, admin := range users { - err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, admin, subspace.Owner) - suite.Require().NoError(err) - } - } - - expected := []types2.UsersEntry{ - types2.NewUsersEntry( - "5A1B59C7DCB504039C04BCBC8C1C629CF5482374CF85ACD829C18102B301E299", - []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, - ), - types2.NewUsersEntry( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - []string{ - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", - }, - ), - types2.NewUsersEntry( - "C213BBE9641343190E4AAF12D882CD2F91EA588A9D4C18A20B0087C730DBA6CD", - nil, - ), - } - - stored := suite.k.GetAllBannedUsers(suite.ctx) - suite.Require().Equal(expected, stored) -} diff --git a/x/subspaces/keeper/genesis.go b/x/subspaces/keeper/genesis.go index 099637daac..18372b6112 100644 --- a/x/subspaces/keeper/genesis.go +++ b/x/subspaces/keeper/genesis.go @@ -1,75 +1,76 @@ package keeper -import ( - "fmt" - - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// ExportGenesis returns the GenesisState associated with the given context -func (k Keeper) ExportGenesis(ctx sdk.Context) *types2.GenesisState { - return types2.NewGenesisState( - k.GetAllSubspaces(ctx), - k.GetAllAdmins(ctx), - k.GetAllRegisteredUsers(ctx), - k.GetAllBannedUsers(ctx), - ) -} - -// InitGenesis initializes the chain state based on the given GenesisState -func (k Keeper) InitGenesis(ctx sdk.Context, data *types2.GenesisState) { - // Initialize the subspaces - for _, subspace := range data.Subspaces { - err := k.SaveSubspace(ctx, subspace, subspace.Owner) - if err != nil { - panic(err) - } - } - - // Initialize the admins - for _, entry := range data.Admins { - subspace, found := k.GetSubspace(ctx, entry.SubspaceID) - if !found { - panic(fmt.Errorf("invalid admins entry: subspace with id %s does not exist", entry.SubspaceID)) - } - - for _, admin := range entry.Users { - err := k.AddAdminToSubspace(ctx, subspace.ID, admin, subspace.Owner) - if err != nil { - panic(err) - } - } - } - - // Initialize the registered users - for _, entry := range data.RegisteredUsers { - subspace, found := k.GetSubspace(ctx, entry.SubspaceID) - if !found { - panic(fmt.Errorf("invalid registered user entry: subspace with id %s does not exist", entry.SubspaceID)) - } - - for _, user := range entry.Users { - err := k.RegisterUserInSubspace(ctx, subspace.ID, user, subspace.Owner) - if err != nil { - panic(err) - } - } - } - - // Initialize the banned users - for _, entry := range data.BannedUsers { - subspace, found := k.GetSubspace(ctx, entry.SubspaceID) - if !found { - panic(fmt.Errorf("invalid banned user entry: subspace with id %s does not exist", entry.SubspaceID)) - } - - for _, user := range entry.Users { - err := k.BanUserInSubspace(ctx, subspace.ID, user, subspace.Owner) - if err != nil { - panic(err) - } - } - } -} +// +//import ( +// "fmt" +// +// "github.com/desmos-labs/desmos/v2/x/subspaces/types" +// +// sdk "github.com/cosmos/cosmos-sdk/types" +//) +// +//// ExportGenesis returns the GenesisState associated with the given context +//func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { +// return types.NewGenesisState( +// k.GetAllSubspaces(ctx), +// k.GetAllAdmins(ctx), +// k.GetAllRegisteredUsers(ctx), +// k.GetAllBannedUsers(ctx), +// ) +//} +// +//// InitGenesis initializes the chain state based on the given GenesisState +//func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) { +// // Initialize the subspaces +// for _, subspace := range data.Subspaces { +// err := k.SaveSubspace(ctx, subspace, subspace.Owner) +// if err != nil { +// panic(err) +// } +// } +// +// // Initialize the admins +// for _, entry := range data.Admins { +// subspace, found := k.GetSubspace(ctx, entry.SubspaceID) +// if !found { +// panic(fmt.Errorf("invalid admins entry: subspace with id %s does not exist", entry.SubspaceID)) +// } +// +// for _, admin := range entry.Users { +// err := k.AddAdminToSubspace(ctx, subspace.ID, admin, subspace.Owner) +// if err != nil { +// panic(err) +// } +// } +// } +// +// // Initialize the registered users +// for _, entry := range data.RegisteredUsers { +// subspace, found := k.GetSubspace(ctx, entry.SubspaceID) +// if !found { +// panic(fmt.Errorf("invalid registered user entry: subspace with id %s does not exist", entry.SubspaceID)) +// } +// +// for _, user := range entry.Users { +// err := k.RegisterUserInSubspace(ctx, subspace.ID, user, subspace.Owner) +// if err != nil { +// panic(err) +// } +// } +// } +// +// // Initialize the banned users +// for _, entry := range data.BannedUsers { +// subspace, found := k.GetSubspace(ctx, entry.SubspaceID) +// if !found { +// panic(fmt.Errorf("invalid banned user entry: subspace with id %s does not exist", entry.SubspaceID)) +// } +// +// for _, user := range entry.Users { +// err := k.BanUserInSubspace(ctx, subspace.ID, user, subspace.Owner) +// if err != nil { +// panic(err) +// } +// } +// } +//} diff --git a/x/subspaces/keeper/genesis_test.go b/x/subspaces/keeper/genesis_test.go deleted file mode 100644 index 838065a423..0000000000 --- a/x/subspaces/keeper/genesis_test.go +++ /dev/null @@ -1,342 +0,0 @@ -package keeper_test - -import ( - "time" - - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { - tests := []struct { - name string - store func(ctx sdk.Context) - expected *types2.GenesisState - }{ - { - name: "Default expected state", - expected: &types2.GenesisState{Subspaces: nil}, - }, - { - name: "Genesis exported successfully", - store: func(ctx sdk.Context) { - - subspace := types2.NewSubspace( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0", subspace.Owner) - suite.Require().NoError(err) - }, - expected: types2.NewGenesisState( - []types2.Subspace{ - types2.NewSubspace( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - []types2.UsersEntry{ - types2.NewUsersEntry( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, - ), - }, - []types2.UsersEntry{ - types2.NewUsersEntry( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - []string{"cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"}, - ), - }, - []types2.UsersEntry{ - types2.NewUsersEntry( - "A3C6CA0A7141715A61DFD73AB682C8E6B59C6D8C40F0231C2CFC7D21CF968476", - []string{"cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0"}, - ), - }, - ), - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - exported := suite.k.ExportGenesis(suite.ctx) - suite.Equal(test.expected, exported) - }) - } -} - -func (suite *KeeperTestsuite) TestKeeper_InitGenesis() { - tests := []struct { - name string - genesis *types2.GenesisState - expError bool - check func(ctx sdk.Context) - }{ - { - name: "Default genesis is initialized properly", - genesis: types2.DefaultGenesisState(), - expError: false, - }, - { - name: "Invalid subspace panics", - genesis: types2.NewGenesisState( - []types2.Subspace{ - types2.NewSubspace( - "", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - nil, - nil, - nil, - ), - expError: true, - }, - { - name: "Admins entry for non existing subspace returns error", - genesis: types2.NewGenesisState( - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"}, - ), - }, - nil, - nil, - ), - expError: true, - }, - { - name: "Duplicated admins returns error", - genesis: types2.NewGenesisState( - []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{ - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - }, - ), - }, - nil, - nil, - ), - expError: true, - }, - { - name: "Registered users entry for non existing subspace returns error", - genesis: types2.NewGenesisState( - nil, - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"}, - ), - }, - nil, - ), - expError: true, - }, - { - name: "Duplicated registered users returns error", - genesis: types2.NewGenesisState( - []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{ - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - }, - ), - }, - nil, - ), - expError: true, - }, - { - name: "Banned users entry for non existing subspace returns error", - genesis: types2.NewGenesisState( - nil, - nil, - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"}, - ), - }, - ), - expError: true, - }, - { - name: "Duplicated banned users returns error", - genesis: types2.NewGenesisState( - []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - nil, - nil, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{ - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - }, - ), - }, - ), - expError: true, - }, - { - name: "Valid genesis initialized correctly", - genesis: types2.NewGenesisState( - []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 0, 00, 00, 000, time.UTC), - ), - }, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"}, - ), - }, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, - ), - }, - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0"}, - ), - }, - ), - check: func(ctx sdk.Context) { - subspace, found := suite.k.GetSubspace(ctx, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e") - suite.Require().True(found) - suite.Require().True(subspace.Equal(types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 0, 00, 00, 000, time.UTC), - ))) - - suite.Require().Equal( - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"}, - ), - }, - suite.k.GetAllAdmins(ctx), - ) - - suite.Require().Equal( - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos15uc89vnzufu5kuhhsxdkltt38zfx8vcyggzwfm"}, - ), - }, - suite.k.GetAllRegisteredUsers(ctx), - ) - - suite.Require().Equal( - []types2.UsersEntry{ - types2.NewUsersEntry( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - []string{"cosmos1xmquc944hzu6n6qtljcexkuhhz76mucxtgm5x0"}, - ), - }, - suite.k.GetAllBannedUsers(ctx), - ) - }, - expError: false, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - - if test.expError { - suite.Require().Panics(func() { suite.k.InitGenesis(suite.ctx, test.genesis) }) - } else { - suite.k.InitGenesis(suite.ctx, test.genesis) - if test.check != nil { - test.check(suite.ctx) - } - } - }) - } -} diff --git a/x/subspaces/keeper/grpc_query.go b/x/subspaces/keeper/grpc_query.go index d7b668685e..ed74f20b35 100644 --- a/x/subspaces/keeper/grpc_query.go +++ b/x/subspaces/keeper/grpc_query.go @@ -1,9 +1,10 @@ package keeper import ( + "bytes" "context" - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" @@ -13,31 +14,30 @@ import ( "google.golang.org/grpc/status" ) -var _ types2.QueryServer = Keeper{} - -func (k Keeper) Subspace(ctx context.Context, request *types2.QuerySubspaceRequest) (*types2.QuerySubspaceResponse, error) { - if !types2.IsValidSubspace(request.SubspaceId) { - return nil, sdkerrors.Wrap(types2.ErrInvalidSubspaceID, request.SubspaceId) - } +var _ types.QueryServer = Keeper{} +// Subspace implements the Query/Subspace gRPC method +func (k Keeper) Subspace(ctx context.Context, request *types.QuerySubspaceRequest) (*types.QuerySubspaceResponse, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) + subspace, found := k.GetSubspace(sdkCtx, request.SubspaceId) if !found { - return nil, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "subspace with id %s not found", request.SubspaceId) + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "subspace with id %d not found", request.SubspaceId) } - return &types2.QuerySubspaceResponse{Subspace: subspace}, nil + return &types.QuerySubspaceResponse{Subspace: subspace}, nil } -func (k Keeper) Subspaces(goCtx context.Context, request *types2.QuerySubspacesRequest) (*types2.QuerySubspacesResponse, error) { - var subspaces []types2.Subspace - ctx := sdk.UnwrapSDKContext(goCtx) +// Subspaces implements the Query/Subspaces gRPC method +func (k Keeper) Subspaces(ctx context.Context, request *types.QuerySubspacesRequest) (*types.QuerySubspacesResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) - store := ctx.KVStore(k.storeKey) - subspacesStore := prefix.NewStore(store, types2.SubspaceStorePrefix) + store := sdkCtx.KVStore(k.storeKey) + subspacesStore := prefix.NewStore(store, types.SubspacePrefix) + var subspaces []types.Subspace pageRes, err := query.Paginate(subspacesStore, request.Pagination, func(key []byte, value []byte) error { - var subspace types2.Subspace + var subspace types.Subspace if err := k.cdc.Unmarshal(value, &subspace); err != nil { return status.Error(codes.Internal, err.Error()) } @@ -50,23 +50,21 @@ func (k Keeper) Subspaces(goCtx context.Context, request *types2.QuerySubspacesR return nil, status.Error(codes.Internal, err.Error()) } - return &types2.QuerySubspacesResponse{Subspaces: subspaces, Pagination: pageRes}, nil + return &types.QuerySubspacesResponse{Subspaces: subspaces, Pagination: pageRes}, nil } -func (k Keeper) Admins(goCtx context.Context, request *types2.QueryAdminsRequest) (*types2.QueryAdminsResponse, error) { - if !types2.IsValidSubspace(request.SubspaceId) { - return nil, sdkerrors.Wrap(types2.ErrInvalidSubspaceID, request.SubspaceId) - } - - var admins []string - ctx := sdk.UnwrapSDKContext(goCtx) +// UserGroups implements the Query/UserGroups gRPC method +func (k Keeper) UserGroups(ctx context.Context, request *types.QueryUserGroupsRequest) (*types.QueryUserGroupsResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) - store := ctx.KVStore(k.storeKey) - subspacesStore := prefix.NewStore(store, types2.SubspaceAdminsPrefix(request.SubspaceId)) + store := sdkCtx.KVStore(k.storeKey) + storePrefix := types.GroupsStoreKey(request.SubspaceId) + groupsStore := prefix.NewStore(store, storePrefix) - pageRes, err := query.Paginate(subspacesStore, request.Pagination, func(_ []byte, value []byte) error { - admin := string(value) - admins = append(admins, admin) + var groups []string + pageRes, err := query.Paginate(groupsStore, request.Pagination, func(key []byte, value []byte) error { + groupName := types.GetGroupNameFromBytes(bytes.TrimPrefix(key, storePrefix)) + groups = append(groups, groupName) return nil }) @@ -74,23 +72,21 @@ func (k Keeper) Admins(goCtx context.Context, request *types2.QueryAdminsRequest return nil, status.Error(codes.Internal, err.Error()) } - return &types2.QueryAdminsResponse{Admins: admins, Pagination: pageRes}, nil + return &types.QueryUserGroupsResponse{Groups: groups, Pagination: pageRes}, nil } -func (k Keeper) RegisteredUsers(goCtx context.Context, request *types2.QueryRegisteredUsersRequest) (*types2.QueryRegisteredUsersResponse, error) { - if !types2.IsValidSubspace(request.SubspaceId) { - return nil, sdkerrors.Wrap(types2.ErrInvalidSubspaceID, request.SubspaceId) - } - - var users []string - ctx := sdk.UnwrapSDKContext(goCtx) +// UserGroupMembers implements the Query/UserGroupMembers gRPC method +func (k Keeper) UserGroupMembers(ctx context.Context, request *types.QueryUserGroupMembersRequest) (*types.QueryUserGroupMembersResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) - store := ctx.KVStore(k.storeKey) - subspacesStore := prefix.NewStore(store, types2.SubspaceRegisteredUsersPrefix(request.SubspaceId)) + store := sdkCtx.KVStore(k.storeKey) + storePrefix := types.GroupMembersStoreKey(request.SubspaceId, request.GroupName) + membersStore := prefix.NewStore(store, storePrefix) - pageRes, err := query.Paginate(subspacesStore, request.Pagination, func(_ []byte, value []byte) error { - user := string(value) - users = append(users, user) + var members []string + pageRes, err := query.Paginate(membersStore, request.Pagination, func(key []byte, value []byte) error { + member := types.GetGroupMemberFromBytes(bytes.TrimPrefix(key, storePrefix)) + members = append(members, member) return nil }) @@ -98,29 +94,12 @@ func (k Keeper) RegisteredUsers(goCtx context.Context, request *types2.QueryRegi return nil, status.Error(codes.Internal, err.Error()) } - return &types2.QueryRegisteredUsersResponse{Users: users, Pagination: pageRes}, nil + return &types.QueryUserGroupMembersResponse{Members: members, Pagination: pageRes}, nil } -func (k Keeper) BannedUsers(goCtx context.Context, request *types2.QueryBannedUsersRequest) (*types2.QueryBannedUsersResponse, error) { - if !types2.IsValidSubspace(request.SubspaceId) { - return nil, sdkerrors.Wrap(types2.ErrInvalidSubspaceID, request.SubspaceId) - } - - var users []string - ctx := sdk.UnwrapSDKContext(goCtx) - - store := ctx.KVStore(k.storeKey) - subspacesStore := prefix.NewStore(store, types2.SubspaceBannedUsersPrefix(request.SubspaceId)) - - pageRes, err := query.Paginate(subspacesStore, request.Pagination, func(_ []byte, value []byte) error { - user := string(value) - users = append(users, user) - return nil - }) - - if err != nil { - return nil, status.Error(codes.Internal, err.Error()) - } - - return &types2.QueryBannedUsersResponse{Users: users, Pagination: pageRes}, nil +// Permissions implements the Query/Permissions gRPC method +func (k Keeper) Permissions(ctx context.Context, request *types.QueryPermissionsRequest) (*types.QueryPermissionsResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + permission := k.GetPermissions(sdkCtx, request.SubspaceId, request.Target) + return &types.QueryPermissionsResponse{Permissions: permission}, nil } diff --git a/x/subspaces/keeper/grpc_query_test.go b/x/subspaces/keeper/grpc_query_test.go index 8c84e8c4dd..eb19fd7eb6 100644 --- a/x/subspaces/keeper/grpc_query_test.go +++ b/x/subspaces/keeper/grpc_query_test.go @@ -1,348 +1,349 @@ package keeper_test -import ( - "time" - - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/types/query" -) - -func (suite *KeeperTestsuite) TestQueryServer_Subspace() { - tests := []struct { - name string - store func(ctx sdk.Context) - request *types2.QuerySubspaceRequest - shouldErr bool - expResponse *types2.QuerySubspaceResponse - }{ - { - name: "Invalid subspace id returns error", - request: types2.NewQuerySubspaceRequest("123"), - shouldErr: true, - }, - { - name: "Not found subspace returns error", - request: types2.NewQuerySubspaceRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - shouldErr: true, - }, - { - name: "Found subspace is returned properly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - request: types2.NewQuerySubspaceRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - shouldErr: false, - expResponse: &types2.QuerySubspaceResponse{ - Subspace: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - response, err := suite.k.Subspace(sdk.WrapSDKContext(suite.ctx), test.request) - if test.shouldErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(test.expResponse, response) - } - }) - } -} - -func (suite *KeeperTestsuite) TestQueryServer_Subspaces() { - tests := []struct { - name string - store func(ctx sdk.Context) - req *types2.QuerySubspacesRequest - expSubspaces []types2.Subspace - }{ - - { - name: "Invalid pagination returns empty slice", - req: types2.NewQuerySubspacesRequest(&query.PageRequest{ - Limit: 1, - Offset: 1, - }), - expSubspaces: nil, - }, - { - name: "Valid pagination returns result properly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - req: &types2.QuerySubspacesRequest{}, - expSubspaces: []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - res, err := suite.k.Subspaces(sdk.WrapSDKContext(suite.ctx), test.req) - suite.Require().NoError(err) - suite.Require().Equal(test.expSubspaces, res.Subspaces) - }) - } -} - -func (suite *KeeperTestsuite) TestQueryServer_Admins() { - tests := []struct { - name string - store func(ctx sdk.Context) - req *types2.QueryAdminsRequest - shouldErr bool - expAdmins []string - }{ - { - name: "Invalid subspace id returns error", - req: types2.NewQueryAdminsRequest("123", nil), - shouldErr: true, - }, - { - name: "Non existing subspace returns empty slice", - req: types2.NewQueryAdminsRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), - shouldErr: false, - expAdmins: nil, - }, - { - name: "Requests pagination works properly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) - suite.Require().NoError(err) - }, - req: types2.NewQueryAdminsRequest( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - &query.PageRequest{ - Offset: 1, - Limit: 1, - }, - ), - expAdmins: []string{ - "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - res, err := suite.k.Admins(sdk.WrapSDKContext(suite.ctx), test.req) - if test.shouldErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(test.expAdmins, res.Admins) - } - }) - } -} - -func (suite *KeeperTestsuite) TestQueryServer_RegisteredUsers() { - tests := []struct { - name string - store func(ctx sdk.Context) - req *types2.QueryRegisteredUsersRequest - shouldErr bool - expUsers []string - }{ - { - name: "Invalid subspace id returns error", - req: types2.NewQueryRegisteredUsersRequest("123", nil), - shouldErr: true, - }, - { - name: "Non existing subspace returns empty slice", - req: types2.NewQueryRegisteredUsersRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), - shouldErr: false, - expUsers: nil, - }, - { - name: "Requests pagination works properly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) - suite.Require().NoError(err) - }, - req: types2.NewQueryRegisteredUsersRequest( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - &query.PageRequest{ - Offset: 1, - Limit: 1, - }, - ), - expUsers: []string{ - "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - res, err := suite.k.RegisteredUsers(sdk.WrapSDKContext(suite.ctx), test.req) - if test.shouldErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(test.expUsers, res.Users) - } - }) - } -} - -func (suite *KeeperTestsuite) TestQueryServer_BannedUsers() { - tests := []struct { - name string - store func(ctx sdk.Context) - req *types2.QueryBannedUsersRequest - shouldErr bool - expUsers []string - }{ - { - name: "Invalid subspace id returns error", - req: types2.NewQueryBannedUsersRequest("123", nil), - shouldErr: true, - }, - { - name: "Non existing subspace returns empty slice", - req: types2.NewQueryBannedUsersRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), - shouldErr: false, - expUsers: nil, - }, - { - name: "Requests pagination works properly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) - suite.Require().NoError(err) - }, - req: types2.NewQueryBannedUsersRequest( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - &query.PageRequest{ - Offset: 1, - Limit: 1, - }, - ), - expUsers: []string{ - "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - res, err := suite.k.BannedUsers(sdk.WrapSDKContext(suite.ctx), test.req) - if test.shouldErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(test.expUsers, res.Users) - } - }) - } -} +// +//import ( +// "time" +// +// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" +// +// sdk "github.com/cosmos/cosmos-sdk/types" +// "github.com/cosmos/cosmos-sdk/types/query" +//) +// +//func (suite *KeeperTestsuite) TestQueryServer_Subspace() { +// tests := []struct { +// name string +// store func(ctx sdk.Context) +// request *types2.QuerySubspaceRequest +// shouldErr bool +// expResponse *types2.QuerySubspaceResponse +// }{ +// { +// name: "Invalid subspace id returns error", +// request: types2.NewQuerySubspaceRequest("123"), +// shouldErr: true, +// }, +// { +// name: "Not found subspace returns error", +// request: types2.NewQuerySubspaceRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), +// shouldErr: true, +// }, +// { +// name: "Found subspace is returned properly", +// store: func(ctx sdk.Context) { +// subspace := types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), +// ) +// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) +// suite.Require().NoError(err) +// }, +// request: types2.NewQuerySubspaceRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), +// shouldErr: false, +// expResponse: &types2.QuerySubspaceResponse{ +// Subspace: types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), +// ), +// }, +// }, +// } +// +// for _, test := range tests { +// test := test +// suite.Run(test.name, func() { +// suite.SetupTest() +// if test.store != nil { +// test.store(suite.ctx) +// } +// +// response, err := suite.k.Subspace(sdk.WrapSDKContext(suite.ctx), test.request) +// if test.shouldErr { +// suite.Require().Error(err) +// } else { +// suite.Require().NoError(err) +// suite.Require().Equal(test.expResponse, response) +// } +// }) +// } +//} +// +//func (suite *KeeperTestsuite) TestQueryServer_Subspaces() { +// tests := []struct { +// name string +// store func(ctx sdk.Context) +// req *types2.QuerySubspacesRequest +// expSubspaces []types2.Subspace +// }{ +// +// { +// name: "Invalid pagination returns empty slice", +// req: types2.NewQuerySubspacesRequest(&query.PageRequest{ +// Limit: 1, +// Offset: 1, +// }), +// expSubspaces: nil, +// }, +// { +// name: "Valid pagination returns result properly", +// store: func(ctx sdk.Context) { +// subspace := types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), +// ) +// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) +// suite.Require().NoError(err) +// }, +// req: &types2.QuerySubspacesRequest{}, +// expSubspaces: []types2.Subspace{ +// types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), +// ), +// }, +// }, +// } +// +// for _, test := range tests { +// test := test +// suite.Run(test.name, func() { +// suite.SetupTest() +// if test.store != nil { +// test.store(suite.ctx) +// } +// +// res, err := suite.k.Subspaces(sdk.WrapSDKContext(suite.ctx), test.req) +// suite.Require().NoError(err) +// suite.Require().Equal(test.expSubspaces, res.Subspaces) +// }) +// } +//} +// +//func (suite *KeeperTestsuite) TestQueryServer_Admins() { +// tests := []struct { +// name string +// store func(ctx sdk.Context) +// req *types2.QueryAdminsRequest +// shouldErr bool +// expAdmins []string +// }{ +// { +// name: "Invalid subspace id returns error", +// req: types2.NewQueryAdminsRequest("123", nil), +// shouldErr: true, +// }, +// { +// name: "Non existing subspace returns empty slice", +// req: types2.NewQueryAdminsRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), +// shouldErr: false, +// expAdmins: nil, +// }, +// { +// name: "Requests pagination works properly", +// store: func(ctx sdk.Context) { +// subspace := types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), +// ) +// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) +// suite.Require().NoError(err) +// +// err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) +// suite.Require().NoError(err) +// +// err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) +// suite.Require().NoError(err) +// }, +// req: types2.NewQueryAdminsRequest( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// &query.PageRequest{ +// Offset: 1, +// Limit: 1, +// }, +// ), +// expAdmins: []string{ +// "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", +// }, +// }, +// } +// +// for _, test := range tests { +// test := test +// suite.Run(test.name, func() { +// suite.SetupTest() +// if test.store != nil { +// test.store(suite.ctx) +// } +// +// res, err := suite.k.Admins(sdk.WrapSDKContext(suite.ctx), test.req) +// if test.shouldErr { +// suite.Require().Error(err) +// } else { +// suite.Require().NoError(err) +// suite.Require().Equal(test.expAdmins, res.Admins) +// } +// }) +// } +//} +// +//func (suite *KeeperTestsuite) TestQueryServer_RegisteredUsers() { +// tests := []struct { +// name string +// store func(ctx sdk.Context) +// req *types2.QueryRegisteredUsersRequest +// shouldErr bool +// expUsers []string +// }{ +// { +// name: "Invalid subspace id returns error", +// req: types2.NewQueryRegisteredUsersRequest("123", nil), +// shouldErr: true, +// }, +// { +// name: "Non existing subspace returns empty slice", +// req: types2.NewQueryRegisteredUsersRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), +// shouldErr: false, +// expUsers: nil, +// }, +// { +// name: "Requests pagination works properly", +// store: func(ctx sdk.Context) { +// subspace := types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), +// ) +// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) +// suite.Require().NoError(err) +// +// err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) +// suite.Require().NoError(err) +// +// err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) +// suite.Require().NoError(err) +// }, +// req: types2.NewQueryRegisteredUsersRequest( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// &query.PageRequest{ +// Offset: 1, +// Limit: 1, +// }, +// ), +// expUsers: []string{ +// "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", +// }, +// }, +// } +// +// for _, test := range tests { +// test := test +// suite.Run(test.name, func() { +// suite.SetupTest() +// if test.store != nil { +// test.store(suite.ctx) +// } +// +// res, err := suite.k.RegisteredUsers(sdk.WrapSDKContext(suite.ctx), test.req) +// if test.shouldErr { +// suite.Require().Error(err) +// } else { +// suite.Require().NoError(err) +// suite.Require().Equal(test.expUsers, res.Users) +// } +// }) +// } +//} +// +//func (suite *KeeperTestsuite) TestQueryServer_BannedUsers() { +// tests := []struct { +// name string +// store func(ctx sdk.Context) +// req *types2.QueryBannedUsersRequest +// shouldErr bool +// expUsers []string +// }{ +// { +// name: "Invalid subspace id returns error", +// req: types2.NewQueryBannedUsersRequest("123", nil), +// shouldErr: true, +// }, +// { +// name: "Non existing subspace returns empty slice", +// req: types2.NewQueryBannedUsersRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), +// shouldErr: false, +// expUsers: nil, +// }, +// { +// name: "Requests pagination works properly", +// store: func(ctx sdk.Context) { +// subspace := types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), +// ) +// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) +// suite.Require().NoError(err) +// +// err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) +// suite.Require().NoError(err) +// +// err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) +// suite.Require().NoError(err) +// }, +// req: types2.NewQueryBannedUsersRequest( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// &query.PageRequest{ +// Offset: 1, +// Limit: 1, +// }, +// ), +// expUsers: []string{ +// "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", +// }, +// }, +// } +// +// for _, test := range tests { +// test := test +// suite.Run(test.name, func() { +// suite.SetupTest() +// if test.store != nil { +// test.store(suite.ctx) +// } +// +// res, err := suite.k.BannedUsers(sdk.WrapSDKContext(suite.ctx), test.req) +// if test.shouldErr { +// suite.Require().Error(err) +// } else { +// suite.Require().NoError(err) +// suite.Require().Equal(test.expUsers, res.Users) +// } +// }) +// } +//} diff --git a/x/subspaces/keeper/invariants.go b/x/subspaces/keeper/invariants.go index 655b03ecac..22461a01d9 100644 --- a/x/subspaces/keeper/invariants.go +++ b/x/subspaces/keeper/invariants.go @@ -1,50 +1,51 @@ package keeper -import ( - "fmt" - - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// RegisterInvariants registers all subspaces invariants -func RegisterInvariants(ir sdk.InvariantRegistry, keeper Keeper) { - ir.RegisterRoute(types2.ModuleName, "valid-subspaces", - ValidSubspacesInvariant(keeper)) -} - -// AllInvariants runs all invariants of the module -func AllInvariants(k Keeper) sdk.Invariant { - return func(ctx sdk.Context) (string, bool) { - if res, stop := ValidSubspacesInvariant(k)(ctx); stop { - return res, stop - } - return "Every invariant condition is fulfilled correctly", true - } -} - -// formatOutputSubspaces concatenate the subspaces given into a unique string -func formatOutputSubspaces(subspaces []types2.Subspace) (outputSubspaces string) { - for _, subspace := range subspaces { - outputSubspaces += subspace.ID + "\n" - } - return outputSubspaces -} - -// ValidSubspacesInvariant checks that all the subspaces are valid -func ValidSubspacesInvariant(k Keeper) sdk.Invariant { - return func(ctx sdk.Context) (string, bool) { - var invalidSubspaces []types2.Subspace - k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { - if err := subspace.Validate(); err != nil { - invalidSubspaces = append(invalidSubspaces, subspace) - } - return false - }) - - return sdk.FormatInvariant(types2.ModuleName, "invalid subspaces", - fmt.Sprintf("the following subspaces are invalid:\n %s", formatOutputSubspaces(invalidSubspaces)), - ), invalidSubspaces != nil - } -} +// +//import ( +// "fmt" +// +// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" +// +// sdk "github.com/cosmos/cosmos-sdk/types" +//) +// +//// RegisterInvariants registers all subspaces invariants +//func RegisterInvariants(ir sdk.InvariantRegistry, keeper Keeper) { +// ir.RegisterRoute(types2.ModuleName, "valid-subspaces", +// ValidSubspacesInvariant(keeper)) +//} +// +//// AllInvariants runs all invariants of the module +//func AllInvariants(k Keeper) sdk.Invariant { +// return func(ctx sdk.Context) (string, bool) { +// if res, stop := ValidSubspacesInvariant(k)(ctx); stop { +// return res, stop +// } +// return "Every invariant condition is fulfilled correctly", true +// } +//} +// +//// formatOutputSubspaces concatenate the subspaces given into a unique string +//func formatOutputSubspaces(subspaces []types2.Subspace) (outputSubspaces string) { +// for _, subspace := range subspaces { +// outputSubspaces += subspace.ID + "\n" +// } +// return outputSubspaces +//} +// +//// ValidSubspacesInvariant checks that all the subspaces are valid +//func ValidSubspacesInvariant(k Keeper) sdk.Invariant { +// return func(ctx sdk.Context) (string, bool) { +// var invalidSubspaces []types2.Subspace +// k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { +// if err := subspace.Validate(); err != nil { +// invalidSubspaces = append(invalidSubspaces, subspace) +// } +// return false +// }) +// +// return sdk.FormatInvariant(types2.ModuleName, "invalid subspaces", +// fmt.Sprintf("the following subspaces are invalid:\n %s", formatOutputSubspaces(invalidSubspaces)), +// ), invalidSubspaces != nil +// } +//} diff --git a/x/subspaces/keeper/invariants_test.go b/x/subspaces/keeper/invariants_test.go index 3eb759326a..8ed1ab3d9c 100644 --- a/x/subspaces/keeper/invariants_test.go +++ b/x/subspaces/keeper/invariants_test.go @@ -1,64 +1,65 @@ package keeper_test -import ( - "time" - - "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (suite *KeeperTestsuite) TestInvariants() { - tests := []struct { - name string - store func(ctx sdk.Context) - expStop bool - }{ - { - name: "All invariants are not violated", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - expStop: true, - }, - { - name: "Valid subspace invariant violated", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC), - ) - _ = suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - }, - expStop: true, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - _, stop := keeper.AllInvariants(suite.k)(suite.ctx) - suite.Require().Equal(test.expStop, stop) - }) - } -} +// +//import ( +// "time" +// +// "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" +// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" +// +// sdk "github.com/cosmos/cosmos-sdk/types" +//) +// +//func (suite *KeeperTestsuite) TestInvariants() { +// tests := []struct { +// name string +// store func(ctx sdk.Context) +// expStop bool +// }{ +// { +// name: "All invariants are not violated", +// store: func(ctx sdk.Context) { +// subspace := types2.NewSubspace( +// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", +// "test", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC), +// ) +// +// err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) +// suite.Require().NoError(err) +// }, +// expStop: true, +// }, +// { +// name: "Valid subspace invariant violated", +// store: func(ctx sdk.Context) { +// subspace := types2.NewSubspace( +// "", +// "test", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", +// types2.SubspaceTypeOpen, +// time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC), +// ) +// _ = suite.k.SaveSubspace(ctx, subspace, subspace.Owner) +// }, +// expStop: true, +// }, +// } +// +// for _, test := range tests { +// test := test +// suite.Run(test.name, func() { +// suite.SetupTest() +// if test.store != nil { +// test.store(suite.ctx) +// } +// +// _, stop := keeper.AllInvariants(suite.k)(suite.ctx) +// suite.Require().Equal(test.expStop, stop) +// }) +// } +//} diff --git a/x/subspaces/keeper/keeper_test.go b/x/subspaces/keeper/keeper_test.go deleted file mode 100644 index ec590dbd72..0000000000 --- a/x/subspaces/keeper/keeper_test.go +++ /dev/null @@ -1,908 +0,0 @@ -package keeper_test - -import ( - "time" - - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (suite *KeeperTestsuite) TestKeeper_SaveSubspace() { - tests := []struct { - name string - storedSubspaces []types2.Subspace - subspaceToSave types2.Subspace - expErr bool - expStored []types2.Subspace - }{ - { - name: "Already stored subspace with different owner", - storedSubspaces: []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - subspaceToSave: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - expErr: true, - }, - { - name: "New subspace saved correctly", - subspaceToSave: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - expErr: false, - expStored: []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - }, - { - name: "Old subspace edited correctly", - storedSubspaces: []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - subspaceToSave: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test-updated", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeClosed, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - expErr: false, - expStored: []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test-updated", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeClosed, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - store := suite.ctx.KVStore(suite.storeKey) - for _, subspace := range test.storedSubspaces { - store.Set(types2.SubspaceStoreKey(subspace.ID), suite.cdc.MustMarshal(&subspace)) - } - - err := suite.k.SaveSubspace(suite.ctx, test.subspaceToSave, test.subspaceToSave.Owner) - if test.expErr { - suite.Error(err) - } else { - suite.NoError(err) - suite.Require().Equal(test.expStored, suite.k.GetAllSubspaces(suite.ctx)) - } - }) - } -} - -func (suite *KeeperTestsuite) TestKeeper_DoesSubspaceExists() { - tests := []struct { - name string - subspaceID string - storedSubspaces []types2.Subspace - exists bool - }{ - { - name: "Returns true when the subspace exists", - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - storedSubspaces: []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ), - }, - exists: true, - }, - { - name: "Return false when the subspace doesn't exist", - subspaceID: "123", - exists: false, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - for _, subspace := range test.storedSubspaces { - suite.Require().NoError(suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner)) - } - - exists := suite.k.DoesSubspaceExist(suite.ctx, test.subspaceID) - suite.Equal(test.exists, exists) - }) - } -} - -func (suite *KeeperTestsuite) TestKeeper_GetSubspace() { - tests := []struct { - name string - store func(ctx sdk.Context) - subspaceID string - expFound bool - expSubspace types2.Subspace - }{ - { - name: "Return false when not found", - subspaceID: "123", - expFound: false, - }, - { - name: "Returns the subspace and true when found", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - expFound: true, - expSubspace: types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ), - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - subspace, found := suite.k.GetSubspace(suite.ctx, test.subspaceID) - suite.Require().Equal(test.expFound, found) - - if test.expFound { - suite.Equal(test.expSubspace, subspace) - } - }) - } -} - -func (suite *KeeperTestsuite) TestKeeper_AddAdminToSubspace() { - tests := []struct { - name string - store func(ctx sdk.Context) - subspaceID string - user string - owner string - expError bool - expAdmins []string - }{ - { - name: "Non existent subspace returns error", - subspaceID: "", - expError: true, - }, - { - name: "User already an admin returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: true, - expAdmins: []string{ - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - { - name: "User added as admin correctly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: false, - expAdmins: []string{ - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - err := suite.k.AddAdminToSubspace(suite.ctx, test.subspaceID, test.user, test.owner) - if test.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - } - - var admins []string - suite.k.IterateSubspaceAdmins(suite.ctx, test.subspaceID, func(index int64, admin string) (stop bool) { - admins = append(admins, admin) - return false - }) - suite.Require().Equal(test.expAdmins, admins) - }) - } -} - -func (suite *KeeperTestsuite) TestKeeper_RemoveAdminFromSubspace() { - tests := []struct { - name string - store func(ctx sdk.Context) - subspaceID string - user string - owner string - expAdmins []string - expError bool - }{ - { - name: "Non existent subspace returns error", - subspaceID: "non-existing", - expError: true, - }, - { - name: "Invalid admin returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: true, - expAdmins: []string{ - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - { - name: "One of many admins is removed correctly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: false, - expAdmins: []string{ - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - { - name: "Single admin is removed correctly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - owner: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: false, - expAdmins: nil, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - err := suite.k.RemoveAdminFromSubspace(suite.ctx, test.subspaceID, test.user, test.owner) - if test.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - } - }) - - var admins []string - suite.k.IterateSubspaceAdmins(suite.ctx, test.subspaceID, func(index int64, admin string) (stop bool) { - admins = append(admins, admin) - return false - }) - suite.Require().Equal(test.expAdmins, admins) - } -} - -func (suite *KeeperTestsuite) TestKeeper_RegisterUserInSubspace() { - tests := []struct { - name string - store func(ctx sdk.Context) - subspaceID string - user string - admin string - expError bool - expUsers []string - }{ - { - name: "Non existent subspace returns error", - subspaceID: "non-existing", - expError: true, - }, - { - name: "User already registered returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: true, - expUsers: []string{ - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - { - name: "User registered correctly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: false, - expUsers: []string{ - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - err := suite.k.RegisterUserInSubspace(suite.ctx, test.subspaceID, test.user, test.admin) - if test.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - } - - var users []string - suite.k.IterateSubspaceRegisteredUsers(suite.ctx, test.subspaceID, func(index int64, user string) (stop bool) { - users = append(users, user) - return false - }) - suite.Require().Equal(users, test.expUsers) - }) - } -} - -func (suite *KeeperTestsuite) TestKeeper_UnregisterUserInSubspace() { - tests := []struct { - name string - store func(ctx sdk.Context) - subspaceID string - user string - admin string - expError bool - expUsers []string - }{ - { - name: "Non existent subspace returns error", - subspaceID: "non-existing", - expError: true, - }, - { - name: "Invalid user returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: true, - expUsers: []string{ - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - { - name: "Valid user unregistered correctly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: false, - expUsers: []string{ - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - err := suite.k.UnregisterUserFromSubspace(suite.ctx, test.subspaceID, test.user, test.admin) - if test.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - } - }) - - var users []string - suite.k.IterateSubspaceRegisteredUsers(suite.ctx, test.subspaceID, func(index int64, user string) (stop bool) { - users = append(users, user) - return false - }) - suite.Require().Equal(users, test.expUsers) - } -} - -func (suite *KeeperTestsuite) TestKeeper_BanUser() { - tests := []struct { - name string - store func(ctx sdk.Context) - subspaceID string - user string - admin string - expError bool - expUsers []string - }{ - { - name: "Non existent subspace returns error", - subspaceID: "non-existing", - expError: true, - }, - { - name: "User already banned returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: true, - expUsers: []string{ - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - { - name: "User banned correctly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: false, - expUsers: []string{ - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - err := suite.k.BanUserInSubspace(suite.ctx, test.subspaceID, test.user, test.admin) - if test.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - } - }) - - var users []string - suite.k.IterateSubspaceBannedUsers(suite.ctx, test.subspaceID, func(index int64, user string) (stop bool) { - users = append(users, user) - return false - }) - suite.Require().Equal(users, test.expUsers) - } -} - -func (suite *KeeperTestsuite) TestKeeper_UnbanUser() { - tests := []struct { - name string - store func(ctx sdk.Context) - subspaceID string - user string - admin string - expUsers []string - expError bool - }{ - { - name: "Non existent subspace returns error", - subspaceID: "non-existing", - expError: true, - }, - { - name: "Invalid user returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: true, - expUsers: []string{ - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - { - name: "User unbanned correctly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - admin: "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - expError: false, - expUsers: []string{ - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - err := suite.k.UnbanUserInSubspace(suite.ctx, test.subspaceID, test.user, test.admin) - if test.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - } - - var users []string - suite.k.IterateSubspaceBannedUsers(suite.ctx, test.subspaceID, func(index int64, user string) (stop bool) { - users = append(users, user) - return false - }) - suite.Require().Equal(users, test.expUsers) - }) - } -} - -func (suite *KeeperTestsuite) TestKeeper_CheckSubspaceUserPermission() { - tests := []struct { - name string - store func(ctx sdk.Context) - subspaceID string - user string - expError bool - }{ - { - name: "Non existent subspace returns error", - subspaceID: "non-existing", - expError: true, - }, - { - name: "Banned user returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - expError: true, - }, - { - name: "Subspace types closed and not registered user returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeClosed, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - expError: true, - }, - { - name: "No errors", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - time.Unix(1, 1), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", subspace.Owner) - suite.Require().NoError(err) - }, - subspaceID: "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - user: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - expError: false, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - err := suite.k.CheckSubspaceUserPermission(suite.ctx, test.subspaceID, test.user) - if test.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - } - }) - } -} diff --git a/x/subspaces/keeper/msg_server.go b/x/subspaces/keeper/msg_server.go index 084dd281f1..ba95527c32 100644 --- a/x/subspaces/keeper/msg_server.go +++ b/x/subspaces/keeper/msg_server.go @@ -23,6 +23,7 @@ func NewMsgServerImpl(keeper Keeper) types.MsgServer { var _ types.MsgServer = msgServer{} +// CreateSubspace defines a rpc method for MsgCreateSubspace func (k msgServer) CreateSubspace(goCtx context.Context, msg *types.MsgCreateSubspace) (*types.MsgCreateSubspaceResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) @@ -39,10 +40,7 @@ func (k msgServer) CreateSubspace(goCtx context.Context, msg *types.MsgCreateSub } // Save the subspace - err = k.SaveSubspace(ctx, subspace) - if err != nil { - return nil, err - } + k.SaveSubspace(ctx, subspace) // Update the id for the next subspace k.SetSubspaceID(ctx, subspace.ID+1) @@ -67,6 +65,7 @@ func (k msgServer) CreateSubspace(goCtx context.Context, msg *types.MsgCreateSub }, nil } +// EditSubspace defines a rpc method for MsgEditSubspace func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspace) (*types.MsgEditSubspaceResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) @@ -82,7 +81,7 @@ func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspac // Check the if the subspace exists subspace, exists := k.GetSubspace(ctx, msg.SubspaceID) if !exists { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %s not found", msg.SubspaceID) + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) } // Update the subspace and validate it @@ -93,10 +92,7 @@ func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspac } // Save the subspace - err = k.SaveSubspace(ctx, updated) - if err != nil { - return nil, err - } + k.SaveSubspace(ctx, updated) ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( @@ -113,6 +109,7 @@ func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspac return &types.MsgEditSubspaceResponse{}, nil } +// CreateUserGroup defines a rpc method for MsgCreateUserGroup func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUserGroup) (*types.MsgCreateUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) @@ -149,6 +146,7 @@ func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUs return &types.MsgCreateUserGroupResponse{}, nil } +// DeleteUserGroup defines a rpc method for MsgDeleteUserGroup func (k msgServer) DeleteUserGroup(goCtx context.Context, msg *types.MsgDeleteUserGroup) (*types.MsgDeleteUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) @@ -185,6 +183,7 @@ func (k msgServer) DeleteUserGroup(goCtx context.Context, msg *types.MsgDeleteUs return &types.MsgDeleteUserGroupResponse{}, nil } +// AddUserToUserGroup defines a rpc method for MsgAddUserToUserGroup func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUserToUserGroup) (*types.MsgAddUserToUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) @@ -230,6 +229,7 @@ func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUs return &types.MsgAddUserToUserGroupResponse{}, nil } +// RemoveUserFromUserGroup defines a rpc method for MsgRemoveUserFromUserGroup func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.MsgRemoveUserFromUserGroup) (*types.MsgRemoveUserFromUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) @@ -275,6 +275,7 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg return &types.MsgRemoveUserFromUserGroupResponse{}, nil } +// SetPermissions defines a rpc method for MsgSetPermissions func (k msgServer) SetPermissions(goCtx context.Context, msg *types.MsgSetPermissions) (*types.MsgSetPermissionsResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) diff --git a/x/subspaces/keeper/msg_server_test.go b/x/subspaces/keeper/msg_server_test.go deleted file mode 100644 index a3aa88369d..0000000000 --- a/x/subspaces/keeper/msg_server_test.go +++ /dev/null @@ -1,877 +0,0 @@ -package keeper_test - -import ( - "time" - - "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -func (suite *KeeperTestsuite) TestMsgServer_CreateSubspace() { - creationTime := time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC) - - tests := []struct { - name string - blockTime time.Time - store func(ctx sdk.Context) - msg *types2.MsgCreateSubspace - expErr bool - expEvents sdk.Events - }{ - { - name: "Subspace already existing returns error", - blockTime: creationTime, - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - ctx.BlockTime(), - ) - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgCreateSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test2", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ), - expErr: true, - }, - { - name: "Non existing subspace is saved properly", - blockTime: creationTime, - msg: types2.NewMsgCreateSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test2", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - ), - expErr: false, - expEvents: sdk.Events{ - sdk.NewEvent( - types2.EventTypeCreateSubspace, - sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - sdk.NewAttribute(types2.AttributeKeySubspaceName, "test2"), - sdk.NewAttribute(types2.AttributeKeySubspaceCreator, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"), - sdk.NewAttribute(types2.AttributeKeyCreationTime, creationTime.Format(time.RFC3339)), - ), - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - suite.ctx = suite.ctx.WithBlockTime(test.blockTime) - if test.store != nil { - test.store(suite.ctx) - } - - handler := keeper.NewMsgServerImpl(suite.k) - _, err := handler.CreateSubspace(sdk.WrapSDKContext(suite.ctx), test.msg) - - if test.expErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - - events := suite.ctx.EventManager().Events() - suite.Equal(test.expEvents, events) - } - }) - } -} - -func (suite *KeeperTestsuite) TestMsgServer_EditSubspace() { - creationTime := time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC) - tests := []struct { - name string - blockTime time.Time - store func(ctx sdk.Context) - msg *types2.MsgEditSubspace - expErr bool - expEvents sdk.Events - expStored []types2.Subspace - }{ - { - name: "Non existing subspace returns error", - blockTime: creationTime, - msg: types2.NewMsgEditSubspace( - "1234", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "edited", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - ), - expErr: true, - }, - { - name: "Wrong editor returns error", - blockTime: creationTime, - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - creationTime, - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgEditSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "ccosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "edited", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeClosed, - ), - expErr: true, - }, - { - name: "subspace edited successfully", - blockTime: creationTime, - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeOpen, - creationTime, - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgEditSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "edited", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeClosed, - ), - expErr: false, - expEvents: sdk.Events{ - sdk.NewEvent( - types2.EventTypeEditSubspace, - sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - sdk.NewAttribute(types2.AttributeKeyNewOwner, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"), - sdk.NewAttribute(types2.AttributeKeySubspaceName, "edited"), - ), - }, - expStored: []types2.Subspace{ - types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "edited", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - types2.SubspaceTypeClosed, - creationTime, - ), - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - suite.ctx = suite.ctx.WithBlockTime(test.blockTime) - if test.store != nil { - test.store(suite.ctx) - } - - handler := keeper.NewMsgServerImpl(suite.k) - _, err := handler.EditSubspace(sdk.WrapSDKContext(suite.ctx), test.msg) - - if test.expErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Equal(test.expEvents, suite.ctx.EventManager().Events()) - - var subspaces []types2.Subspace - suite.k.IterateSubspaces(suite.ctx, func(index int64, subspace types2.Subspace) (stop bool) { - subspaces = append(subspaces, subspace) - return false - }) - suite.Require().Equal(test.expStored, subspaces) - } - }) - } -} - -func (suite *KeeperTestsuite) TestMsgServer_AddAdmin() { - tests := []struct { - name string - store func(ctx sdk.Context) - msg *types2.MsgAddAdmin - expErr bool - expEvents sdk.Events - expAdmins []string - }{ - { - name: "Non existing subspace returns error", - msg: types2.NewMsgAddAdmin( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "Duplicated admin returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgAddAdmin( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "Wrong owner returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgAddAdmin( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - ), - expErr: true, - }, - { - name: "Valid request adds the admin properly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgAddAdmin( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - expEvents: sdk.Events{ - sdk.NewEvent( - types2.EventTypeAddAdmin, - sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - sdk.NewAttribute(types2.AttributeKeySubspaceNewAdmin, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"), - ), - }, - expAdmins: []string{ - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - handler := keeper.NewMsgServerImpl(suite.k) - _, err := handler.AddAdmin(sdk.WrapSDKContext(suite.ctx), test.msg) - - if test.expErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - - suite.Equal(test.expEvents, suite.ctx.EventManager().Events()) - - var admins []string - suite.k.IterateSubspaceAdmins(suite.ctx, test.msg.SubspaceID, func(index int64, admin string) (stop bool) { - admins = append(admins, admin) - return false - }) - suite.Require().Equal(test.expAdmins, admins) - } - }) - } -} - -func (suite *KeeperTestsuite) TestMsgServer_RemoveAdmin() { - tests := []struct { - name string - store func(ctx sdk.Context) - msg *types2.MsgRemoveAdmin - expErr bool - expEvents sdk.Events - expAdmins []string - }{ - { - name: "Non existing subspace returns error", - msg: types2.NewMsgRemoveAdmin( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "Non existing admin returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgRemoveAdmin( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "Existing admin is removed successfully", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.AddAdminToSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgRemoveAdmin( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - expEvents: sdk.Events{ - sdk.NewEvent( - types2.EventTypeRemoveAdmin, - sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - sdk.NewAttribute(types2.AttributeKeySubspaceRemovedAdmin, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"), - ), - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - handler := keeper.NewMsgServerImpl(suite.k) - _, err := handler.RemoveAdmin(sdk.WrapSDKContext(suite.ctx), test.msg) - - if test.expErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(test.expEvents, suite.ctx.EventManager().Events()) - - var admins []string - suite.k.IterateSubspaceAdmins(suite.ctx, test.msg.SubspaceID, func(index int64, admin string) (stop bool) { - admins = append(admins, admin) - return false - }) - suite.Require().Equal(test.expAdmins, admins) - } - }) - } -} - -func (suite *KeeperTestsuite) TestMsgServer_RegisterUser() { - tests := []struct { - name string - store func(ctx sdk.Context) - msg *types2.MsgRegisterUser - expErr bool - expEvents sdk.Events - expUsers []string - }{ - { - name: "Non existing subspace returns error", - msg: types2.NewMsgRegisterUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "Registered user returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgRegisterUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - expUsers: []string{ - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - }, - }, - { - name: "Non registered user is registered correctly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgRegisterUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - expEvents: sdk.Events{ - sdk.NewEvent( - types2.EventTypeRegisterUser, - sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - sdk.NewAttribute(types2.AttributeKeyRegisteredUser, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"), - ), - }, - expUsers: []string{ - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - handler := keeper.NewMsgServerImpl(suite.k) - _, err := handler.RegisterUser(sdk.WrapSDKContext(suite.ctx), test.msg) - - if test.expErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Equal(test.expEvents, suite.ctx.EventManager().Events()) - } - - var users []string - suite.k.IterateSubspaceRegisteredUsers(suite.ctx, test.msg.SubspaceID, func(index int64, user string) (stop bool) { - users = append(users, user) - return false - }) - suite.Require().Equal(test.expUsers, users) - }) - } -} - -func (suite *KeeperTestsuite) TestMsgServer_UnregisterUser() { - tests := []struct { - name string - store func(ctx sdk.Context) - msg *types2.MsgUnregisterUser - expErr bool - expEvents sdk.Events - expUsers []string - }{ - { - name: "Non existing subspace returns error", - msg: types2.NewMsgUnregisterUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "Not found user returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgUnregisterUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - expUsers: []string{ - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - }, - }, - { - name: "Valid user unregistered successfully", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.RegisterUserInSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgUnregisterUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - expEvents: sdk.Events{ - sdk.NewEvent( - types2.EventTypeUnregisterUser, - sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - sdk.NewAttribute(types2.AttributeKeyUnregisteredUser, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"), - ), - }, - expUsers: nil, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - handler := keeper.NewMsgServerImpl(suite.k) - _, err := handler.UnregisterUser(sdk.WrapSDKContext(suite.ctx), test.msg) - - if test.expErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(test.expEvents, suite.ctx.EventManager().Events()) - } - - var users []string - suite.k.IterateSubspaceRegisteredUsers(suite.ctx, test.msg.SubspaceID, func(index int64, user string) (stop bool) { - users = append(users, user) - return false - }) - suite.Require().Equal(test.expUsers, users) - }) - } -} - -func (suite *KeeperTestsuite) TestMsgServer_BlockUser() { - tests := []struct { - name string - store func(ctx sdk.Context) - msg *types2.MsgBanUser - expErr bool - expEvents sdk.Events - expUsers []string - }{ - { - name: "Non existing subspace returns error", - msg: types2.NewMsgBanUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "Duplicated ban returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgBanUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - expUsers: []string{ - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - }, - }, - { - name: "Valid ban request works properly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgBanUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - expEvents: sdk.Events{ - sdk.NewEvent( - types2.EventTypeBanUser, - sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - sdk.NewAttribute(types2.AttributeKeyBanUser, "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"), - ), - }, - expUsers: []string{ - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - }, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - handler := keeper.NewMsgServerImpl(suite.k) - _, err := handler.BanUser(sdk.WrapSDKContext(suite.ctx), test.msg) - - if test.expErr { - suite.Error(err) - } else { - suite.NoError(err) - suite.Require().Equal(test.expEvents, suite.ctx.EventManager().Events()) - } - - var users []string - suite.k.IterateSubspaceBannedUsers(suite.ctx, test.msg.SubspaceID, func(index int64, user string) (stop bool) { - users = append(users, user) - return false - }) - suite.Require().Equal(test.expUsers, users) - }) - } -} - -func (suite *KeeperTestsuite) TestMsgServer_UnblockUser() { - tests := []struct { - name string - store func(ctx sdk.Context) - msg *types2.MsgUnbanUser - expErr bool - expEvents sdk.Events - expUsers []string - }{ - { - name: "Non existing subspace returns error", - msg: types2.NewMsgUnbanUser( - "123", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "Not found user returns error", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgUnbanUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: true, - }, - { - name: "Valid block works properly", - store: func(ctx sdk.Context) { - subspace := types2.NewSubspace( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "test", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - types2.SubspaceTypeOpen, - time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), - ) - - err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) - suite.Require().NoError(err) - - err = suite.k.BanUserInSubspace(ctx, subspace.ID, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", subspace.Owner) - suite.Require().NoError(err) - }, - msg: types2.NewMsgUnbanUser( - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", - "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - ), - expErr: false, - expEvents: sdk.Events{ - sdk.NewEvent( - types2.EventTypeUnbanUser, - sdk.NewAttribute(types2.AttributeKeySubspaceID, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), - sdk.NewAttribute(types2.AttributeKeyUnbannedUser, "cosmos1mtanzwyk5p23haky8r6n4gxu7ypv0tlx9dgnk5"), - ), - }, - expUsers: nil, - }, - } - - for _, test := range tests { - test := test - suite.Run(test.name, func() { - suite.SetupTest() - if test.store != nil { - test.store(suite.ctx) - } - - handler := keeper.NewMsgServerImpl(suite.k) - _, err := handler.UnbanUser(sdk.WrapSDKContext(suite.ctx), test.msg) - - if test.expErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(test.expEvents, suite.ctx.EventManager().Events()) - } - - var users []string - suite.k.IterateSubspaceBannedUsers(suite.ctx, test.msg.SubspaceID, func(index int64, user string) (stop bool) { - users = append(users, user) - return false - }) - suite.Require().Equal(test.expUsers, users) - }) - } -} diff --git a/x/subspaces/keeper/permissions.go b/x/subspaces/keeper/permissions.go index 12cd439c4e..2dd9839c33 100644 --- a/x/subspaces/keeper/permissions.go +++ b/x/subspaces/keeper/permissions.go @@ -29,6 +29,12 @@ func (k Keeper) GetGroupsInheritedPermissions(ctx sdk.Context, subspaceID uint64 // HasPermission checks whether the specific target has the given permission inside a specific subspace func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, target string, permission types.Permission) (bool, error) { + // Get the subspace to make sure the request is valid + subspace, found := k.GetSubspace(ctx, subspaceID) + if !found { + return false, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d does not exist", subspaceID) + } + specificPermissions := k.GetPermissions(ctx, subspaceID, target) userAddr, err := sdk.AccAddressFromBech32(target) @@ -36,12 +42,6 @@ func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, target string, return types.CheckPermission(specificPermissions, permission), nil } - // Get the subspace to check the ownership - subspace, found := k.GetSubspace(ctx, subspaceID) - if !found { - return false, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d does not exist", subspaceID) - } - // The owner of the subspaces has all the permissions by default if subspace.Owner == userAddr.String() { return true, nil diff --git a/x/subspaces/keeper/permissions_test.go b/x/subspaces/keeper/permissions_test.go new file mode 100644 index 0000000000..7c38a4bc04 --- /dev/null +++ b/x/subspaces/keeper/permissions_test.go @@ -0,0 +1,342 @@ +package keeper_test + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +func (suite *KeeperTestsuite) TestGetPermissions() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + target string + expPermissions types.Permission + }{ + { + name: "not found target returns PermissionNothing", + subspaceID: 1, + target: "", + expPermissions: types.PermissionNothing, + }, + { + name: "found user returns the correct permission", + store: func(ctx sdk.Context) { + suite.k.SetPermissions( + ctx, + 1, + "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + types.PermissionWrite|types.PermissionAddLink, + ) + }, + subspaceID: 1, + target: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + expPermissions: types.PermissionWrite | types.PermissionAddLink, + }, + { + name: "found group returns the correct permission", + store: func(ctx sdk.Context) { + suite.k.SetPermissions( + ctx, 1, "my_group", types.PermissionChangeInfo|types.PermissionSetPermissions) + }, + subspaceID: 1, + target: "my_group", + expPermissions: types.PermissionChangeInfo | types.PermissionSetPermissions, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + permission := suite.k.GetPermissions(ctx, tc.subspaceID, tc.target) + suite.Require().Equal(tc.expPermissions, permission) + }) + } +} + +func (suite *KeeperTestsuite) TestGetGroupsInheritedPermissions() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + user string + expPermissions types.Permission + }{ + { + name: "user in no group returns PermissionNothing", + subspaceID: 1, + user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + expPermissions: types.PermissionNothing, + }, + { + name: "user inside one group returns that group's permission", + store: func(ctx sdk.Context) { + suite.k.SaveUserGroup(ctx, 1, "write-group", types.PermissionWrite) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm") + suite.Require().NoError(err) + err = suite.k.AddUserToGroup(ctx, 1, "write-group", userAddr) + suite.Require().NoError(err) + }, + subspaceID: 1, + user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + expPermissions: types.PermissionWrite, + }, + { + name: "user inside multiple groups returns the combination of the various permissions", + store: func(ctx sdk.Context) { + suite.k.SaveUserGroup(ctx, 1, + "write-group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, 1, + "permission-group", types.PermissionSetPermissions|types.PermissionChangeInfo) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, "write-group", userAddr) + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, "permission-group", userAddr) + suite.Require().NoError(err) + }, + subspaceID: 1, + user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + expPermissions: types.PermissionWrite | types.PermissionChangeInfo | types.PermissionSetPermissions, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + userAddr, err := sdk.AccAddressFromBech32(tc.user) + suite.Require().NoError(err) + + permissions := suite.k.GetGroupsInheritedPermissions(ctx, tc.subspaceID, userAddr) + suite.Require().Equal(tc.expPermissions, permissions) + }) + } +} + +func (suite *KeeperTestsuite) TestHasPermission() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + target string + permission types.Permission + expError bool + expResult bool + }{ + { + name: "subspace not found returns error", + subspaceID: 1, + expError: true, + }, + { + name: "group with permission returns true", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SetPermissions(ctx, 1, "group", types.PermissionWrite) + }, + subspaceID: 1, + target: "group", + permission: types.PermissionWrite, + expError: false, + expResult: true, + }, + { + name: "group without permission returns false", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + subspaceID: 1, + target: "group", + permission: types.PermissionWrite, + expError: false, + expResult: false, + }, + { + name: "subspace owner returns always true", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + subspaceID: 1, + target: "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + permission: types.PermissionEverything, + expError: false, + expResult: true, + }, + { + name: "user with inherited permission returns true", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite|types.PermissionChangeInfo) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + suite.Require().NoError(err) + }, + subspaceID: 1, + target: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", + permission: types.PermissionWrite, + expError: false, + expResult: true, + }, + { + name: "user with custom permission returns true", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite|types.PermissionChangeInfo) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + suite.Require().NoError(err) + + suite.k.SetPermissions(ctx, 1, userAddr.String(), types.PermissionAddLink) + }, + subspaceID: 1, + target: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", + permission: types.PermissionAddLink, + expError: false, + expResult: true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + result, err := suite.k.HasPermission(ctx, tc.subspaceID, tc.target, tc.permission) + if tc.expError { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expResult, result) + } + }) + } +} + +func (suite *KeeperTestsuite) TestSetPermissions() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + target string + permission types.Permission + check func(ctx sdk.Context) + }{ + { + name: "permission is set properly for group", + subspaceID: 1, + target: "group", + permission: types.PermissionWrite, + check: func(ctx sdk.Context) { + permission := suite.k.GetPermissions(ctx, 1, "group") + suite.Require().Equal(types.PermissionWrite, permission) + }, + }, + { + name: "permission is set properly for user", + subspaceID: 1, + target: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", + permission: types.PermissionChangeInfo, + check: func(ctx sdk.Context) { + permission := suite.k.GetPermissions(ctx, 1, "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") + suite.Require().Equal(types.PermissionChangeInfo, permission) + }, + }, + { + name: "existing permission is overridden", + store: func(ctx sdk.Context) { + suite.k.SetPermissions(ctx, 1, "group", types.PermissionAddLink) + }, + subspaceID: 1, + target: "group", + permission: types.PermissionWrite, + check: func(ctx sdk.Context) { + permission := suite.k.GetPermissions(ctx, 1, "group") + suite.Require().Equal(types.PermissionWrite, permission) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + suite.k.SetPermissions(ctx, tc.subspaceID, tc.target, tc.permission) + + if tc.check != nil { + tc.check(ctx) + } + }) + } +} diff --git a/x/subspaces/keeper/subspaces.go b/x/subspaces/keeper/subspaces.go index 82492d3c50..6e607ad3c8 100644 --- a/x/subspaces/keeper/subspaces.go +++ b/x/subspaces/keeper/subspaces.go @@ -26,13 +26,11 @@ func (k Keeper) SetSubspaceID(ctx sdk.Context, subspaceID uint64) { } // SaveSubspace saves the given subspace inside the current context. -func (k Keeper) SaveSubspace(ctx sdk.Context, subspace types.Subspace) error { +func (k Keeper) SaveSubspace(ctx sdk.Context, subspace types.Subspace) { store := ctx.KVStore(k.storeKey) store.Set(types.SubspaceKey(subspace.ID), k.cdc.MustMarshal(&subspace)) k.Logger(ctx).Info("subspace saved", "id", subspace.ID) - - return nil } // GetSubspace returns the subspace associated with the given id. diff --git a/x/subspaces/keeper/subspaces_test.go b/x/subspaces/keeper/subspaces_test.go new file mode 100644 index 0000000000..2750c7245e --- /dev/null +++ b/x/subspaces/keeper/subspaces_test.go @@ -0,0 +1,231 @@ +package keeper_test + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +func (suite *KeeperTestsuite) TestGetSubspaceID() { + testCases := []struct { + name string + store func(ctx sdk.Context) + shouldErr bool + expID uint64 + }{ + { + name: "initial subspace not set", + shouldErr: true, + }, + { + name: "subspace id set", + store: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + store.Set(types.SubspaceIDKey, types.GetSubspaceIDBytes(1)) + }, + shouldErr: false, + expID: 1, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + id, err := suite.k.GetSubspaceID(ctx) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expID, id) + } + }) + } +} + +func (suite *KeeperTestsuite) TestSetSubspaceID() { + testCases := []struct { + name string + id uint64 + check func(ctx sdk.Context) + }{ + { + name: "zero subspace id", + id: 0, + check: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + suite.Require().Equal(uint64(0), types.GetSubspaceIDFromBytes(store.Get(types.SubspaceIDKey))) + }, + }, + { + name: "non-zero subspace id", + id: 5, + check: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + suite.Require().Equal(uint64(5), types.GetSubspaceIDFromBytes(store.Get(types.SubspaceIDKey))) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + + suite.k.SetSubspaceID(ctx, tc.id) + if tc.check != nil { + tc.check(ctx) + } + }) + } +} + +func (suite *KeeperTestsuite) TestSaveSubspace() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspace types.Subspace + check func(ctx sdk.Context) + }{ + { + name: "non existing subspace is stored properly", + subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + check: func(ctx sdk.Context) { + subspace, found := suite.k.GetSubspace(ctx, 1) + suite.Require().True(found) + suite.Require().Equal(types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), subspace) + }, + }, + { + name: "existing subspace is replaced correctly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + subspace: types.NewSubspace( + 1, + "Test subspace with another name and owner", + "This is a test subspace with a changed description", + "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + check: func(ctx sdk.Context) { + subspace, found := suite.k.GetSubspace(ctx, 1) + suite.Require().True(found) + suite.Require().Equal(types.NewSubspace( + 1, + "Test subspace with another name and owner", + "This is a test subspace with a changed description", + "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), subspace) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + suite.k.SaveSubspace(ctx, tc.subspace) + + if tc.check != nil { + tc.check(ctx) + } + }) + } +} + +func (suite *KeeperTestsuite) TestGetSubspace() { + testCases := []struct { + name string + store func(ctx sdk.Context) + id uint64 + expSubspace types.Subspace + expFound bool + }{ + { + name: "not found subspace returns false", + id: 1, + expFound: false, + }, + { + name: "found subspace returns the correct data", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + id: 1, + expFound: true, + expSubspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + subspace, found := suite.k.GetSubspace(ctx, tc.id) + suite.Require().Equal(tc.expFound, found) + if tc.expFound { + suite.Require().Equal(tc.expSubspace, subspace) + } + }) + } +} diff --git a/x/subspaces/types/keys.go b/x/subspaces/types/keys.go index 21583cc317..f781503e18 100644 --- a/x/subspaces/types/keys.go +++ b/x/subspaces/types/keys.go @@ -47,22 +47,27 @@ func SubspaceKey(subspaceID uint64) []byte { return append(SubspacePrefix, GetSubspaceIDBytes(subspaceID)...) } +// ACLStoreKey returns the key used to store the entire ACL for a given subspace func ACLStoreKey(subspaceID uint64) []byte { return append(ACLStorePrefix, GetSubspaceIDBytes(subspaceID)...) } +// PermissionStoreKey returns the key used to store the permission for the given target inside the given subspace func PermissionStoreKey(subspaceID uint64, target string) []byte { return append(ACLStoreKey(subspaceID), []byte(target)...) } +// GroupsStoreKey returns the key used to store all the groups of a given subspace func GroupsStoreKey(subspaceID uint64) []byte { return append(GroupsPrefix, GetSubspaceIDBytes(subspaceID)...) } +// GetGroupNameBytes returns the key byte representation of the groupName func GetGroupNameBytes(groupName string) []byte { return []byte(groupName) } +// GetGroupNameFromBytes returns groupName in string format from a byte array func GetGroupNameFromBytes(bz []byte) string { return string(bz) } @@ -72,10 +77,23 @@ func GroupStoreKey(subspaceID uint64, groupName string) []byte { return append(GroupsStoreKey(subspaceID), GetGroupNameBytes(groupName)...) } +// GroupMembersStoreKey returns the key used to store all the members of the given group inside the given subspace func GroupMembersStoreKey(subspaceID uint64, groupName string) []byte { return append(append(GroupMembersStorePrefix, GetSubspaceIDBytes(subspaceID)...), GetGroupNameBytes(groupName)...) } +// GetGroupMemberBytes returns the key byte representation of the member +func GetGroupMemberBytes(member string) []byte { + return []byte(member) +} + +// GetGroupMemberFromBytes returns member in string format from a byte array +func GetGroupMemberFromBytes(bz []byte) string { + return string(bz) +} + +// GroupMemberStoreKey returns the key used to store the membership of the given user to the +// specified group inside the provided subspace func GroupMemberStoreKey(subspaceID uint64, groupName string, user string) []byte { - return append(GroupStoreKey(subspaceID, groupName), []byte(user)...) + return append(GroupStoreKey(subspaceID, groupName), GetGroupMemberBytes(user)...) } diff --git a/x/subspaces/types/query.pb.go b/x/subspaces/types/query.pb.go index d040a92635..5c37b815e5 100644 --- a/x/subspaces/types/query.pb.go +++ b/x/subspaces/types/query.pb.go @@ -480,7 +480,7 @@ var xxx_messageInfo_QueryPermissionsRequest proto.InternalMessageInfo // QuerySubspaceResponse is the response type for the Query/Subspace method type QueryPermissionsResponse struct { - Permissions []byte `protobuf:"bytes,1,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` + Permissions uint32 `protobuf:"varint,1,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` } func (m *QueryPermissionsResponse) Reset() { *m = QueryPermissionsResponse{} } @@ -516,11 +516,11 @@ func (m *QueryPermissionsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryPermissionsResponse proto.InternalMessageInfo -func (m *QueryPermissionsResponse) GetPermissions() []byte { +func (m *QueryPermissionsResponse) GetPermissions() uint32 { if m != nil { return m.Permissions } - return nil + return 0 } func init() { @@ -541,52 +541,52 @@ func init() { proto.RegisterFile("desmos/subspaces/v1/query.proto", fileDescript var fileDescriptor_883a12b013a133fc = []byte{ // 741 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0x4f, 0x4f, 0x13, 0x4f, - 0x18, 0xc7, 0x3b, 0xc0, 0xaf, 0x3f, 0xfa, 0x54, 0x13, 0x19, 0x01, 0x9b, 0x0d, 0xec, 0x92, 0x8d, - 0x41, 0x01, 0xd9, 0x49, 0xab, 0x09, 0xca, 0x41, 0xb4, 0x07, 0x88, 0x89, 0x1a, 0x5c, 0x35, 0x51, - 0x2f, 0x64, 0x17, 0x26, 0x6b, 0x13, 0xb6, 0xbb, 0xec, 0x6c, 0x1b, 0x91, 0x70, 0xe1, 0xa2, 0x07, - 0x4d, 0x4c, 0x3c, 0xe9, 0x89, 0x83, 0x37, 0xcf, 0xbe, 0x00, 0x6f, 0x1c, 0x49, 0x8c, 0x89, 0xa7, - 0xc6, 0x80, 0x07, 0xcf, 0xbc, 0x02, 0xd3, 0xd9, 0x99, 0x76, 0xfb, 0x47, 0x58, 0x81, 0x5b, 0x67, - 0xe6, 0xfb, 0x3c, 0xcf, 0x67, 0xbe, 0xd3, 0xe7, 0x69, 0x41, 0x5b, 0xa1, 0xcc, 0xf5, 0x18, 0x61, - 0x15, 0x9b, 0xf9, 0xd6, 0x32, 0x65, 0xa4, 0x9a, 0x27, 0x6b, 0x15, 0x1a, 0xac, 0x1b, 0x7e, 0xe0, - 0x85, 0x1e, 0x3e, 0x1f, 0x09, 0x8c, 0x86, 0xc0, 0xa8, 0xe6, 0x95, 0x41, 0xc7, 0x73, 0x3c, 0x7e, - 0x4e, 0xea, 0x9f, 0x22, 0xa9, 0x32, 0xe2, 0x78, 0x9e, 0xb3, 0x4a, 0x89, 0xe5, 0x97, 0x88, 0x55, - 0x2e, 0x7b, 0xa1, 0x15, 0x96, 0xbc, 0x32, 0x13, 0xa7, 0x7a, 0xb7, 0x4a, 0x72, 0x21, 0x34, 0x93, - 0xcb, 0x1e, 0xd7, 0xd8, 0x16, 0xa3, 0x11, 0x05, 0xa9, 0xe6, 0x6d, 0x1a, 0x5a, 0x79, 0xe2, 0x5b, - 0x4e, 0xa9, 0xcc, 0x13, 0x46, 0x5a, 0xfd, 0x29, 0x0c, 0x3e, 0xa8, 0x2b, 0x1e, 0x8a, 0x14, 0x26, - 0x5d, 0xab, 0x50, 0x16, 0xe2, 0x19, 0xc8, 0xca, 0xac, 0x4b, 0xa5, 0x95, 0x1c, 0x1a, 0x43, 0x97, - 0xfb, 0x8a, 0xc3, 0x07, 0x35, 0x0d, 0xaf, 0x5b, 0xee, 0xea, 0xac, 0x1e, 0x3b, 0xd4, 0x4d, 0x90, - 0xab, 0x3b, 0x2b, 0xb3, 0xfd, 0xaf, 0xb7, 0xb5, 0xd4, 0xef, 0x6d, 0x2d, 0xa5, 0x3f, 0x81, 0xa1, - 0xb6, 0xd4, 0xcc, 0xf7, 0xca, 0x8c, 0xe2, 0x39, 0xe8, 0x97, 0x01, 0x3c, 0x71, 0xb6, 0x30, 0x6a, - 0x74, 0xf1, 0xc7, 0x90, 0x81, 0xc5, 0xbe, 0x9d, 0x9a, 0x96, 0x32, 0x1b, 0x41, 0xfa, 0x52, 0x5b, - 0x66, 0x26, 0xa9, 0xe7, 0x01, 0x9a, 0x37, 0x14, 0xb9, 0xc7, 0x8d, 0xc8, 0x0e, 0xa3, 0x6e, 0x87, - 0x11, 0x3d, 0x8a, 0xb0, 0xc3, 0x58, 0xb4, 0x1c, 0x79, 0x63, 0x33, 0x16, 0xa9, 0x7f, 0x42, 0x30, - 0xdc, 0x5e, 0x41, 0xc0, 0xdf, 0x86, 0x4c, 0x03, 0x32, 0x87, 0xc6, 0x7a, 0x93, 0xd2, 0x37, 0xa3, - 0xf0, 0x42, 0x0b, 0x65, 0x0f, 0xa7, 0xbc, 0x74, 0x24, 0x65, 0x54, 0xbf, 0x05, 0xf3, 0x83, 0xc4, - 0x7c, 0xcc, 0x68, 0xb0, 0x10, 0x78, 0x15, 0x9f, 0x9d, 0xf4, 0xfd, 0xda, 0x2c, 0xec, 0x39, 0xb6, - 0x85, 0x2f, 0xe1, 0x42, 0x07, 0x9a, 0xb0, 0x70, 0x18, 0xd2, 0x0e, 0xdf, 0xe1, 0xfe, 0x65, 0x4c, - 0xb1, 0x3a, 0x3d, 0x5f, 0xbe, 0x23, 0x18, 0x69, 0x2d, 0x7e, 0x8f, 0xba, 0x36, 0x0d, 0x4e, 0xee, - 0xce, 0x35, 0x00, 0x0e, 0xbb, 0x54, 0xb6, 0x5c, 0xca, 0x11, 0x33, 0xc5, 0xa1, 0x83, 0x9a, 0x36, - 0x10, 0xc5, 0x35, 0xcf, 0x74, 0x33, 0xc3, 0x17, 0xf7, 0x2d, 0x97, 0xb6, 0x79, 0xda, 0x7b, 0x6c, - 0x4f, 0xb7, 0x10, 0x8c, 0xfe, 0xe5, 0x5e, 0xc2, 0xda, 0x1c, 0xfc, 0xef, 0x46, 0x5b, 0xc2, 0x5b, - 0xb9, 0x3c, 0x3d, 0x73, 0x5f, 0x21, 0xf1, 0xb2, 0x8b, 0x34, 0x70, 0x4b, 0x8c, 0xd5, 0x87, 0xd3, - 0x89, 0x7d, 0x9d, 0x80, 0x74, 0x68, 0x05, 0x0e, 0x0d, 0x85, 0xa7, 0x03, 0x07, 0x35, 0xed, 0x6c, + 0x18, 0xc7, 0x3b, 0xc0, 0xaf, 0x3f, 0xfa, 0x34, 0x24, 0x32, 0x02, 0x36, 0x1b, 0xd8, 0x25, 0x1b, + 0x83, 0x02, 0xb2, 0x93, 0x56, 0x13, 0x94, 0x83, 0x68, 0x0f, 0x10, 0x13, 0x35, 0xb8, 0x6a, 0xa2, + 0x5e, 0xc8, 0x2e, 0x4c, 0xd6, 0x26, 0x6c, 0x77, 0xd9, 0xd9, 0x36, 0x22, 0xe1, 0xc2, 0x45, 0x0f, + 0x9a, 0x98, 0x78, 0xd2, 0x13, 0x07, 0x6f, 0x9e, 0x7d, 0x01, 0xde, 0x38, 0x92, 0x18, 0x13, 0x4f, + 0x8d, 0x01, 0x0f, 0x9e, 0x79, 0x05, 0xa6, 0xb3, 0x33, 0xed, 0xf6, 0x8f, 0xb0, 0x02, 0xb7, 0xce, + 0xcc, 0xf7, 0x79, 0x9e, 0xcf, 0x7c, 0xa7, 0xcf, 0xd3, 0x82, 0xb6, 0x4a, 0x99, 0xeb, 0x31, 0xc2, + 0x2a, 0x36, 0xf3, 0xad, 0x15, 0xca, 0x48, 0x35, 0x4f, 0xd6, 0x2b, 0x34, 0xd8, 0x30, 0xfc, 0xc0, + 0x0b, 0x3d, 0x7c, 0x3e, 0x12, 0x18, 0x0d, 0x81, 0x51, 0xcd, 0x2b, 0x43, 0x8e, 0xe7, 0x78, 0xfc, + 0x9c, 0xd4, 0x3f, 0x45, 0x52, 0x65, 0xd4, 0xf1, 0x3c, 0x67, 0x8d, 0x12, 0xcb, 0x2f, 0x11, 0xab, + 0x5c, 0xf6, 0x42, 0x2b, 0x2c, 0x79, 0x65, 0x26, 0x4e, 0xf5, 0x6e, 0x95, 0xe4, 0x42, 0x68, 0xa6, + 0x56, 0x3c, 0xae, 0xb1, 0x2d, 0x46, 0x23, 0x0a, 0x52, 0xcd, 0xdb, 0x34, 0xb4, 0xf2, 0xc4, 0xb7, + 0x9c, 0x52, 0x99, 0x27, 0x8c, 0xb4, 0xfa, 0x53, 0x18, 0x7a, 0x50, 0x57, 0x3c, 0x14, 0x29, 0x4c, + 0xba, 0x5e, 0xa1, 0x2c, 0xc4, 0xb3, 0x90, 0x95, 0x59, 0x97, 0x4b, 0xab, 0x39, 0x34, 0x8e, 0x2e, + 0xf7, 0x15, 0x47, 0x0e, 0x6b, 0x1a, 0xde, 0xb0, 0xdc, 0xb5, 0x39, 0x3d, 0x76, 0xa8, 0x9b, 0x20, + 0x57, 0x77, 0x56, 0xe7, 0xfa, 0x5f, 0xef, 0x68, 0xa9, 0xdf, 0x3b, 0x5a, 0x4a, 0x7f, 0x02, 0xc3, + 0x6d, 0xa9, 0x99, 0xef, 0x95, 0x19, 0xc5, 0xf3, 0xd0, 0x2f, 0x03, 0x78, 0xe2, 0x6c, 0x61, 0xcc, + 0xe8, 0xe2, 0x8f, 0x21, 0x03, 0x8b, 0x7d, 0xbb, 0x35, 0x2d, 0x65, 0x36, 0x82, 0xf4, 0xe5, 0xb6, + 0xcc, 0x4c, 0x52, 0x2f, 0x00, 0x34, 0x6f, 0x28, 0x72, 0x4f, 0x18, 0x91, 0x1d, 0x46, 0xdd, 0x0e, + 0x23, 0x7a, 0x14, 0x61, 0x87, 0xb1, 0x64, 0x39, 0xf2, 0xc6, 0x66, 0x2c, 0x52, 0xff, 0x84, 0x60, + 0xa4, 0xbd, 0x82, 0x80, 0xbf, 0x0d, 0x99, 0x06, 0x64, 0x0e, 0x8d, 0xf7, 0x26, 0xa5, 0x6f, 0x46, + 0xe1, 0xc5, 0x16, 0xca, 0x1e, 0x4e, 0x79, 0xe9, 0x58, 0xca, 0xa8, 0x7e, 0x0b, 0xe6, 0x07, 0x89, + 0xf9, 0x98, 0xd1, 0x60, 0x31, 0xf0, 0x2a, 0x3e, 0x3b, 0xed, 0xfb, 0xb5, 0x59, 0xd8, 0x73, 0x62, + 0x0b, 0x5f, 0xc2, 0x85, 0x0e, 0x34, 0x61, 0xe1, 0x08, 0xa4, 0x1d, 0xbe, 0xc3, 0xfd, 0xcb, 0x98, + 0x62, 0x75, 0x76, 0xbe, 0x7c, 0x47, 0x30, 0xda, 0x5a, 0xfc, 0x1e, 0x75, 0x6d, 0x1a, 0x9c, 0xde, + 0x9d, 0x6b, 0x00, 0x1c, 0x76, 0xb9, 0x6c, 0xb9, 0x94, 0x23, 0x66, 0x8a, 0xc3, 0x87, 0x35, 0x6d, + 0x30, 0x8a, 0x6b, 0x9e, 0xe9, 0x66, 0x86, 0x2f, 0xee, 0x5b, 0x2e, 0x6d, 0xf3, 0xb4, 0xf7, 0xc4, + 0x9e, 0x6e, 0x23, 0x18, 0xfb, 0xcb, 0xbd, 0x84, 0xb5, 0x39, 0xf8, 0xdf, 0x8d, 0xb6, 0x84, 0xb7, + 0x72, 0x79, 0x76, 0xe6, 0xbe, 0x42, 0xe2, 0x65, 0x97, 0x68, 0xe0, 0x96, 0x18, 0xab, 0x0f, 0xa7, + 0x53, 0xfb, 0x3a, 0x09, 0xe9, 0xd0, 0x0a, 0x1c, 0x1a, 0x0a, 0x4f, 0x07, 0x0f, 0x6b, 0xda, 0x40, 0x14, 0x13, 0xed, 0xeb, 0xa6, 0x10, 0xc4, 0x06, 0xcc, 0x23, 0xc8, 0x75, 0x82, 0x08, 0x23, 0xae, - 0x43, 0xd6, 0x6f, 0x6e, 0x73, 0x92, 0x33, 0x71, 0x92, 0xd8, 0xa1, 0x6e, 0xc6, 0xa5, 0x85, 0x2f, - 0x69, 0xf8, 0x8f, 0xa7, 0xc5, 0x6f, 0x11, 0xf4, 0xcb, 0x2e, 0xc6, 0x13, 0x5d, 0x9b, 0xbc, 0xdb, - 0xec, 0x54, 0x26, 0x93, 0x48, 0x23, 0x4e, 0x7d, 0x72, 0xeb, 0xdb, 0xaf, 0xf7, 0x3d, 0x17, 0xb1, - 0x4e, 0xba, 0x0d, 0xf6, 0x8d, 0x98, 0x61, 0x9b, 0xf8, 0x0d, 0x82, 0x4c, 0x63, 0x20, 0xe1, 0x04, - 0x55, 0xe4, 0xbb, 0x28, 0x53, 0x89, 0xb4, 0x02, 0x69, 0x9c, 0x23, 0x8d, 0x61, 0x95, 0x1c, 0xf6, - 0x5b, 0xc3, 0xf0, 0x47, 0x04, 0xd0, 0xec, 0x6e, 0x7c, 0x48, 0x8d, 0x8e, 0xf1, 0xa4, 0x5c, 0x49, - 0x26, 0x16, 0x44, 0x79, 0x4e, 0x34, 0x85, 0x27, 0x8e, 0x36, 0x89, 0x88, 0x59, 0xf2, 0x15, 0xc1, - 0xb9, 0xf6, 0x2e, 0xc1, 0xf9, 0x04, 0x55, 0x5b, 0x27, 0x85, 0x52, 0xf8, 0x97, 0x10, 0x81, 0x3b, - 0xcf, 0x71, 0x6f, 0xe1, 0x9b, 0x89, 0x71, 0xc9, 0x46, 0x73, 0x72, 0x6c, 0x12, 0xd9, 0xb2, 0x9f, - 0x11, 0x64, 0x63, 0xdf, 0x6d, 0x7c, 0x88, 0x69, 0x9d, 0xbd, 0xa8, 0x4c, 0x27, 0x54, 0x0b, 0xe8, - 0x39, 0x0e, 0x7d, 0x03, 0xcf, 0x24, 0x80, 0x8e, 0xb5, 0x0b, 0xd9, 0x88, 0xda, 0x72, 0xb3, 0x78, - 0x77, 0x67, 0x4f, 0x45, 0xbb, 0x7b, 0x2a, 0xfa, 0xb9, 0xa7, 0xa2, 0x77, 0xfb, 0x6a, 0x6a, 0x77, - 0x5f, 0x4d, 0xfd, 0xd8, 0x57, 0x53, 0xcf, 0x0a, 0x4e, 0x29, 0x7c, 0x5e, 0xb1, 0x8d, 0x65, 0xcf, - 0x15, 0xc9, 0xa7, 0x57, 0x2d, 0x9b, 0xc9, 0x42, 0xd5, 0x02, 0x79, 0x11, 0xab, 0x16, 0xae, 0xfb, - 0x94, 0xd9, 0x69, 0xfe, 0xf7, 0xe4, 0xea, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x75, 0x05, 0x78, - 0xdc, 0x5a, 0x09, 0x00, 0x00, + 0x43, 0xd6, 0x6f, 0x6e, 0x73, 0x92, 0x81, 0x38, 0x49, 0xec, 0x50, 0x37, 0xe3, 0xd2, 0xc2, 0x97, + 0x34, 0xfc, 0xc7, 0xd3, 0xe2, 0xb7, 0x08, 0xfa, 0x65, 0x17, 0xe3, 0xc9, 0xae, 0x4d, 0xde, 0x6d, + 0x76, 0x2a, 0x53, 0x49, 0xa4, 0x11, 0xa7, 0x3e, 0xb5, 0xfd, 0xed, 0xd7, 0xfb, 0x9e, 0x8b, 0x58, + 0x27, 0xdd, 0x06, 0xfb, 0x66, 0xcc, 0xb0, 0x2d, 0xfc, 0x06, 0x41, 0xa6, 0x31, 0x90, 0x70, 0x82, + 0x2a, 0xf2, 0x5d, 0x94, 0xe9, 0x44, 0x5a, 0x81, 0x34, 0xc1, 0x91, 0xc6, 0xb1, 0x4a, 0x8e, 0xfa, + 0xad, 0x61, 0xf8, 0x23, 0x02, 0x68, 0x76, 0x37, 0x3e, 0xa2, 0x46, 0xc7, 0x78, 0x52, 0xae, 0x24, + 0x13, 0x0b, 0xa2, 0x3c, 0x27, 0x9a, 0xc6, 0x93, 0xc7, 0x9b, 0x44, 0xc4, 0x2c, 0xf9, 0x8a, 0xe0, + 0x5c, 0x7b, 0x97, 0xe0, 0x7c, 0x82, 0xaa, 0xad, 0x93, 0x42, 0x29, 0xfc, 0x4b, 0x88, 0xc0, 0x5d, + 0xe0, 0xb8, 0xb7, 0xf0, 0xcd, 0xc4, 0xb8, 0x64, 0xb3, 0x39, 0x39, 0xb6, 0x88, 0x6c, 0xd9, 0xcf, + 0x08, 0xb2, 0xb1, 0xef, 0x36, 0x3e, 0xc2, 0xb4, 0xce, 0x5e, 0x54, 0x66, 0x12, 0xaa, 0x05, 0xf4, + 0x3c, 0x87, 0xbe, 0x81, 0x67, 0x13, 0x40, 0xc7, 0xda, 0x85, 0x6c, 0x46, 0x6d, 0xb9, 0x55, 0xbc, + 0xbb, 0xbb, 0xaf, 0xa2, 0xbd, 0x7d, 0x15, 0xfd, 0xdc, 0x57, 0xd1, 0xbb, 0x03, 0x35, 0xb5, 0x77, + 0xa0, 0xa6, 0x7e, 0x1c, 0xa8, 0xa9, 0x67, 0x05, 0xa7, 0x14, 0x3e, 0xaf, 0xd8, 0xc6, 0x8a, 0xe7, + 0x8a, 0xe4, 0x33, 0x6b, 0x96, 0xcd, 0x64, 0xa1, 0x6a, 0x81, 0xbc, 0x88, 0x55, 0x0b, 0x37, 0x7c, + 0xca, 0xec, 0x34, 0xff, 0x7b, 0x72, 0xf5, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0x77, 0xad, + 0x4c, 0x5a, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1202,12 +1202,10 @@ func (m *QueryPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error _ = i var l int _ = l - if len(m.Permissions) > 0 { - i -= len(m.Permissions) - copy(dAtA[i:], m.Permissions) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Permissions))) + if m.Permissions != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Permissions)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x8 } return len(dAtA) - i, nil } @@ -1374,9 +1372,8 @@ func (m *QueryPermissionsResponse) Size() (n int) { } var l int _ = l - l = len(m.Permissions) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if m.Permissions != 0 { + n += 1 + sovQuery(uint64(m.Permissions)) } return n } @@ -2354,10 +2351,10 @@ func (m *QueryPermissionsResponse) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) } - var byteLen int + m.Permissions = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2367,26 +2364,11 @@ func (m *QueryPermissionsResponse) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + m.Permissions |= uint32(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Permissions = append(m.Permissions[:0], dAtA[iNdEx:postIndex]...) - if m.Permissions == nil { - m.Permissions = []byte{} - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) From e08f3b35e5145105fc01273b8f72ad817635094f Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Fri, 21 Jan 2022 09:20:28 +0100 Subject: [PATCH 07/47] completed the keeper package tests Signed-off-by: Riccardo Montagnin --- proto/desmos/subspaces/v1/genesis.proto | 12 +- proto/desmos/subspaces/v1/msgs.proto | 8 +- proto/desmos/subspaces/v1/subspace.proto | 12 +- x/profiles/types/models_relationships.go | 1 + x/subspaces/handler.go | 37 +- x/subspaces/keeper/alias_functions.go | 50 +- x/subspaces/keeper/genesis.go | 157 ++-- x/subspaces/keeper/genesis_test.go | 305 +++++++ x/subspaces/keeper/groups.go | 34 +- x/subspaces/keeper/groups_test.go | 391 ++++++++ x/subspaces/keeper/grpc_query.go | 23 +- x/subspaces/keeper/grpc_query_test.go | 707 ++++++++------- x/subspaces/keeper/invariants.go | 100 ++- x/subspaces/keeper/invariants_test.go | 123 ++- x/subspaces/keeper/msg_server.go | 123 +-- x/subspaces/keeper/msg_server_test.go | 1049 ++++++++++++++++++++++ x/subspaces/keeper/permissions.go | 17 +- x/subspaces/keeper/permissions_test.go | 85 +- x/subspaces/keeper/subspaces.go | 6 + x/subspaces/keeper/subspaces_test.go | 8 +- x/subspaces/module.go | 2 +- x/subspaces/types/events.go | 2 + x/subspaces/types/genesis.go | 20 + x/subspaces/types/genesis.pb.go | 235 +++-- x/subspaces/types/keys.go | 58 +- x/subspaces/types/msgs.go | 8 +- x/subspaces/types/msgs.pb.go | 163 ++-- x/subspaces/types/permissions.go | 8 +- x/subspaces/types/permissions_test.go | 10 +- x/subspaces/types/query.go | 27 + x/subspaces/types/subspace.go | 20 +- x/subspaces/types/subspace.pb.go | 98 +- 32 files changed, 2958 insertions(+), 941 deletions(-) create mode 100644 x/subspaces/keeper/genesis_test.go create mode 100644 x/subspaces/keeper/groups_test.go create mode 100644 x/subspaces/keeper/msg_server_test.go diff --git a/proto/desmos/subspaces/v1/genesis.proto b/proto/desmos/subspaces/v1/genesis.proto index 5abdb35a64..0c78bc1ca9 100644 --- a/proto/desmos/subspaces/v1/genesis.proto +++ b/proto/desmos/subspaces/v1/genesis.proto @@ -8,6 +8,9 @@ option go_package = "github.com/desmos-labs/desmos/v2/x/subspaces/types"; // GenesisState contains the data of the genesis state for the subspaces module message GenesisState { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + repeated desmos.subspaces.v1.Subspace subspaces = 1 [ (gogoproto.nullable) = false ]; @@ -19,10 +22,13 @@ message GenesisState { // ACL represents a single Access Control List entry message ACLEntry { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + // Either group name or user address uint64 subspace_id = 1; string target = 2; - bytes permissions = 3; + uint32 permissions = 3; } // UsersEntry contains the data of a slice of users associated to a subspace @@ -31,7 +37,7 @@ message UserGroup { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = true; - string subspace_id = 1 [ (gogoproto.customname) = "SubspaceID" ]; + uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID" ]; string name = 2; - repeated string users = 3; + repeated string members = 3; } \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/msgs.proto b/proto/desmos/subspaces/v1/msgs.proto index d995609585..3a24fe0390 100644 --- a/proto/desmos/subspaces/v1/msgs.proto +++ b/proto/desmos/subspaces/v1/msgs.proto @@ -43,8 +43,8 @@ message MsgCreateSubspace { string name = 1 [ (gogoproto.moretags) = "yaml:\"name\"" ]; string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; - string owner = 3 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; - string treasury = 4 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; + string treasury = 3 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; + string owner = 4 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; string creator = 5 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; } @@ -70,8 +70,8 @@ message MsgEditSubspace { string name = 2 [ (gogoproto.moretags) = "yaml:\"name\"" ]; string description = 3 [ (gogoproto.moretags) = "yaml:\"description\"" ]; - string owner = 4 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; - string treasury = 5 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; + string treasury = 4 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; + string owner = 5 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; string signer = 6 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; } diff --git a/proto/desmos/subspaces/v1/subspace.proto b/proto/desmos/subspaces/v1/subspace.proto index 52595f7562..024c45c0a8 100644 --- a/proto/desmos/subspaces/v1/subspace.proto +++ b/proto/desmos/subspaces/v1/subspace.proto @@ -21,15 +21,15 @@ message Subspace { // Optional description of this subspace string description = 3 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + // Represents the account that is associated with the subspace and + // should be used to connect external applications to verify this subspace + string treasury = 4 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; + // Address of the user that owns the subspace - string owner = 4 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; + string owner = 5 [ (gogoproto.moretags) = "yaml:\"owner\"" ]; // Address of the subspace creator - string creator = 5 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; - - // Represents the account that is associated with the subspace and - // should be used to connect external applications to verify this subspace - string treasury = 6 [ (gogoproto.moretags) = "yaml:\"treasury\"" ]; + string creator = 6 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; // the creation time of the subspace google.protobuf.Timestamp creation_time = 7 [ diff --git a/x/profiles/types/models_relationships.go b/x/profiles/types/models_relationships.go index 05a816ace9..d51b335d4c 100644 --- a/x/profiles/types/models_relationships.go +++ b/x/profiles/types/models_relationships.go @@ -12,6 +12,7 @@ import ( // NOTE: Currently we only support the empty subspace which identifies the generic Desmos subspace that can be used // to block users on every subspace func IsValidSubspace(subspace string) bool { + // TODO: Change with uint64 return subspace == "" } diff --git a/x/subspaces/handler.go b/x/subspaces/handler.go index fb20f6d374..a761ed3939 100644 --- a/x/subspaces/handler.go +++ b/x/subspaces/handler.go @@ -5,46 +5,43 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/gogo/protobuf/proto" - keeper2 "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" - types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) // NewHandler returns a handler for subspaces type messages -func NewHandler(k keeper2.Keeper) sdk.Handler { - msgServer := keeper2.NewMsgServerImpl(k) +func NewHandler(k keeper.Keeper) sdk.Handler { + msgServer := keeper.NewMsgServerImpl(k) return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { ctx = ctx.WithEventManager(sdk.NewEventManager()) switch msg := msg.(type) { - case *types2.MsgCreateSubspace: + case *types.MsgCreateSubspace: res, err := msgServer.CreateSubspace(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) - case *types2.MsgEditSubspace: + case *types.MsgEditSubspace: res, err := msgServer.EditSubspace(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) - case *types2.MsgAddAdmin: - res, err := msgServer.AddAdmin(sdk.WrapSDKContext(ctx), msg) + case *types.MsgCreateUserGroup: + res, err := msgServer.CreateUserGroup(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) - case *types2.MsgRemoveAdmin: - res, err := msgServer.RemoveAdmin(sdk.WrapSDKContext(ctx), msg) + case *types.MsgDeleteUserGroup: + res, err := msgServer.DeleteUserGroup(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) - case *types2.MsgRegisterUser: - res, err := msgServer.RegisterUser(sdk.WrapSDKContext(ctx), msg) + case *types.MsgAddUserToUserGroup: + res, err := msgServer.AddUserToUserGroup(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) - case *types2.MsgUnregisterUser: - res, err := msgServer.UnregisterUser(sdk.WrapSDKContext(ctx), msg) + case *types.MsgRemoveUserFromUserGroup: + res, err := msgServer.RemoveUserFromUserGroup(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) - case *types2.MsgBanUser: - res, err := msgServer.BanUser(sdk.WrapSDKContext(ctx), msg) - return sdk.WrapServiceResult(ctx, res, err) - case *types2.MsgUnbanUser: - res, err := msgServer.UnbanUser(sdk.WrapSDKContext(ctx), msg) + case *types.MsgSetPermissions: + res, err := msgServer.SetPermissions(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) default: return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, - "unrecognized %s message type: %v", types2.ModuleName, proto.MessageName(msg)) + "unrecognized %s message type: %v", types.ModuleName, proto.MessageName(msg)) } } } diff --git a/x/subspaces/keeper/alias_functions.go b/x/subspaces/keeper/alias_functions.go index 4e8f0aca3d..7881f5f083 100644 --- a/x/subspaces/keeper/alias_functions.go +++ b/x/subspaces/keeper/alias_functions.go @@ -40,7 +40,9 @@ func (k Keeper) GetAllSubspaces(ctx sdk.Context) []types.Subspace { // -------------------------------------------------------------------------------------------------------------------- // IterateSubspaceGroups allows iterating over all the groups that are part of the subspace having the given id -func (k Keeper) IterateSubspaceGroups(ctx sdk.Context, subspaceID uint64, fn func(index int64, groupName string) (stop bool)) { +func (k Keeper) IterateSubspaceGroups( + ctx sdk.Context, subspaceID uint64, fn func(index int64, groupName string) (stop bool), +) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, types.GroupsStoreKey(subspaceID)) defer iterator.Close() @@ -55,3 +57,49 @@ func (k Keeper) IterateSubspaceGroups(ctx sdk.Context, subspaceID uint64, fn fun i++ } } + +// IterateGroupMembers iterates over all the members of the group with the given name present inside the given subspace +func (k Keeper) IterateGroupMembers( + ctx sdk.Context, subspaceID uint64, groupName string, fn func(index int64, member sdk.AccAddress) (stop bool), +) { + store := ctx.KVStore(k.storeKey) + + prefix := types.GroupMembersStoreKey(subspaceID, groupName) + iterator := sdk.KVStorePrefixIterator(store, prefix) + defer iterator.Close() + + i := int64(0) + for ; iterator.Valid(); iterator.Next() { + member := types.GetGroupMemberFromBytes(bytes.TrimPrefix(iterator.Key(), prefix)) + stop := fn(i, member) + if stop { + break + } + i++ + } +} + +// -------------------------------------------------------------------------------------------------------------------- + +// IteratePermissions iterates over all the permissions set for the subspace with the given id +func (k Keeper) IteratePermissions( + ctx sdk.Context, subspaceID uint64, fn func(index int64, target string, permission types.Permission) (stop bool), +) { + store := ctx.KVStore(k.storeKey) + + prefix := types.PermissionsStoreKey(subspaceID) + iterator := sdk.KVStorePrefixIterator(store, prefix) + defer iterator.Close() + + i := int64(0) + for ; iterator.Valid(); iterator.Next() { + target := types.GetTargetFromBytes(bytes.TrimPrefix(iterator.Key(), prefix)) + permission := types.UnmarshalPermission(iterator.Value()) + + stop := fn(i, target, permission) + if stop { + break + } + i++ + } +} diff --git a/x/subspaces/keeper/genesis.go b/x/subspaces/keeper/genesis.go index 18372b6112..6200f60ce9 100644 --- a/x/subspaces/keeper/genesis.go +++ b/x/subspaces/keeper/genesis.go @@ -1,76 +1,85 @@ package keeper -// -//import ( -// "fmt" -// -// "github.com/desmos-labs/desmos/v2/x/subspaces/types" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -//) -// -//// ExportGenesis returns the GenesisState associated with the given context -//func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { -// return types.NewGenesisState( -// k.GetAllSubspaces(ctx), -// k.GetAllAdmins(ctx), -// k.GetAllRegisteredUsers(ctx), -// k.GetAllBannedUsers(ctx), -// ) -//} -// -//// InitGenesis initializes the chain state based on the given GenesisState -//func (k Keeper) InitGenesis(ctx sdk.Context, data *types.GenesisState) { -// // Initialize the subspaces -// for _, subspace := range data.Subspaces { -// err := k.SaveSubspace(ctx, subspace, subspace.Owner) -// if err != nil { -// panic(err) -// } -// } -// -// // Initialize the admins -// for _, entry := range data.Admins { -// subspace, found := k.GetSubspace(ctx, entry.SubspaceID) -// if !found { -// panic(fmt.Errorf("invalid admins entry: subspace with id %s does not exist", entry.SubspaceID)) -// } -// -// for _, admin := range entry.Users { -// err := k.AddAdminToSubspace(ctx, subspace.ID, admin, subspace.Owner) -// if err != nil { -// panic(err) -// } -// } -// } -// -// // Initialize the registered users -// for _, entry := range data.RegisteredUsers { -// subspace, found := k.GetSubspace(ctx, entry.SubspaceID) -// if !found { -// panic(fmt.Errorf("invalid registered user entry: subspace with id %s does not exist", entry.SubspaceID)) -// } -// -// for _, user := range entry.Users { -// err := k.RegisterUserInSubspace(ctx, subspace.ID, user, subspace.Owner) -// if err != nil { -// panic(err) -// } -// } -// } -// -// // Initialize the banned users -// for _, entry := range data.BannedUsers { -// subspace, found := k.GetSubspace(ctx, entry.SubspaceID) -// if !found { -// panic(fmt.Errorf("invalid banned user entry: subspace with id %s does not exist", entry.SubspaceID)) -// } -// -// for _, user := range entry.Users { -// err := k.BanUserInSubspace(ctx, subspace.ID, user, subspace.Owner) -// if err != nil { -// panic(err) -// } -// } -// } -//} +import ( + "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// ExportGenesis returns the GenesisState associated with the given context +func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + return types.NewGenesisState( + k.GetAllSubspaces(ctx), + k.GetAllPermissions(ctx), + k.GetAllUserGroups(ctx), + ) +} + +// GetAllPermissions returns all the stored permissions for all subspaces +func (k Keeper) GetAllPermissions(ctx sdk.Context) []types.ACLEntry { + var entries []types.ACLEntry + k.IterateSubspaces(ctx, func(index int64, subspace types.Subspace) (stop bool) { + k.IteratePermissions(ctx, subspace.ID, func(index int64, target string, permission types.Permission) (stop bool) { + entries = append(entries, types.NewACLEntry(subspace.ID, target, permission)) + return false + }) + return false + }) + + return entries +} + +// GetAllUserGroups returns the information (name and members) for all the groups of all the subspaces +func (k Keeper) GetAllUserGroups(ctx sdk.Context) []types.UserGroup { + var groups []types.UserGroup + k.IterateSubspaces(ctx, func(index int64, subspace types.Subspace) (stop bool) { + k.IterateSubspaceGroups(ctx, subspace.ID, func(index int64, groupName string) (stop bool) { + + var members []string + k.IterateGroupMembers(ctx, subspace.ID, groupName, func(index int64, member sdk.AccAddress) (stop bool) { + members = append(members, member.String()) + return false + }) + + groups = append(groups, types.NewUserGroup(subspace.ID, groupName, members)) + return false + }) + + return false + }) + return groups +} + +// -------------------------------------------------------------------------------------------------------------------- + +// InitGenesis initializes the chain state based on the given GenesisState +func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { + // Initialize the subspaces + for _, subspace := range data.Subspaces { + k.SaveSubspace(ctx, subspace) + } + + // Initialize the groups with default permission PermissionNothing + // The real permission will be set later when initializing the various permissions + for _, group := range data.UserGroups { + k.SaveUserGroup(ctx, group.SubspaceID, group.Name, types.PermissionNothing) + + // Initialize the members + for _, member := range group.Members { + userAddr, err := sdk.AccAddressFromBech32(member) + if err != nil { + panic(err) + } + + err = k.AddUserToGroup(ctx, group.SubspaceID, group.Name, userAddr) + if err != nil { + panic(err) + } + } + } + + // Initialize the permissions + for _, entry := range data.ACL { + k.SetPermissions(ctx, entry.SubspaceId, entry.Target, entry.Permissions) + } +} diff --git a/x/subspaces/keeper/genesis_test.go b/x/subspaces/keeper/genesis_test.go new file mode 100644 index 0000000000..29537d0100 --- /dev/null +++ b/x/subspaces/keeper/genesis_test.go @@ -0,0 +1,305 @@ +package keeper_test + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { + testCases := []struct { + name string + store func(ctx sdk.Context) + expGenesis *types.GenesisState + }{ + { + name: "subspaces are exported correctly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SaveSubspace(ctx, types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + )) + }, + expGenesis: types.NewGenesisState( + []types.Subspace{ + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + }, + nil, + nil, + ), + }, + { + name: "permissions are exported correctly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SetPermissions(ctx, 1, "group", types.PermissionWrite) + + suite.k.SaveSubspace(ctx, types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + )) + suite.k.SetPermissions(ctx, 2, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", types.PermissionSetPermissions) + }, + expGenesis: types.NewGenesisState( + []types.Subspace{ + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + }, + []types.ACLEntry{ + types.NewACLEntry(1, "group", types.PermissionWrite), + types.NewACLEntry(2, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", types.PermissionSetPermissions), + }, + nil, + ), + }, + { + name: "user groups are exported properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + + suite.k.SaveSubspace(ctx, types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SaveUserGroup(ctx, 2, "another-group", types.PermissionManageGroups) + + userAddr, err = sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + err = suite.k.AddUserToGroup(ctx, 2, "another-group", userAddr) + + userAddr, err = sdk.AccAddressFromBech32("cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5") + suite.Require().NoError(err) + err = suite.k.AddUserToGroup(ctx, 2, "another-group", userAddr) + }, + expGenesis: types.NewGenesisState( + []types.Subspace{ + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + }, + []types.ACLEntry{ + types.NewACLEntry(1, "group", types.PermissionWrite), + types.NewACLEntry(2, "another-group", types.PermissionManageGroups), + }, + []types.UserGroup{ + types.NewUserGroup(1, "group", []string{ + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + }), + types.NewUserGroup(2, "another-group", []string{ + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + }), + }, + ), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + genesis := suite.k.ExportGenesis(ctx) + suite.Require().Equal(tc.expGenesis, genesis) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_InitGenesis() { + testCases := []struct { + name string + genesis types.GenesisState + check func(ctx sdk.Context) + }{ + { + name: "all data is imported properly", + genesis: types.GenesisState{ + Subspaces: []types.Subspace{ + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + }, + ACL: []types.ACLEntry{ + types.NewACLEntry(1, "group", types.PermissionWrite), + types.NewACLEntry(2, "another-group", types.PermissionManageGroups), + }, + UserGroups: []types.UserGroup{ + types.NewUserGroup(1, "group", []string{ + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + }), + types.NewUserGroup(2, "another-group", []string{ + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + }), + }, + }, + check: func(ctx sdk.Context) { + subspaces := suite.k.GetAllSubspaces(ctx) + suite.Require().Len(subspaces, 2) + + var firstSubspaceGroups = 0 + suite.k.IterateSubspaceGroups(ctx, 1, func(index int64, groupName string) (stop bool) { + firstSubspaceGroups += 1 + return false + }) + suite.Require().Equal(firstSubspaceGroups, 1) + + groupPermissions := suite.k.GetPermissions(ctx, 1, "group") + suite.Require().Equal(types.PermissionWrite, groupPermissions) + + var groupMembers = 0 + suite.k.IterateGroupMembers(ctx, 1, "group", func(index int64, member sdk.AccAddress) (stop bool) { + groupMembers += 1 + return false + }) + suite.Require().Equal(1, groupMembers) + + var secondSubspaceGroups = 0 + suite.k.IterateSubspaceGroups(ctx, 2, func(index int64, groupName string) (stop bool) { + secondSubspaceGroups += 1 + return false + }) + suite.Require().Equal(secondSubspaceGroups, 1) + + var anotherGroupMembers = 0 + suite.k.IterateGroupMembers(ctx, 2, "another-group", func(index int64, member sdk.AccAddress) (stop bool) { + anotherGroupMembers += 1 + return false + }) + suite.Require().Equal(2, anotherGroupMembers) + + anotherGroupPermissions := suite.k.GetPermissions(ctx, 2, "another-group") + suite.Require().Equal(types.PermissionManageGroups, anotherGroupPermissions) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + + suite.k.InitGenesis(ctx, tc.genesis) + + if tc.check != nil { + tc.check(ctx) + } + + }) + } +} diff --git a/x/subspaces/keeper/groups.go b/x/subspaces/keeper/groups.go index 681a626b45..bf34f1bac1 100644 --- a/x/subspaces/keeper/groups.go +++ b/x/subspaces/keeper/groups.go @@ -7,8 +7,8 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) -// HasGroup returns whether the given subspace has a group with the specified name or not -func (k Keeper) HasGroup(ctx sdk.Context, subspaceID uint64, groupName string) bool { +// HasUserGroup returns whether the given subspace has a group with the specified name or not +func (k Keeper) HasUserGroup(ctx sdk.Context, subspaceID uint64, groupName string) bool { store := ctx.KVStore(k.storeKey) return store.Has(types.GroupStoreKey(subspaceID, groupName)) } @@ -30,36 +30,44 @@ func (k Keeper) DeleteUserGroup(ctx sdk.Context, subspaceID uint64, groupName st k.Logger(ctx).Info("group deleted", "subspace_id", subspaceID, "group_name", groupName) store.Delete(types.GroupStoreKey(subspaceID, groupName)) + + // Remove all the members from this group + var members []sdk.AccAddress + k.IterateGroupMembers(ctx, subspaceID, groupName, func(index int64, member sdk.AccAddress) (stop bool) { + members = append(members, member) + return false + }) + + for _, member := range members { + k.RemoveUserFromGroup(ctx, subspaceID, groupName, member) + } + + // Remove the group permissions + k.RemovePermissions(ctx, subspaceID, groupName) } // IsMemberOfGroup returns whether the given user is part of the group with // the specified name inside the provided subspace func (k Keeper) IsMemberOfGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) bool { store := ctx.KVStore(k.storeKey) - return store.Has(types.GroupMemberStoreKey(subspaceID, groupName, user.String())) - + return store.Has(types.GroupMemberStoreKey(subspaceID, groupName, user)) } // AddUserToGroup adds the given user to the group having the provided name inside the specified subspace. // If the group does not exist inside the subspace, it returns an error. func (k Keeper) AddUserToGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) error { - if !k.HasGroup(ctx, subspaceID, groupName) { + if !k.HasUserGroup(ctx, subspaceID, groupName) { return sdkerrors.Wrapf(sdkerrors.ErrInvalidVersion, "group with name %s does not exist", groupName) } store := ctx.KVStore(k.storeKey) - store.Set(types.GroupMemberStoreKey(subspaceID, groupName, user.String()), []byte{0x01}) + store.Set(types.GroupMemberStoreKey(subspaceID, groupName, user), []byte{0x01}) return nil } // RemoveUserFromGroup removes the specified user from the subspace group having the given name. // If the group does not exist inside the subspace, it returns an error. -func (k Keeper) RemoveUserFromGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) error { - if !k.HasGroup(ctx, subspaceID, groupName) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidVersion, "group with name %s does not exist", groupName) - } - +func (k Keeper) RemoveUserFromGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { store := ctx.KVStore(k.storeKey) - store.Delete(types.GroupMemberStoreKey(subspaceID, groupName, user.String())) - return nil + store.Delete(types.GroupMemberStoreKey(subspaceID, groupName, user)) } diff --git a/x/subspaces/keeper/groups_test.go b/x/subspaces/keeper/groups_test.go new file mode 100644 index 0000000000..cf0b6c9ea7 --- /dev/null +++ b/x/subspaces/keeper/groups_test.go @@ -0,0 +1,391 @@ +package keeper_test + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +func (suite *KeeperTestsuite) TestKeeper_HasUserGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + groupName string + expResult bool + }{ + { + name: "not found group returns false", + subspaceID: 1, + groupName: "group", + expResult: false, + }, + { + name: "found group returns true", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + }, + subspaceID: 1, + groupName: "group", + expResult: true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + result := suite.k.HasUserGroup(ctx, tc.subspaceID, tc.groupName) + suite.Require().Equal(tc.expResult, result) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_SaveUserGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + groupName string + permissions types.Permission + check func(ctx sdk.Context) + }{ + { + name: "non existing group is stored properly", + subspaceID: 1, + groupName: "group", + permissions: types.PermissionWrite, + check: func(ctx sdk.Context) { + hasGroup := suite.k.HasUserGroup(ctx, 1, "group") + suite.Require().True(hasGroup) + + permissions := suite.k.GetPermissions(ctx, 1, "group") + suite.Require().Equal(types.PermissionWrite, permissions) + }, + }, + { + name: "existing group permissions are updated properly", + store: func(ctx sdk.Context) { + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + }, + subspaceID: 1, + groupName: "group", + permissions: types.PermissionManageGroups, + check: func(ctx sdk.Context) { + hasGroup := suite.k.HasUserGroup(ctx, 1, "group") + suite.Require().True(hasGroup) + + permissions := suite.k.GetPermissions(ctx, 1, "group") + suite.Require().Equal(types.PermissionManageGroups, permissions) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + suite.k.SaveUserGroup(ctx, tc.subspaceID, tc.groupName, tc.permissions) + if tc.check != nil { + tc.check(ctx) + } + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_DeleteUserGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + groupName string + check func(ctx sdk.Context) + }{ + { + name: "non existing group is deleted properly", + subspaceID: 1, + groupName: "group", + check: func(ctx sdk.Context) { + hasGroup := suite.k.HasUserGroup(ctx, 1, "group") + suite.Require().False(hasGroup) + }, + }, + { + name: "existing group is deleted properly, members are deleted and permissions are cleared", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + suite.Require().NoError(err) + + userAddr, err = sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + suite.Require().NoError(err) + }, + subspaceID: 1, + groupName: "group", + check: func(ctx sdk.Context) { + hasGroup := suite.k.HasUserGroup(ctx, 1, "group") + suite.Require().False(hasGroup) + + var members []sdk.AccAddress + suite.k.IterateGroupMembers(ctx, 1, "group", func(index int64, member sdk.AccAddress) (stop bool) { + members = append(members, member) + return false + }) + suite.Require().Empty(members) + + store := ctx.KVStore(suite.storeKey) + suite.Require().False(store.Has(types.PermissionStoreKey(1, "group"))) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + suite.k.DeleteUserGroup(ctx, tc.subspaceID, tc.groupName) + if tc.check != nil { + tc.check(ctx) + } + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_IsMemberOfGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + groupName string + user string + expResult bool + }{ + { + name: "not being part of group returns false", + subspaceID: 1, + groupName: "group", + user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + expResult: false, + }, + { + name: "being part of group returns true", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + suite.Require().NoError(err) + }, + subspaceID: 1, + groupName: "group", + user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + expResult: true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + userAddr, err := sdk.AccAddressFromBech32(tc.user) + suite.Require().NoError(err) + + result := suite.k.IsMemberOfGroup(ctx, tc.subspaceID, tc.groupName, userAddr) + suite.Require().Equal(tc.expResult, result) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_AddUserToGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + groupName string + user string + shouldErr bool + check func(ctx sdk.Context) + }{ + { + name: "non existing group returns error", + subspaceID: 1, + groupName: "group", + user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + shouldErr: true, + }, + { + name: "user is added properly to group", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + }, + subspaceID: 1, + groupName: "group", + user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + shouldErr: false, + check: func(ctx sdk.Context) { + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + + isMember := suite.k.IsMemberOfGroup(ctx, 1, "group", userAddr) + suite.Require().True(isMember) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + userAddr, err := sdk.AccAddressFromBech32(tc.user) + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, tc.subspaceID, tc.groupName, userAddr) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_RemoveUserFromGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + groupName string + user string + check func(ctx sdk.Context) + }{ + { + name: "non existing user is removed properly", + subspaceID: 1, + groupName: "group", + user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + check: func(ctx sdk.Context) { + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + + isMember := suite.k.IsMemberOfGroup(ctx, 1, "group", userAddr) + suite.Require().False(isMember) + }, + }, + { + name: "existing user is removed properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + suite.Require().NoError(err) + }, + subspaceID: 1, + groupName: "group", + user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + check: func(ctx sdk.Context) { + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + + isMember := suite.k.IsMemberOfGroup(ctx, 1, "group", userAddr) + suite.Require().False(isMember) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + userAddr, err := sdk.AccAddressFromBech32(tc.user) + suite.Require().NoError(err) + + suite.k.RemoveUserFromGroup(ctx, tc.subspaceID, tc.groupName, userAddr) + if tc.check != nil { + tc.check(ctx) + } + }) + } +} diff --git a/x/subspaces/keeper/grpc_query.go b/x/subspaces/keeper/grpc_query.go index ed74f20b35..cfa1bd2e19 100644 --- a/x/subspaces/keeper/grpc_query.go +++ b/x/subspaces/keeper/grpc_query.go @@ -57,6 +57,11 @@ func (k Keeper) Subspaces(ctx context.Context, request *types.QuerySubspacesRequ func (k Keeper) UserGroups(ctx context.Context, request *types.QueryUserGroupsRequest) (*types.QueryUserGroupsResponse, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) + // Check if the subspace exists + if !k.HasSubspace(sdkCtx, request.SubspaceId) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", request.SubspaceId) + } + store := sdkCtx.KVStore(k.storeKey) storePrefix := types.GroupsStoreKey(request.SubspaceId) groupsStore := prefix.NewStore(store, storePrefix) @@ -79,6 +84,16 @@ func (k Keeper) UserGroups(ctx context.Context, request *types.QueryUserGroupsRe func (k Keeper) UserGroupMembers(ctx context.Context, request *types.QueryUserGroupMembersRequest) (*types.QueryUserGroupMembersResponse, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) + // Check if the subspace exists + if !k.HasSubspace(sdkCtx, request.SubspaceId) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", request.SubspaceId) + } + + // Check if the group exists + if !k.HasUserGroup(sdkCtx, request.SubspaceId, request.GroupName) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %s could not be found", request.GroupName) + } + store := sdkCtx.KVStore(k.storeKey) storePrefix := types.GroupMembersStoreKey(request.SubspaceId, request.GroupName) membersStore := prefix.NewStore(store, storePrefix) @@ -86,7 +101,7 @@ func (k Keeper) UserGroupMembers(ctx context.Context, request *types.QueryUserGr var members []string pageRes, err := query.Paginate(membersStore, request.Pagination, func(key []byte, value []byte) error { member := types.GetGroupMemberFromBytes(bytes.TrimPrefix(key, storePrefix)) - members = append(members, member) + members = append(members, member.String()) return nil }) @@ -100,6 +115,12 @@ func (k Keeper) UserGroupMembers(ctx context.Context, request *types.QueryUserGr // Permissions implements the Query/Permissions gRPC method func (k Keeper) Permissions(ctx context.Context, request *types.QueryPermissionsRequest) (*types.QueryPermissionsResponse, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) + + // Check if the subspace exists + if !k.HasSubspace(sdkCtx, request.SubspaceId) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", request.SubspaceId) + } + permission := k.GetPermissions(sdkCtx, request.SubspaceId, request.Target) return &types.QueryPermissionsResponse{Permissions: permission}, nil } diff --git a/x/subspaces/keeper/grpc_query_test.go b/x/subspaces/keeper/grpc_query_test.go index eb19fd7eb6..c5caf9ed76 100644 --- a/x/subspaces/keeper/grpc_query_test.go +++ b/x/subspaces/keeper/grpc_query_test.go @@ -1,349 +1,362 @@ package keeper_test -// -//import ( -// "time" -// -// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -// "github.com/cosmos/cosmos-sdk/types/query" -//) -// -//func (suite *KeeperTestsuite) TestQueryServer_Subspace() { -// tests := []struct { -// name string -// store func(ctx sdk.Context) -// request *types2.QuerySubspaceRequest -// shouldErr bool -// expResponse *types2.QuerySubspaceResponse -// }{ -// { -// name: "Invalid subspace id returns error", -// request: types2.NewQuerySubspaceRequest("123"), -// shouldErr: true, -// }, -// { -// name: "Not found subspace returns error", -// request: types2.NewQuerySubspaceRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), -// shouldErr: true, -// }, -// { -// name: "Found subspace is returned properly", -// store: func(ctx sdk.Context) { -// subspace := types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), -// ) -// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) -// suite.Require().NoError(err) -// }, -// request: types2.NewQuerySubspaceRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), -// shouldErr: false, -// expResponse: &types2.QuerySubspaceResponse{ -// Subspace: types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), -// ), -// }, -// }, -// } -// -// for _, test := range tests { -// test := test -// suite.Run(test.name, func() { -// suite.SetupTest() -// if test.store != nil { -// test.store(suite.ctx) -// } -// -// response, err := suite.k.Subspace(sdk.WrapSDKContext(suite.ctx), test.request) -// if test.shouldErr { -// suite.Require().Error(err) -// } else { -// suite.Require().NoError(err) -// suite.Require().Equal(test.expResponse, response) -// } -// }) -// } -//} -// -//func (suite *KeeperTestsuite) TestQueryServer_Subspaces() { -// tests := []struct { -// name string -// store func(ctx sdk.Context) -// req *types2.QuerySubspacesRequest -// expSubspaces []types2.Subspace -// }{ -// -// { -// name: "Invalid pagination returns empty slice", -// req: types2.NewQuerySubspacesRequest(&query.PageRequest{ -// Limit: 1, -// Offset: 1, -// }), -// expSubspaces: nil, -// }, -// { -// name: "Valid pagination returns result properly", -// store: func(ctx sdk.Context) { -// subspace := types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), -// ) -// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) -// suite.Require().NoError(err) -// }, -// req: &types2.QuerySubspacesRequest{}, -// expSubspaces: []types2.Subspace{ -// types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), -// ), -// }, -// }, -// } -// -// for _, test := range tests { -// test := test -// suite.Run(test.name, func() { -// suite.SetupTest() -// if test.store != nil { -// test.store(suite.ctx) -// } -// -// res, err := suite.k.Subspaces(sdk.WrapSDKContext(suite.ctx), test.req) -// suite.Require().NoError(err) -// suite.Require().Equal(test.expSubspaces, res.Subspaces) -// }) -// } -//} -// -//func (suite *KeeperTestsuite) TestQueryServer_Admins() { -// tests := []struct { -// name string -// store func(ctx sdk.Context) -// req *types2.QueryAdminsRequest -// shouldErr bool -// expAdmins []string -// }{ -// { -// name: "Invalid subspace id returns error", -// req: types2.NewQueryAdminsRequest("123", nil), -// shouldErr: true, -// }, -// { -// name: "Non existing subspace returns empty slice", -// req: types2.NewQueryAdminsRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), -// shouldErr: false, -// expAdmins: nil, -// }, -// { -// name: "Requests pagination works properly", -// store: func(ctx sdk.Context) { -// subspace := types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), -// ) -// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) -// suite.Require().NoError(err) -// -// err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) -// suite.Require().NoError(err) -// -// err = suite.k.AddAdminToSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) -// suite.Require().NoError(err) -// }, -// req: types2.NewQueryAdminsRequest( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// &query.PageRequest{ -// Offset: 1, -// Limit: 1, -// }, -// ), -// expAdmins: []string{ -// "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", -// }, -// }, -// } -// -// for _, test := range tests { -// test := test -// suite.Run(test.name, func() { -// suite.SetupTest() -// if test.store != nil { -// test.store(suite.ctx) -// } -// -// res, err := suite.k.Admins(sdk.WrapSDKContext(suite.ctx), test.req) -// if test.shouldErr { -// suite.Require().Error(err) -// } else { -// suite.Require().NoError(err) -// suite.Require().Equal(test.expAdmins, res.Admins) -// } -// }) -// } -//} -// -//func (suite *KeeperTestsuite) TestQueryServer_RegisteredUsers() { -// tests := []struct { -// name string -// store func(ctx sdk.Context) -// req *types2.QueryRegisteredUsersRequest -// shouldErr bool -// expUsers []string -// }{ -// { -// name: "Invalid subspace id returns error", -// req: types2.NewQueryRegisteredUsersRequest("123", nil), -// shouldErr: true, -// }, -// { -// name: "Non existing subspace returns empty slice", -// req: types2.NewQueryRegisteredUsersRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), -// shouldErr: false, -// expUsers: nil, -// }, -// { -// name: "Requests pagination works properly", -// store: func(ctx sdk.Context) { -// subspace := types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), -// ) -// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) -// suite.Require().NoError(err) -// -// err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) -// suite.Require().NoError(err) -// -// err = suite.k.RegisterUserInSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) -// suite.Require().NoError(err) -// }, -// req: types2.NewQueryRegisteredUsersRequest( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// &query.PageRequest{ -// Offset: 1, -// Limit: 1, -// }, -// ), -// expUsers: []string{ -// "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", -// }, -// }, -// } -// -// for _, test := range tests { -// test := test -// suite.Run(test.name, func() { -// suite.SetupTest() -// if test.store != nil { -// test.store(suite.ctx) -// } -// -// res, err := suite.k.RegisteredUsers(sdk.WrapSDKContext(suite.ctx), test.req) -// if test.shouldErr { -// suite.Require().Error(err) -// } else { -// suite.Require().NoError(err) -// suite.Require().Equal(test.expUsers, res.Users) -// } -// }) -// } -//} -// -//func (suite *KeeperTestsuite) TestQueryServer_BannedUsers() { -// tests := []struct { -// name string -// store func(ctx sdk.Context) -// req *types2.QueryBannedUsersRequest -// shouldErr bool -// expUsers []string -// }{ -// { -// name: "Invalid subspace id returns error", -// req: types2.NewQueryBannedUsersRequest("123", nil), -// shouldErr: true, -// }, -// { -// name: "Non existing subspace returns empty slice", -// req: types2.NewQueryBannedUsersRequest("4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", nil), -// shouldErr: false, -// expUsers: nil, -// }, -// { -// name: "Requests pagination works properly", -// store: func(ctx sdk.Context) { -// subspace := types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// time.Date(2020, 1, 1, 00, 00, 00, 000, time.UTC), -// ) -// err := suite.k.SaveSubspace(suite.ctx, subspace, subspace.Owner) -// suite.Require().NoError(err) -// -// err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", subspace.Owner) -// suite.Require().NoError(err) -// -// err = suite.k.BanUserInSubspace(suite.ctx, subspace.ID, "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", subspace.Owner) -// suite.Require().NoError(err) -// }, -// req: types2.NewQueryBannedUsersRequest( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// &query.PageRequest{ -// Offset: 1, -// Limit: 1, -// }, -// ), -// expUsers: []string{ -// "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", -// }, -// }, -// } -// -// for _, test := range tests { -// test := test -// suite.Run(test.name, func() { -// suite.SetupTest() -// if test.store != nil { -// test.store(suite.ctx) -// } -// -// res, err := suite.k.BannedUsers(sdk.WrapSDKContext(suite.ctx), test.req) -// if test.shouldErr { -// suite.Require().Error(err) -// } else { -// suite.Require().NoError(err) -// suite.Require().Equal(test.expUsers, res.Users) -// } -// }) -// } -//} +import ( + "time" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" +) + +func (suite *KeeperTestsuite) TestQueryServer_Subspace() { + testCases := []struct { + name string + store func(ctx sdk.Context) + request *types.QuerySubspaceRequest + shouldErr bool + expResponse *types.QuerySubspaceResponse + }{ + { + name: "not found subspace returns error", + request: types.NewQuerySubspaceRequest(1), + shouldErr: true, + }, + { + name: "found subspace is returned properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + request: types.NewQuerySubspaceRequest(1), + shouldErr: false, + expResponse: &types.QuerySubspaceResponse{ + Subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + response, err := suite.k.Subspace(sdk.WrapSDKContext(ctx), tc.request) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expResponse, response) + } + }) + } +} + +func (suite *KeeperTestsuite) TestQueryServer_Subspaces() { + testCases := []struct { + name string + store func(ctx sdk.Context) + req *types.QuerySubspacesRequest + expSubspaces []types.Subspace + }{ + + { + name: "invalid pagination returns empty slice", + req: types.NewQuerySubspacesRequest(&query.PageRequest{ + Limit: 1, + Offset: 1, + }), + expSubspaces: nil, + }, + { + name: "valid pagination returns result properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveSubspace(ctx, types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + req: &types.QuerySubspacesRequest{ + Pagination: &query.PageRequest{ + Offset: 1, + Limit: 1, + CountTotal: true, + }, + }, + expSubspaces: []types.Subspace{ + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + res, err := suite.k.Subspaces(sdk.WrapSDKContext(ctx), tc.req) + suite.Require().NoError(err) + suite.Require().Equal(tc.expSubspaces, res.Subspaces) + }) + } +} + +func (suite *KeeperTestsuite) TestQueryServer_UserGroups() { + testCases := []struct { + name string + store func(ctx sdk.Context) + shouldErr bool + req *types.QueryUserGroupsRequest + expGroups []string + }{ + { + name: "non existing subspace returns error", + req: types.NewQueryUserGroupsRequest(1, nil), + shouldErr: true, + }, + { + name: "existing groups are returned properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SaveUserGroup(ctx, 1, "1-group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, 1, "2-group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, 1, "3-group", types.PermissionWrite) + }, + req: types.NewQueryUserGroupsRequest(1, &query.PageRequest{ + Offset: 1, + Limit: 2, + }), + shouldErr: false, + expGroups: []string{"2-group", "3-group"}, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + res, err := suite.k.UserGroups(sdk.WrapSDKContext(ctx), tc.req) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expGroups, res.Groups) + } + }) + } +} + +func (suite *KeeperTestsuite) TestQueryServer_UserGroupMembers() { + testCases := []struct { + name string + store func(ctx sdk.Context) + req *types.QueryUserGroupMembersRequest + shouldErr bool + expMembers []string + }{ + { + name: "non existing subspace returns error", + req: types.NewQueryUserGroupMembersRequest(1, "group", nil), + shouldErr: true, + }, + { + name: "non existing group returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + req: types.NewQueryUserGroupMembersRequest(1, "group", nil), + shouldErr: true, + }, + { + name: "existing group members are returned properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + suite.Require().NoError(err) + + userAddr, err = sdk.AccAddressFromBech32("cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + suite.Require().NoError(err) + + userAddr, err = sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + suite.Require().NoError(err) + }, + req: types.NewQueryUserGroupMembersRequest(1, "group", &query.PageRequest{ + Offset: 1, + Limit: 1, + }), + shouldErr: false, + expMembers: []string{"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"}, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + res, err := suite.k.UserGroupMembers(sdk.WrapSDKContext(ctx), tc.req) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expMembers, res.Members) + } + }) + } +} + +func (suite *KeeperTestsuite) TestQueryServer_Permissions() { + testCases := []struct { + name string + store func(ctx sdk.Context) + req *types.QueryPermissionsRequest + shouldErr bool + expPermissions types.Permission + }{ + { + name: "not found subspace returns error", + shouldErr: true, + req: types.NewQueryPermissionsRequest(1, "group"), + }, + { + name: "not found target returns PermissionNothing", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + req: types.NewQueryPermissionsRequest(1, "group"), + shouldErr: false, + expPermissions: types.PermissionNothing, + }, + { + name: "existing permissions are returned correctly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SetPermissions(ctx, 1, "group", types.PermissionWrite) + }, + req: types.NewQueryPermissionsRequest(1, "group"), + shouldErr: false, + expPermissions: types.PermissionWrite, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + res, err := suite.k.Permissions(sdk.WrapSDKContext(ctx), tc.req) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expPermissions, res.Permissions) + } + }) + } +} diff --git a/x/subspaces/keeper/invariants.go b/x/subspaces/keeper/invariants.go index 22461a01d9..f1db7f42ed 100644 --- a/x/subspaces/keeper/invariants.go +++ b/x/subspaces/keeper/invariants.go @@ -1,51 +1,53 @@ package keeper -// -//import ( -// "fmt" -// -// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -//) -// -//// RegisterInvariants registers all subspaces invariants -//func RegisterInvariants(ir sdk.InvariantRegistry, keeper Keeper) { -// ir.RegisterRoute(types2.ModuleName, "valid-subspaces", -// ValidSubspacesInvariant(keeper)) -//} -// -//// AllInvariants runs all invariants of the module -//func AllInvariants(k Keeper) sdk.Invariant { -// return func(ctx sdk.Context) (string, bool) { -// if res, stop := ValidSubspacesInvariant(k)(ctx); stop { -// return res, stop -// } -// return "Every invariant condition is fulfilled correctly", true -// } -//} -// -//// formatOutputSubspaces concatenate the subspaces given into a unique string -//func formatOutputSubspaces(subspaces []types2.Subspace) (outputSubspaces string) { -// for _, subspace := range subspaces { -// outputSubspaces += subspace.ID + "\n" -// } -// return outputSubspaces -//} -// -//// ValidSubspacesInvariant checks that all the subspaces are valid -//func ValidSubspacesInvariant(k Keeper) sdk.Invariant { -// return func(ctx sdk.Context) (string, bool) { -// var invalidSubspaces []types2.Subspace -// k.IterateSubspaces(ctx, func(_ int64, subspace types2.Subspace) (stop bool) { -// if err := subspace.Validate(); err != nil { -// invalidSubspaces = append(invalidSubspaces, subspace) -// } -// return false -// }) -// -// return sdk.FormatInvariant(types2.ModuleName, "invalid subspaces", -// fmt.Sprintf("the following subspaces are invalid:\n %s", formatOutputSubspaces(invalidSubspaces)), -// ), invalidSubspaces != nil -// } -//} +import ( + "fmt" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// RegisterInvariants registers all subspaces invariants +func RegisterInvariants(ir sdk.InvariantRegistry, keeper Keeper) { + ir.RegisterRoute(types.ModuleName, "valid-subspaces", + ValidSubspacesInvariant(keeper)) +} + +// AllInvariants runs all invariants of the module +func AllInvariants(k Keeper) sdk.Invariant { + return func(ctx sdk.Context) (string, bool) { + res, broken := ValidSubspacesInvariant(k)(ctx) + if broken { + return res, true + } + + return "Every invariant condition is fulfilled correctly", false + } +} + +// formatOutputSubspaces concatenate the subspaces given into a unique string +func formatOutputSubspaces(subspaces []types.Subspace) (outputSubspaces string) { + for _, subspace := range subspaces { + outputSubspaces += fmt.Sprintf("%d\n", subspace.ID) + } + return outputSubspaces +} + +// ValidSubspacesInvariant checks that all the subspaces are valid +func ValidSubspacesInvariant(k Keeper) sdk.Invariant { + return func(ctx sdk.Context) (string, bool) { + var invalidSubspaces []types.Subspace + k.IterateSubspaces(ctx, func(_ int64, subspace types.Subspace) (stop bool) { + err := subspace.Validate() + if err != nil { + invalidSubspaces = append(invalidSubspaces, subspace) + } + return false + }) + + return sdk.FormatInvariant(types.ModuleName, "invalid subspaces", + fmt.Sprintf("the following subspaces are invalid:\n %s", formatOutputSubspaces(invalidSubspaces)), + ), invalidSubspaces != nil + } +} diff --git a/x/subspaces/keeper/invariants_test.go b/x/subspaces/keeper/invariants_test.go index 8ed1ab3d9c..e62bcb65cb 100644 --- a/x/subspaces/keeper/invariants_test.go +++ b/x/subspaces/keeper/invariants_test.go @@ -1,65 +1,62 @@ package keeper_test -// -//import ( -// "time" -// -// "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" -// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -//) -// -//func (suite *KeeperTestsuite) TestInvariants() { -// tests := []struct { -// name string -// store func(ctx sdk.Context) -// expStop bool -// }{ -// { -// name: "All invariants are not violated", -// store: func(ctx sdk.Context) { -// subspace := types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC), -// ) -// -// err := suite.k.SaveSubspace(ctx, subspace, subspace.Owner) -// suite.Require().NoError(err) -// }, -// expStop: true, -// }, -// { -// name: "Valid subspace invariant violated", -// store: func(ctx sdk.Context) { -// subspace := types2.NewSubspace( -// "", -// "test", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC), -// ) -// _ = suite.k.SaveSubspace(ctx, subspace, subspace.Owner) -// }, -// expStop: true, -// }, -// } -// -// for _, test := range tests { -// test := test -// suite.Run(test.name, func() { -// suite.SetupTest() -// if test.store != nil { -// test.store(suite.ctx) -// } -// -// _, stop := keeper.AllInvariants(suite.k)(suite.ctx) -// suite.Require().Equal(test.expStop, stop) -// }) -// } -//} +import ( + "time" + + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (suite *KeeperTestsuite) TestInvariants() { + tests := []struct { + name string + store func(ctx sdk.Context) + expBroken bool + }{ + { + name: "all invariants are not violated", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + expBroken: false, + }, + { + name: "valid subspace invariant violated", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + expBroken: true, + }, + } + + for _, test := range tests { + test := test + suite.Run(test.name, func() { + ctx, _ := suite.ctx.CacheContext() + if test.store != nil { + test.store(ctx) + } + + _, broken := keeper.AllInvariants(suite.k)(ctx) + suite.Require().Equal(test.expBroken, broken) + }) + } +} diff --git a/x/subspaces/keeper/msg_server.go b/x/subspaces/keeper/msg_server.go index ba95527c32..f31cd32e99 100644 --- a/x/subspaces/keeper/msg_server.go +++ b/x/subspaces/keeper/msg_server.go @@ -49,7 +49,7 @@ func (k msgServer) CreateSubspace(goCtx context.Context, msg *types.MsgCreateSub sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), - sdk.NewAttribute(sdk.AttributeKeySender, msg.Creator), + sdk.NewAttribute(sdk.AttributeKeySender, subspace.Creator), ), sdk.NewEvent( types.EventTypeCreateSubspace, @@ -61,7 +61,7 @@ func (k msgServer) CreateSubspace(goCtx context.Context, msg *types.MsgCreateSub }) return &types.MsgCreateSubspaceResponse{ - SubspaceID: subspaceID, + SubspaceID: subspace.ID, }, nil } @@ -69,24 +69,20 @@ func (k msgServer) CreateSubspace(goCtx context.Context, msg *types.MsgCreateSub func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspace) (*types.MsgEditSubspaceResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // Check the permission to edit - hasPermissions, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionChangeInfo) - if err != nil { - return nil, err - } - if !hasPermissions { - return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot edit this subspace") - } - // Check the if the subspace exists subspace, exists := k.GetSubspace(ctx, msg.SubspaceID) if !exists { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) } + // Check the permission to edit + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionChangeInfo) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot edit this subspace") + } + // Update the subspace and validate it updated := subspace.Update(types.NewSubspaceUpdate(msg.Name, msg.Description, msg.Owner, msg.Treasury)) - err = updated.Validate() + err := updated.Validate() if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) } @@ -113,20 +109,21 @@ func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspac func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUserGroup) (*types.MsgCreateUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // Check the permission first - hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Creator, types.PermissionSetPermissions) - if err != nil { - return nil, err - } - if !hasPermission { - return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot create user groups in this subspace") + // Check if the subspace exists + if !k.HasSubspace(ctx, msg.SubspaceID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) } - // Check if there is another group - if k.HasGroup(ctx, msg.SubspaceID, msg.GroupName) { + // Check if there is another group with the same name + if k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupName) { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group with name %s already exists", msg.GroupName) } + // Check the permission to create a group + if !k.HasPermission(ctx, msg.SubspaceID, msg.Creator, types.PermissionManageGroups) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot create user groups in this subspace") + } + // Store the group k.SaveUserGroup(ctx, msg.SubspaceID, msg.GroupName, msg.DefaultPermissions) @@ -150,20 +147,21 @@ func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUs func (k msgServer) DeleteUserGroup(goCtx context.Context, msg *types.MsgDeleteUserGroup) (*types.MsgDeleteUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // Check for permissions - hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) - if err != nil { - return nil, err - } - if !hasPermission { - return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot delete user groups in this subspace") + // Check if the subspace exists + if !k.HasSubspace(ctx, msg.SubspaceID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) } // Check if the group exists - if !k.HasGroup(ctx, msg.SubspaceID, msg.GroupName) { + if !k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupName) { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %s could not be found", msg.GroupName) } + // Check for permissions + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionManageGroups) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot delete user groups in this subspace") + } + // Delete the group k.Keeper.DeleteUserGroup(ctx, msg.SubspaceID, msg.GroupName) @@ -187,12 +185,18 @@ func (k msgServer) DeleteUserGroup(goCtx context.Context, msg *types.MsgDeleteUs func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUserToUserGroup) (*types.MsgAddUserToUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // Check the permissions - hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) - if err != nil { - return nil, err + // Check if the subspace exists + if !k.HasSubspace(ctx, msg.SubspaceID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) } - if !hasPermission { + + // Check if the group exists + if !k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupName) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %s could not be found", msg.GroupName) + } + + // Check the permissions + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage user group members in this subspace") } @@ -219,7 +223,7 @@ func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUs sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), ), sdk.NewEvent( - types.EventTypeEditSubspace, + types.EventTypeAddUserToGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), sdk.NewAttribute(types.AttributeKeyUser, msg.User), @@ -233,12 +237,18 @@ func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUs func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.MsgRemoveUserFromUserGroup) (*types.MsgRemoveUserFromUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // Check the permissions - hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) - if err != nil { - return nil, err + // Check if the subspace exists + if !k.HasSubspace(ctx, msg.SubspaceID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) + } + + // Check if the group exists + if !k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupName) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %s could not be found", msg.GroupName) } - if !hasPermission { + + // Check the permissions + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage user group members in this subspace") } @@ -252,11 +262,8 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user is not part of group %s", msg.GroupName) } - // Set the user group - err = k.RemoveUserFromGroup(ctx, msg.SubspaceID, msg.GroupName, user) - if err != nil { - return nil, err - } + // Remove the user group + k.RemoveUserFromGroup(ctx, msg.SubspaceID, msg.GroupName, user) ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( @@ -265,7 +272,7 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), ), sdk.NewEvent( - types.EventTypeEditSubspace, + types.EventTypeRemoveUserFromGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), sdk.NewAttribute(types.AttributeKeyUser, msg.User), @@ -279,17 +286,31 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg func (k msgServer) SetPermissions(goCtx context.Context, msg *types.MsgSetPermissions) (*types.MsgSetPermissionsResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // Check the permissions - hasPermission, err := k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) - if err != nil { - return nil, err + // Check if the subspace exists + if !k.HasSubspace(ctx, msg.SubspaceID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) } - if !hasPermission { + + // Check the permissions + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { return nil, sdkerrors.Wrapf(types.ErrPermissionDenied, "you cannot set other users permissions") } // Set the permissions k.Keeper.SetPermissions(ctx, msg.SubspaceID, msg.Target, msg.Permissions) + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), + ), + sdk.NewEvent( + types.EventTypeSetPermissions, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), + sdk.NewAttribute(types.AttributeKeyTarget, msg.Target), + ), + }) + return &types.MsgSetPermissionsResponse{}, nil } diff --git a/x/subspaces/keeper/msg_server_test.go b/x/subspaces/keeper/msg_server_test.go new file mode 100644 index 0000000000..48c9c9f03c --- /dev/null +++ b/x/subspaces/keeper/msg_server_test.go @@ -0,0 +1,1049 @@ +package keeper_test + +import ( + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +func (suite *KeeperTestsuite) TestMsgServer_CreateSubspace() { + blockTime := time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC) + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgCreateSubspace + shouldErr bool + expResponse *types.MsgCreateSubspaceResponse + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "subspace id not set returns error", + msg: types.NewMsgCreateSubspace( + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + ), + shouldErr: true, + }, + { + name: "invalid subspace returns error", + store: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + store.Set(types.SubspaceIDKey, types.GetSubspaceIDBytes(1)) + }, + msg: types.NewMsgCreateSubspace( + "", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + ), + shouldErr: true, + }, + { + name: "first subspace is created properly", + store: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + store.Set(types.SubspaceIDKey, types.GetSubspaceIDBytes(1)) + }, + msg: types.NewMsgCreateSubspace( + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + ), + shouldErr: false, + expResponse: &types.MsgCreateSubspaceResponse{SubspaceID: 1}, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69"), + ), + sdk.NewEvent( + types.EventTypeCreateSubspace, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + sdk.NewAttribute(types.AttributeKeySubspaceName, "Test subspace"), + sdk.NewAttribute(types.AttributeKeySubspaceCreator, "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69"), + sdk.NewAttribute(types.AttributeKeyCreationTime, "2020-01-01T12:00:00Z"), + ), + }, + check: func(ctx sdk.Context) { + // Make sure the subspace is stored + subspace, found := suite.k.GetSubspace(ctx, 1) + suite.Require().True(found) + suite.Require().Equal(types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), subspace) + + // Make sure the subspace id has increased + store := ctx.KVStore(suite.storeKey) + id := types.GetSubspaceIDFromBytes(store.Get(types.SubspaceIDKey)) + suite.Require().Equal(uint64(2), id) + }, + }, + { + name: "subspace has correct id when another subspace already exists", + store: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + store.Set(types.SubspaceIDKey, types.GetSubspaceIDBytes(1)) + + // Run the fist subspace creation message + msgServer := keeper.NewMsgServerImpl(suite.k) + _, err := msgServer.CreateSubspace(sdk.WrapSDKContext(ctx), types.NewMsgCreateSubspace( + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + )) + suite.Require().NoError(err) + }, + msg: types.NewMsgCreateSubspace( + "Another subspace", + "This is a second test subspace", + "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll", + "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll", + "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll", + ), + shouldErr: false, + expResponse: &types.MsgCreateSubspaceResponse{SubspaceID: 2}, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll"), + ), + sdk.NewEvent( + types.EventTypeCreateSubspace, + sdk.NewAttribute(types.AttributeKeySubspaceID, "2"), + sdk.NewAttribute(types.AttributeKeySubspaceName, "Another subspace"), + sdk.NewAttribute(types.AttributeKeySubspaceCreator, "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll"), + sdk.NewAttribute(types.AttributeKeyCreationTime, "2020-01-01T12:00:00Z"), + ), + }, + check: func(ctx sdk.Context) { + // Make sure the subspace is stored + subspace, found := suite.k.GetSubspace(ctx, 2) + suite.Require().True(found) + suite.Require().Equal(types.NewSubspace( + 2, + "Another subspace", + "This is a second test subspace", + "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll", + "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll", + "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), subspace) + + // Make sure the subspace id has increased + store := ctx.KVStore(suite.storeKey) + id := types.GetSubspaceIDFromBytes(store.Get(types.SubspaceIDKey)) + suite.Require().Equal(uint64(3), id) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + ctx = ctx.WithBlockTime(blockTime) + + if tc.store != nil { + tc.store(ctx) + } + + // Reset any event that might have been emitted during the setup + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + res, err := service.CreateSubspace(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expResponse, res) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_EditSubspace() { + blockTime := time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC) + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgEditSubspace + shouldErr bool + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "subspace not found returns error", + msg: types.NewMsgEditSubspace( + 1, + types.DoNotModify, + "This is a new description", + types.DoNotModify, + types.DoNotModify, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + check: func(ctx sdk.Context) { + _, found := suite.k.GetSubspace(ctx, 1) + suite.Require().False(found) + }, + }, + { + name: "missing permission returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + blockTime, + )) + }, + msg: types.NewMsgEditSubspace( + 1, + types.DoNotModify, + "This is a new description", + types.DoNotModify, + types.DoNotModify, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + check: func(ctx sdk.Context) { + subspace, found := suite.k.GetSubspace(ctx, 1) + suite.Require().True(found) + suite.Require().Equal(types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + blockTime, + ), subspace) + }, + }, + { + name: "invalid update returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + blockTime, + )) + }, + msg: types.NewMsgEditSubspace( + 1, + "", + "This is a new description", + types.DoNotModify, + types.DoNotModify, + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + ), + shouldErr: true, + check: func(ctx sdk.Context) { + subspace, found := suite.k.GetSubspace(ctx, 1) + suite.Require().True(found) + suite.Require().Equal(types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + blockTime, + ), subspace) + }, + }, + { + name: "existing subspace is updated correctly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + blockTime, + )) + suite.k.SetPermissions(ctx, 1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", types.PermissionChangeInfo) + }, + msg: types.NewMsgEditSubspace( + 1, + "This is a new name", + "This is a new description", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"), + ), + sdk.NewEvent( + types.EventTypeEditSubspace, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + ), + }, + check: func(ctx sdk.Context) { + subspace, found := suite.k.GetSubspace(ctx, 1) + suite.Require().True(found) + suite.Require().Equal(types.NewSubspace( + 1, + "This is a new name", + "This is a new description", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + blockTime, + ), subspace) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + ctx = ctx.WithBlockTime(blockTime) + + if tc.store != nil { + tc.store(ctx) + } + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + _, err := service.EditSubspace(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgCreateUserGroup + shouldErr bool + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "non existing subspace returns error", + msg: types.NewMsgCreateUserGroup( + 1, + "group", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "duplicated group returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + }, + msg: types.NewMsgCreateUserGroup( + 1, + "group", + types.PermissionWrite, + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + ), + shouldErr: true, + }, + { + name: "user without permission returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + msg: types.NewMsgCreateUserGroup( + 1, + "group", + types.PermissionWrite, + "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll", + ), + shouldErr: true, + }, + { + name: "group is created properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionChangeInfo) + suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionManageGroups) + }, + msg: types.NewMsgCreateUserGroup( + 1, + "another-group", + types.PermissionWrite, + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"), + ), + sdk.NewEvent( + types.EventTypeCreateUserGroup, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + sdk.NewAttribute(types.AttributeKeyUserGroupName, "another-group"), + ), + }, + check: func(ctx sdk.Context) { + suite.Require().True(suite.k.HasUserGroup(ctx, 1, "group")) + suite.Require().True(suite.k.HasUserGroup(ctx, 1, "another-group")) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + _, err := service.CreateUserGroup(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_DeleteUserGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgDeleteUserGroup + shouldErr bool + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "subspace not found returns error", + msg: types.NewMsgDeleteUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "group not found returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + msg: types.NewMsgDeleteUserGroup( + 1, + "group", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "no permission returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + }, + msg: types.NewMsgDeleteUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "existing group is deleted properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionManageGroups) + }, + msg: types.NewMsgDeleteUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"), + ), + sdk.NewEvent( + types.EventTypeDeleteUserGroup, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + sdk.NewAttribute(types.AttributeKeyUserGroupName, "group"), + ), + }, + check: func(ctx sdk.Context) { + hasGroup := suite.k.HasUserGroup(ctx, 1, "group") + suite.Require().False(hasGroup) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + _, err := service.DeleteUserGroup(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_AddUserToGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgAddUserToUserGroup + shouldErr bool + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "subspace not found returns error", + msg: types.NewMsgAddUserToUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "group not found returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + msg: types.NewMsgAddUserToUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "no permission returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + }, + msg: types.NewMsgAddUserToUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "user already part of group returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, "group", sdkAddr) + suite.Require().NoError(err) + }, + msg: types.NewMsgAddUserToUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "user not part of group is added correctly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionSetPermissions) + }, + msg: types.NewMsgAddUserToUserGroup( + 1, + "group", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"), + ), + sdk.NewEvent( + types.EventTypeAddUserToGroup, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + sdk.NewAttribute(types.AttributeKeyUserGroupName, "group"), + sdk.NewAttribute(types.AttributeKeyUser, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm"), + ), + }, + check: func(ctx sdk.Context) { + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + + result := suite.k.IsMemberOfGroup(ctx, 1, "group", sdkAddr) + suite.Require().True(result) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + _, err := service.AddUserToUserGroup(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgRemoveUserFromUserGroup + shouldErr bool + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "subspace not found returns error", + msg: types.NewMsgRemoveUserFromUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "group not found returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + msg: types.NewMsgRemoveUserFromUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "no permission returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + }, + msg: types.NewMsgRemoveUserFromUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "user not part of group returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + }, + msg: types.NewMsgRemoveUserFromUserGroup( + 1, + "group", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "user part of group is removes correctly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionSetPermissions) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, "group", sdkAddr) + suite.Require().NoError(err) + }, + msg: types.NewMsgRemoveUserFromUserGroup( + 1, + "group", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"), + ), + sdk.NewEvent( + types.EventTypeRemoveUserFromGroup, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + sdk.NewAttribute(types.AttributeKeyUserGroupName, "group"), + sdk.NewAttribute(types.AttributeKeyUser, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm"), + ), + }, + check: func(ctx sdk.Context) { + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + + result := suite.k.IsMemberOfGroup(ctx, 1, "group", sdkAddr) + suite.Require().False(result) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + _, err := service.RemoveUserFromUserGroup(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_SetPermissions() { + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgSetPermissions + shouldErr bool + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "subspace not found returns error", + msg: types.NewMsgSetPermissions( + 1, + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "no permission returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + msg: types.NewMsgSetPermissions( + 1, + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + types.PermissionWrite, + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + ), + shouldErr: true, + }, + { + name: "permissions are set correctly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionSetPermissions) + }, + msg: types.NewMsgSetPermissions( + 1, + "group", + types.PermissionWrite, + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"), + ), + sdk.NewEvent( + types.EventTypeSetPermissions, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + sdk.NewAttribute(types.AttributeKeyTarget, "group"), + ), + }, + check: func(ctx sdk.Context) { + permissions := suite.k.GetPermissions(ctx, 1, "group") + suite.Require().Equal(types.PermissionWrite, permissions) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + _, err := service.SetPermissions(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} diff --git a/x/subspaces/keeper/permissions.go b/x/subspaces/keeper/permissions.go index 2dd9839c33..8b49dd264b 100644 --- a/x/subspaces/keeper/permissions.go +++ b/x/subspaces/keeper/permissions.go @@ -2,7 +2,6 @@ package keeper import ( sdk "github.com/cosmos/cosmos-sdk/types" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) @@ -28,30 +27,30 @@ func (k Keeper) GetGroupsInheritedPermissions(ctx sdk.Context, subspaceID uint64 } // HasPermission checks whether the specific target has the given permission inside a specific subspace -func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, target string, permission types.Permission) (bool, error) { +func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, target string, permission types.Permission) bool { // Get the subspace to make sure the request is valid subspace, found := k.GetSubspace(ctx, subspaceID) if !found { - return false, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d does not exist", subspaceID) + return false } specificPermissions := k.GetPermissions(ctx, subspaceID, target) userAddr, err := sdk.AccAddressFromBech32(target) if err != nil { - return types.CheckPermission(specificPermissions, permission), nil + return types.CheckPermission(specificPermissions, permission) } // The owner of the subspaces has all the permissions by default if subspace.Owner == userAddr.String() { - return true, nil + return true } // Get the group permissions groupPermissions := k.GetGroupsInheritedPermissions(ctx, subspaceID, userAddr) // Check the combination of the permissions - return types.CheckPermission(types.CombinePermissions(specificPermissions, groupPermissions), permission), nil + return types.CheckPermission(types.CombinePermissions(specificPermissions, groupPermissions), permission) } // SetPermissions sets the given permission for the specific target inside a single subspace @@ -59,3 +58,9 @@ func (k Keeper) SetPermissions(ctx sdk.Context, subspaceID uint64, target string store := ctx.KVStore(k.storeKey) store.Set(types.PermissionStoreKey(subspaceID, target), types.MarshalPermission(permissions)) } + +// RemovePermissions removes the permission for the given target inside the provided subspace +func (k Keeper) RemovePermissions(ctx sdk.Context, subspaceID uint64, target string) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.PermissionStoreKey(subspaceID, target)) +} diff --git a/x/subspaces/keeper/permissions_test.go b/x/subspaces/keeper/permissions_test.go index 7c38a4bc04..9096f5202d 100644 --- a/x/subspaces/keeper/permissions_test.go +++ b/x/subspaces/keeper/permissions_test.go @@ -8,7 +8,7 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) -func (suite *KeeperTestsuite) TestGetPermissions() { +func (suite *KeeperTestsuite) TestKeeper_GetPermissions() { testCases := []struct { name string store func(ctx sdk.Context) @@ -29,12 +29,12 @@ func (suite *KeeperTestsuite) TestGetPermissions() { ctx, 1, "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", - types.PermissionWrite|types.PermissionAddLink, + types.PermissionWrite|types.PermissionManageGroups, ) }, subspaceID: 1, target: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", - expPermissions: types.PermissionWrite | types.PermissionAddLink, + expPermissions: types.PermissionWrite | types.PermissionManageGroups, }, { name: "found group returns the correct permission", @@ -62,7 +62,7 @@ func (suite *KeeperTestsuite) TestGetPermissions() { } } -func (suite *KeeperTestsuite) TestGetGroupsInheritedPermissions() { +func (suite *KeeperTestsuite) TestKeeper_GetGroupsInheritedPermissions() { testCases := []struct { name string store func(ctx sdk.Context) @@ -130,20 +130,19 @@ func (suite *KeeperTestsuite) TestGetGroupsInheritedPermissions() { } } -func (suite *KeeperTestsuite) TestHasPermission() { +func (suite *KeeperTestsuite) TestKeeper_HasPermission() { testCases := []struct { name string store func(ctx sdk.Context) subspaceID uint64 target string permission types.Permission - expError bool expResult bool }{ { - name: "subspace not found returns error", + name: "subspace not found returns false", subspaceID: 1, - expError: true, + expResult: false, }, { name: "group with permission returns true", @@ -162,7 +161,6 @@ func (suite *KeeperTestsuite) TestHasPermission() { subspaceID: 1, target: "group", permission: types.PermissionWrite, - expError: false, expResult: true, }, { @@ -181,7 +179,6 @@ func (suite *KeeperTestsuite) TestHasPermission() { subspaceID: 1, target: "group", permission: types.PermissionWrite, - expError: false, expResult: false, }, { @@ -200,7 +197,6 @@ func (suite *KeeperTestsuite) TestHasPermission() { subspaceID: 1, target: "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", permission: types.PermissionEverything, - expError: false, expResult: true, }, { @@ -227,7 +223,6 @@ func (suite *KeeperTestsuite) TestHasPermission() { subspaceID: 1, target: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", permission: types.PermissionWrite, - expError: false, expResult: true, }, { @@ -251,12 +246,11 @@ func (suite *KeeperTestsuite) TestHasPermission() { err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) suite.Require().NoError(err) - suite.k.SetPermissions(ctx, 1, userAddr.String(), types.PermissionAddLink) + suite.k.SetPermissions(ctx, 1, userAddr.String(), types.PermissionManageGroups) }, subspaceID: 1, target: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", - permission: types.PermissionAddLink, - expError: false, + permission: types.PermissionManageGroups, expResult: true, }, } @@ -269,18 +263,13 @@ func (suite *KeeperTestsuite) TestHasPermission() { tc.store(ctx) } - result, err := suite.k.HasPermission(ctx, tc.subspaceID, tc.target, tc.permission) - if tc.expError { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - suite.Require().Equal(tc.expResult, result) - } + result := suite.k.HasPermission(ctx, tc.subspaceID, tc.target, tc.permission) + suite.Require().Equal(tc.expResult, result) }) } } -func (suite *KeeperTestsuite) TestSetPermissions() { +func (suite *KeeperTestsuite) TestKeeper_SetPermissions() { testCases := []struct { name string store func(ctx sdk.Context) @@ -312,7 +301,7 @@ func (suite *KeeperTestsuite) TestSetPermissions() { { name: "existing permission is overridden", store: func(ctx sdk.Context) { - suite.k.SetPermissions(ctx, 1, "group", types.PermissionAddLink) + suite.k.SetPermissions(ctx, 1, "group", types.PermissionManageGroups) }, subspaceID: 1, target: "group", @@ -340,3 +329,51 @@ func (suite *KeeperTestsuite) TestSetPermissions() { }) } } + +func (suite *KeeperTestsuite) TestKeeper_RemovePermissions() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + target string + check func(ctx sdk.Context) + }{ + { + name: "permission is deleted for non existing target", + subspaceID: 1, + target: "group", + check: func(ctx sdk.Context) { + permission := suite.k.GetPermissions(ctx, 1, "group") + suite.Require().Equal(types.PermissionNothing, permission) + }, + }, + { + name: "permission is deleted for existing taget", + store: func(ctx sdk.Context) { + suite.k.SetPermissions(ctx, 1, "group", types.PermissionManageGroups) + }, + subspaceID: 1, + target: "group", + check: func(ctx sdk.Context) { + permission := suite.k.GetPermissions(ctx, 1, "group") + suite.Require().Equal(types.PermissionNothing, permission) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + suite.k.RemovePermissions(ctx, tc.subspaceID, tc.target) + + if tc.check != nil { + tc.check(ctx) + } + }) + } +} diff --git a/x/subspaces/keeper/subspaces.go b/x/subspaces/keeper/subspaces.go index 6e607ad3c8..b37762c7c8 100644 --- a/x/subspaces/keeper/subspaces.go +++ b/x/subspaces/keeper/subspaces.go @@ -33,6 +33,12 @@ func (k Keeper) SaveSubspace(ctx sdk.Context, subspace types.Subspace) { k.Logger(ctx).Info("subspace saved", "id", subspace.ID) } +// HasSubspace tells whether the given subspace exists or not +func (k Keeper) HasSubspace(ctx sdk.Context, subspaceID uint64) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.SubspaceKey(subspaceID)) +} + // GetSubspace returns the subspace associated with the given id. // If there is no subspace associated with the given id the function will return an empty subspace and false. func (k Keeper) GetSubspace(ctx sdk.Context, subspaceID uint64) (subspace types.Subspace, found bool) { diff --git a/x/subspaces/keeper/subspaces_test.go b/x/subspaces/keeper/subspaces_test.go index 2750c7245e..b90a1d8ac8 100644 --- a/x/subspaces/keeper/subspaces_test.go +++ b/x/subspaces/keeper/subspaces_test.go @@ -8,7 +8,7 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) -func (suite *KeeperTestsuite) TestGetSubspaceID() { +func (suite *KeeperTestsuite) TestKeeper_GetSubspaceID() { testCases := []struct { name string store func(ctx sdk.Context) @@ -49,7 +49,7 @@ func (suite *KeeperTestsuite) TestGetSubspaceID() { } } -func (suite *KeeperTestsuite) TestSetSubspaceID() { +func (suite *KeeperTestsuite) TestKeeper_SetSubspaceID() { testCases := []struct { name string id uint64 @@ -86,7 +86,7 @@ func (suite *KeeperTestsuite) TestSetSubspaceID() { } } -func (suite *KeeperTestsuite) TestSaveSubspace() { +func (suite *KeeperTestsuite) TestKeeper_SaveSubspace() { testCases := []struct { name string store func(ctx sdk.Context) @@ -173,7 +173,7 @@ func (suite *KeeperTestsuite) TestSaveSubspace() { } } -func (suite *KeeperTestsuite) TestGetSubspace() { +func (suite *KeeperTestsuite) TestKeeper_GetSubspace() { testCases := []struct { name string store func(ctx sdk.Context) diff --git a/x/subspaces/module.go b/x/subspaces/module.go index 4340c8d66f..471c3a3118 100644 --- a/x/subspaces/module.go +++ b/x/subspaces/module.go @@ -147,7 +147,7 @@ func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sd func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, data json.RawMessage) []abci.ValidatorUpdate { var genesisState types.GenesisState cdc.MustUnmarshalJSON(data, &genesisState) - am.keeper.InitGenesis(ctx, &genesisState) + am.keeper.InitGenesis(ctx, genesisState) return []abci.ValidatorUpdate{} } diff --git a/x/subspaces/types/events.go b/x/subspaces/types/events.go index ce7953ea12..d45db8b996 100644 --- a/x/subspaces/types/events.go +++ b/x/subspaces/types/events.go @@ -8,6 +8,7 @@ const ( EventTypeDeleteUserGroup = "delete_user_group" EventTypeAddUserToGroup = "add_group_member" EventTypeRemoveUserFromGroup = "delete_group_member" + EventTypeSetPermissions = "set_permissions" AttributeValueCategory = ModuleName AttributeKeySubspaceID = "subspace_id" @@ -16,4 +17,5 @@ const ( AttributeKeyCreationTime = "creation_date" AttributeKeyUserGroupName = "user_group_name" AttributeKeyUser = "user" + AttributeKeyTarget = "target" ) diff --git a/x/subspaces/types/genesis.go b/x/subspaces/types/genesis.go index a3ad7c0bf6..cfca3586ed 100644 --- a/x/subspaces/types/genesis.go +++ b/x/subspaces/types/genesis.go @@ -2,6 +2,26 @@ package types import "fmt" +// NewACLEntry returns a new ACLEntry instance +func NewACLEntry(subspaceID uint64, target string, permissions Permission) ACLEntry { + return ACLEntry{ + SubspaceId: subspaceID, + Target: target, + Permissions: permissions, + } +} + +// NewUserGroup returns a new UserGroup instance +func NewUserGroup(subspaceID uint64, groupName string, members []string) UserGroup { + return UserGroup{ + SubspaceID: subspaceID, + Name: groupName, + Members: members, + } +} + +// ------------------------------------------------------------------------------------------------------------------- + // NewGenesisState creates a new genesis state func NewGenesisState(subspaces []Subspace, acl []ACLEntry, userGroups []UserGroup) *GenesisState { return &GenesisState{ diff --git a/x/subspaces/types/genesis.pb.go b/x/subspaces/types/genesis.pb.go index 485c4c0fc9..32f50bd6bc 100644 --- a/x/subspaces/types/genesis.pb.go +++ b/x/subspaces/types/genesis.pb.go @@ -89,7 +89,7 @@ type ACLEntry struct { // Either group name or user address SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` Target string `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty"` - Permissions []byte `protobuf:"bytes,3,opt,name=permissions,proto3" json:"permissions,omitempty"` + Permissions uint32 `protobuf:"varint,3,opt,name=permissions,proto3" json:"permissions,omitempty"` } func (m *ACLEntry) Reset() { *m = ACLEntry{} } @@ -139,19 +139,19 @@ func (m *ACLEntry) GetTarget() string { return "" } -func (m *ACLEntry) GetPermissions() []byte { +func (m *ACLEntry) GetPermissions() uint32 { if m != nil { return m.Permissions } - return nil + return 0 } // UsersEntry contains the data of a slice of users associated to a subspace // with a specific id type UserGroup struct { - SubspaceID string `protobuf:"bytes,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - Users []string `protobuf:"bytes,3,rep,name=users,proto3" json:"users,omitempty"` + Members []string `protobuf:"bytes,3,rep,name=members,proto3" json:"members,omitempty"` } func (m *UserGroup) Reset() { *m = UserGroup{} } @@ -187,11 +187,11 @@ func (m *UserGroup) XXX_DiscardUnknown() { var xxx_messageInfo_UserGroup proto.InternalMessageInfo -func (m *UserGroup) GetSubspaceID() string { +func (m *UserGroup) GetSubspaceID() uint64 { if m != nil { return m.SubspaceID } - return "" + return 0 } func (m *UserGroup) GetName() string { @@ -201,9 +201,9 @@ func (m *UserGroup) GetName() string { return "" } -func (m *UserGroup) GetUsers() []string { +func (m *UserGroup) GetMembers() []string { if m != nil { - return m.Users + return m.Members } return nil } @@ -217,34 +217,109 @@ func init() { func init() { proto.RegisterFile("desmos/subspaces/v1/genesis.proto", fileDescriptor_bce8af665337782b) } var fileDescriptor_bce8af665337782b = []byte{ - // 388 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x52, 0x3f, 0xeb, 0xda, 0x50, - 0x14, 0xcd, 0xfb, 0xc5, 0x8a, 0x79, 0x91, 0x0e, 0xaf, 0x52, 0x82, 0xd0, 0x24, 0xcd, 0x94, 0xa5, - 0x79, 0x68, 0xb7, 0xd2, 0xc5, 0x58, 0x11, 0xc1, 0x29, 0xd2, 0xa5, 0x8b, 0x24, 0xfa, 0x48, 0x03, - 0x26, 0x2f, 0xe4, 0xbe, 0x48, 0xfd, 0x16, 0x1d, 0x3b, 0xfa, 0x71, 0x1c, 0x9d, 0x4a, 0x27, 0x29, - 0x71, 0xe9, 0xc7, 0x28, 0xf9, 0x67, 0x2d, 0x95, 0x6e, 0xf7, 0xdc, 0x77, 0xce, 0x3d, 0xf7, 0x1d, - 0x2e, 0x7e, 0xbd, 0x65, 0x10, 0x73, 0xa0, 0x90, 0x07, 0x90, 0xfa, 0x1b, 0x06, 0x74, 0x3f, 0xa2, - 0x21, 0x4b, 0x18, 0x44, 0xe0, 0xa4, 0x19, 0x17, 0x9c, 0xbc, 0xa8, 0x29, 0xce, 0x8d, 0xe2, 0xec, - 0x47, 0xc3, 0x41, 0xc8, 0x43, 0x5e, 0xbd, 0xd3, 0xb2, 0xaa, 0xa9, 0x43, 0xeb, 0xd1, 0xb4, 0x16, - 0xd4, 0x1c, 0xeb, 0x3b, 0xc2, 0xfd, 0x79, 0x6d, 0xb0, 0x12, 0xbe, 0x60, 0x64, 0x82, 0x95, 0x1b, - 0x5f, 0x43, 0xa6, 0x6c, 0xab, 0xe3, 0x57, 0xce, 0x03, 0x4f, 0x67, 0xd5, 0x00, 0xb7, 0x73, 0xba, - 0x18, 0x92, 0xf7, 0x47, 0x45, 0xde, 0x63, 0xd9, 0xdf, 0xec, 0x34, 0xf9, 0x3f, 0xe2, 0xc9, 0x74, - 0x39, 0x4b, 0x44, 0x76, 0x70, 0xd5, 0x52, 0x5c, 0x5c, 0x0c, 0x79, 0x32, 0x5d, 0x7a, 0xa5, 0x8c, - 0xcc, 0xb0, 0x9a, 0x03, 0xcb, 0xd6, 0x61, 0xc6, 0xf3, 0x14, 0xb4, 0xa7, 0x6a, 0x8a, 0xfe, 0x70, - 0xca, 0x47, 0x60, 0xd9, 0xbc, 0xa4, 0x35, 0x3b, 0xe0, 0xbc, 0x6d, 0x80, 0xc5, 0x70, 0xaf, 0x35, - 0x21, 0x06, 0x56, 0x5b, 0xdd, 0x3a, 0xda, 0x6a, 0xc8, 0x44, 0x76, 0xc7, 0xc3, 0x6d, 0x6b, 0xb1, - 0x25, 0x2f, 0x71, 0x57, 0xf8, 0x59, 0xc8, 0x84, 0xf6, 0x64, 0x22, 0x5b, 0xf1, 0x1a, 0x44, 0x4c, - 0xac, 0xa6, 0x2c, 0x8b, 0x23, 0x80, 0x88, 0x27, 0xa0, 0xc9, 0x26, 0xb2, 0xfb, 0xde, 0x7d, 0xcb, - 0x4a, 0xb1, 0x72, 0xdb, 0x82, 0xd0, 0x7f, 0x7d, 0x14, 0xf7, 0x79, 0x71, 0x31, 0x70, 0x1b, 0xd6, - 0xe2, 0xc3, 0x5f, 0xbe, 0x04, 0x77, 0x12, 0x3f, 0x66, 0x8d, 0x6b, 0x55, 0x93, 0x01, 0x7e, 0x56, - 0x7e, 0x03, 0xaa, 0xfc, 0x14, 0xaf, 0x06, 0xef, 0x7a, 0xdf, 0x8e, 0x06, 0xfa, 0x75, 0x34, 0x90, - 0xbb, 0x3c, 0x15, 0x3a, 0x3a, 0x17, 0x3a, 0xfa, 0x59, 0xe8, 0xe8, 0xeb, 0x55, 0x97, 0xce, 0x57, - 0x5d, 0xfa, 0x71, 0xd5, 0xa5, 0x4f, 0xe3, 0x30, 0x12, 0x9f, 0xf3, 0xc0, 0xd9, 0xf0, 0x98, 0xd6, - 0x71, 0xbd, 0xd9, 0xf9, 0x01, 0x34, 0x35, 0xdd, 0x8f, 0xe9, 0x97, 0xbb, 0x5b, 0x10, 0x87, 0x94, - 0x41, 0xd0, 0xad, 0xce, 0xe0, 0xed, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf5, 0x95, 0x9a, 0x3b, - 0x7a, 0x02, 0x00, 0x00, + // 394 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xbf, 0x8a, 0xdb, 0x40, + 0x10, 0xc6, 0xb5, 0x27, 0x73, 0x39, 0xad, 0x92, 0x14, 0x9b, 0x10, 0xc4, 0x41, 0x24, 0xc5, 0x95, + 0x9a, 0x68, 0x39, 0xa7, 0x0b, 0x69, 0x2c, 0xc7, 0x18, 0x83, 0x2b, 0x99, 0x34, 0x69, 0x8c, 0x64, + 0x2f, 0x8a, 0xc0, 0xd2, 0x8a, 0x9d, 0x95, 0x89, 0xdf, 0x22, 0x65, 0x4a, 0x3f, 0x8e, 0x4b, 0x97, + 0xa9, 0x8c, 0x91, 0x9b, 0x3c, 0x46, 0xd0, 0x3f, 0xdb, 0x01, 0x71, 0xdd, 0xcc, 0xec, 0xf7, 0x7d, + 0xbf, 0x61, 0x58, 0xfc, 0x61, 0xc5, 0x20, 0xe1, 0x40, 0x21, 0x0f, 0x21, 0x0b, 0x96, 0x0c, 0xe8, + 0xe6, 0x89, 0x46, 0x2c, 0x65, 0x10, 0x83, 0x9b, 0x09, 0x2e, 0x39, 0x79, 0x53, 0x4b, 0xdc, 0x8b, + 0xc4, 0xdd, 0x3c, 0x3d, 0xbe, 0x8d, 0x78, 0xc4, 0xab, 0x77, 0x5a, 0x56, 0xb5, 0xf4, 0xb1, 0xdf, + 0x95, 0xd6, 0x36, 0xb5, 0xa6, 0x7f, 0x42, 0xf8, 0xe5, 0xa4, 0x06, 0xcc, 0x65, 0x20, 0x19, 0x19, + 0x62, 0xed, 0xa2, 0x37, 0x90, 0xad, 0x3a, 0xfa, 0xe0, 0xbd, 0xdb, 0xc1, 0x74, 0xe7, 0x4d, 0xe3, + 0xf5, 0xf6, 0x47, 0x4b, 0xf1, 0xaf, 0x2e, 0xf2, 0x05, 0xab, 0xc1, 0x72, 0x6d, 0xa8, 0xcf, 0x98, + 0x87, 0xa3, 0xd9, 0x38, 0x95, 0x62, 0xeb, 0xe9, 0xa5, 0xb9, 0x38, 0x5a, 0xea, 0x70, 0x34, 0xf3, + 0x4b, 0x1b, 0x19, 0x63, 0x3d, 0x07, 0x26, 0x16, 0x91, 0xe0, 0x79, 0x06, 0xc6, 0x5d, 0x95, 0x62, + 0x76, 0xa6, 0x7c, 0x03, 0x26, 0x26, 0xa5, 0xac, 0xd9, 0x01, 0xe7, 0xed, 0x00, 0x3e, 0x3f, 0xfc, + 0xde, 0x59, 0xe8, 0xef, 0xce, 0x42, 0x7d, 0x8e, 0x1f, 0x5a, 0x1c, 0xb1, 0xb0, 0xde, 0x26, 0x2c, + 0xe2, 0x95, 0x81, 0x6c, 0xe4, 0xf4, 0x7c, 0xdc, 0x8e, 0xa6, 0x2b, 0xf2, 0x0e, 0xdf, 0xcb, 0x40, + 0x44, 0x4c, 0x1a, 0x77, 0x36, 0x72, 0x34, 0xbf, 0xe9, 0x88, 0x8d, 0xf5, 0x8c, 0x89, 0x24, 0x06, + 0x88, 0x79, 0x0a, 0x86, 0x6a, 0x23, 0xe7, 0x95, 0x7f, 0x3b, 0xba, 0x01, 0x4a, 0xac, 0x5d, 0x36, + 0x23, 0xb4, 0x83, 0xe8, 0xbd, 0x2e, 0x8e, 0x16, 0x6e, 0x0f, 0x38, 0xfd, 0xfa, 0xdf, 0x06, 0x04, + 0xf7, 0xd2, 0x20, 0x61, 0x0d, 0xbf, 0xaa, 0x89, 0x81, 0x5f, 0x24, 0x2c, 0x09, 0x99, 0x80, 0xea, + 0xaa, 0x9a, 0xdf, 0xb6, 0x57, 0xaa, 0x37, 0xdb, 0x17, 0x26, 0x3a, 0x14, 0x26, 0x3a, 0x15, 0x26, + 0xfa, 0x75, 0x36, 0x95, 0xc3, 0xd9, 0x54, 0xfe, 0x9c, 0x4d, 0xe5, 0xfb, 0x20, 0x8a, 0xe5, 0x8f, + 0x3c, 0x74, 0x97, 0x3c, 0xa1, 0xf5, 0x19, 0x3f, 0xae, 0x83, 0x10, 0x9a, 0x9a, 0x6e, 0x06, 0xf4, + 0xe7, 0xcd, 0x1f, 0x91, 0xdb, 0x8c, 0x41, 0x78, 0x5f, 0x7d, 0x8f, 0x4f, 0xff, 0x02, 0x00, 0x00, + 0xff, 0xff, 0x91, 0xf4, 0x05, 0xa7, 0x92, 0x02, 0x00, 0x00, } +func (this *GenesisState) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*GenesisState) + if !ok { + that2, ok := that.(GenesisState) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if len(this.Subspaces) != len(that1.Subspaces) { + return false + } + for i := range this.Subspaces { + if !this.Subspaces[i].Equal(&that1.Subspaces[i]) { + return false + } + } + if len(this.ACL) != len(that1.ACL) { + return false + } + for i := range this.ACL { + if !this.ACL[i].Equal(&that1.ACL[i]) { + return false + } + } + if len(this.UserGroups) != len(that1.UserGroups) { + return false + } + for i := range this.UserGroups { + if !this.UserGroups[i].Equal(&that1.UserGroups[i]) { + return false + } + } + return true +} +func (this *ACLEntry) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*ACLEntry) + if !ok { + that2, ok := that.(ACLEntry) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.SubspaceId != that1.SubspaceId { + return false + } + if this.Target != that1.Target { + return false + } + if this.Permissions != that1.Permissions { + return false + } + return true +} func (this *UserGroup) Equal(that interface{}) bool { if that == nil { return this == nil @@ -270,11 +345,11 @@ func (this *UserGroup) Equal(that interface{}) bool { if this.Name != that1.Name { return false } - if len(this.Users) != len(that1.Users) { + if len(this.Members) != len(that1.Members) { return false } - for i := range this.Users { - if this.Users[i] != that1.Users[i] { + for i := range this.Members { + if this.Members[i] != that1.Members[i] { return false } } @@ -365,12 +440,10 @@ func (m *ACLEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Permissions) > 0 { - i -= len(m.Permissions) - copy(dAtA[i:], m.Permissions) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Permissions))) + if m.Permissions != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.Permissions)) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x18 } if len(m.Target) > 0 { i -= len(m.Target) @@ -407,11 +480,11 @@ func (m *UserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Users) > 0 { - for iNdEx := len(m.Users) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Users[iNdEx]) - copy(dAtA[i:], m.Users[iNdEx]) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Users[iNdEx]))) + if len(m.Members) > 0 { + for iNdEx := len(m.Members) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Members[iNdEx]) + copy(dAtA[i:], m.Members[iNdEx]) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.Members[iNdEx]))) i-- dAtA[i] = 0x1a } @@ -423,12 +496,10 @@ func (m *UserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - if len(m.SubspaceID) > 0 { - i -= len(m.SubspaceID) - copy(dAtA[i:], m.SubspaceID) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.SubspaceID))) + if m.SubspaceID != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.SubspaceID)) i-- - dAtA[i] = 0xa + dAtA[i] = 0x8 } return len(dAtA) - i, nil } @@ -484,9 +555,8 @@ func (m *ACLEntry) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } - l = len(m.Permissions) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) + if m.Permissions != 0 { + n += 1 + sovGenesis(uint64(m.Permissions)) } return n } @@ -497,16 +567,15 @@ func (m *UserGroup) Size() (n int) { } var l int _ = l - l = len(m.SubspaceID) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) + if m.SubspaceID != 0 { + n += 1 + sovGenesis(uint64(m.SubspaceID)) } l = len(m.Name) if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } - if len(m.Users) > 0 { - for _, s := range m.Users { + if len(m.Members) > 0 { + for _, s := range m.Members { l = len(s) n += 1 + l + sovGenesis(uint64(l)) } @@ -753,10 +822,10 @@ func (m *ACLEntry) Unmarshal(dAtA []byte) error { m.Target = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) } - var byteLen int + m.Permissions = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -766,26 +835,11 @@ func (m *ACLEntry) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - byteLen |= int(b&0x7F) << shift + m.Permissions |= uint32(b&0x7F) << shift if b < 0x80 { break } } - if byteLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + byteLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Permissions = append(m.Permissions[:0], dAtA[iNdEx:postIndex]...) - if m.Permissions == nil { - m.Permissions = []byte{} - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) @@ -837,10 +891,10 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) } - var stringLen uint64 + m.SubspaceID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -850,24 +904,11 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.SubspaceID |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SubspaceID = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) @@ -902,7 +943,7 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Users", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Members", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -930,7 +971,7 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Users = append(m.Users, string(dAtA[iNdEx:postIndex])) + m.Members = append(m.Members, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex default: iNdEx = preIndex diff --git a/x/subspaces/types/keys.go b/x/subspaces/types/keys.go index f781503e18..55e9764599 100644 --- a/x/subspaces/types/keys.go +++ b/x/subspaces/types/keys.go @@ -1,6 +1,10 @@ package types -import "encoding/binary" +import ( + "encoding/binary" + + sdk "github.com/cosmos/cosmos-sdk/types" +) // DONTCOVER @@ -25,9 +29,9 @@ const ( var ( SubspacePrefix = []byte{0x00} SubspaceIDKey = []byte{0x01} - ACLStorePrefix = []byte{0x02} + PermissionsStorePrefix = []byte{0x02} GroupsPrefix = []byte{0x03} - GroupMembersStorePrefix = []byte{0x4} + GroupMembersStorePrefix = []byte{0x04} ) // GetSubspaceIDBytes returns the byte representation of the subspaceID @@ -47,19 +51,22 @@ func SubspaceKey(subspaceID uint64) []byte { return append(SubspacePrefix, GetSubspaceIDBytes(subspaceID)...) } -// ACLStoreKey returns the key used to store the entire ACL for a given subspace -func ACLStoreKey(subspaceID uint64) []byte { - return append(ACLStorePrefix, GetSubspaceIDBytes(subspaceID)...) +// PermissionsStoreKey returns the key used to store the entire ACL for a given subspace +func PermissionsStoreKey(subspaceID uint64) []byte { + return append(PermissionsStorePrefix, GetSubspaceIDBytes(subspaceID)...) } -// PermissionStoreKey returns the key used to store the permission for the given target inside the given subspace -func PermissionStoreKey(subspaceID uint64, target string) []byte { - return append(ACLStoreKey(subspaceID), []byte(target)...) +func GetTargetBytes(target string) []byte { + return []byte(target) } -// GroupsStoreKey returns the key used to store all the groups of a given subspace -func GroupsStoreKey(subspaceID uint64) []byte { - return append(GroupsPrefix, GetSubspaceIDBytes(subspaceID)...) +func GetTargetFromBytes(bz []byte) string { + return string(bz) +} + +// PermissionStoreKey returns the key used to store the permission for the given target inside the given subspace +func PermissionStoreKey(subspaceID uint64, target string) []byte { + return append(PermissionsStoreKey(subspaceID), GetTargetBytes(target)...) } // GetGroupNameBytes returns the key byte representation of the groupName @@ -72,28 +79,33 @@ func GetGroupNameFromBytes(bz []byte) string { return string(bz) } +// GroupsStoreKey returns the key used to store all the groups of a given subspace +func GroupsStoreKey(subspaceID uint64) []byte { + return append(GroupsPrefix, GetSubspaceIDBytes(subspaceID)...) +} + // GroupStoreKey returns the key used to store a group for a subspace func GroupStoreKey(subspaceID uint64, groupName string) []byte { return append(GroupsStoreKey(subspaceID), GetGroupNameBytes(groupName)...) } -// GroupMembersStoreKey returns the key used to store all the members of the given group inside the given subspace -func GroupMembersStoreKey(subspaceID uint64, groupName string) []byte { - return append(append(GroupMembersStorePrefix, GetSubspaceIDBytes(subspaceID)...), GetGroupNameBytes(groupName)...) -} - // GetGroupMemberBytes returns the key byte representation of the member -func GetGroupMemberBytes(member string) []byte { - return []byte(member) +func GetGroupMemberBytes(member sdk.AccAddress) []byte { + return member } // GetGroupMemberFromBytes returns member in string format from a byte array -func GetGroupMemberFromBytes(bz []byte) string { - return string(bz) +func GetGroupMemberFromBytes(bz []byte) sdk.AccAddress { + return bz +} + +// GroupMembersStoreKey returns the key used to store all the members of the given group inside the given subspace +func GroupMembersStoreKey(subspaceID uint64, groupName string) []byte { + return append(append(GroupMembersStorePrefix, GetSubspaceIDBytes(subspaceID)...), GetGroupNameBytes(groupName)...) } // GroupMemberStoreKey returns the key used to store the membership of the given user to the // specified group inside the provided subspace -func GroupMemberStoreKey(subspaceID uint64, groupName string, user string) []byte { - return append(GroupStoreKey(subspaceID, groupName), GetGroupMemberBytes(user)...) +func GroupMemberStoreKey(subspaceID uint64, groupName string, user sdk.AccAddress) []byte { + return append(GroupMembersStoreKey(subspaceID, groupName), GetGroupMemberBytes(user)...) } diff --git a/x/subspaces/types/msgs.go b/x/subspaces/types/msgs.go index e625a03894..a8a7a69bd7 100644 --- a/x/subspaces/types/msgs.go +++ b/x/subspaces/types/msgs.go @@ -8,7 +8,7 @@ import ( ) // NewMsgCreateSubspace creates a new MsgCreateSubspace instance -func NewMsgCreateSubspace(name, description, owner, treasury, creator string) *MsgCreateSubspace { +func NewMsgCreateSubspace(name, description, treasury, owner, creator string) *MsgCreateSubspace { if owner == "" { // If the owner is empty, set the creator as the owner owner = creator @@ -17,8 +17,8 @@ func NewMsgCreateSubspace(name, description, owner, treasury, creator string) *M return &MsgCreateSubspace{ Name: name, Description: description, - Owner: owner, Treasury: treasury, + Owner: owner, Creator: creator, } } @@ -69,13 +69,13 @@ func (msg MsgCreateSubspace) GetSigners() []sdk.AccAddress { // -------------------------------------------------------------------------------------------------------------------- // NewMsgEditSubspace creates a new MsgEditSubspace instance -func NewMsgEditSubspace(subspaceID uint64, name, description, owner, treasury, signer string) *MsgEditSubspace { +func NewMsgEditSubspace(subspaceID uint64, name, description, treasury, owner, signer string) *MsgEditSubspace { return &MsgEditSubspace{ SubspaceID: subspaceID, Name: name, Description: description, - Owner: owner, Treasury: treasury, + Owner: owner, Signer: signer, } } diff --git a/x/subspaces/types/msgs.pb.go b/x/subspaces/types/msgs.pb.go index aac9e20208..95328f2cc5 100644 --- a/x/subspaces/types/msgs.pb.go +++ b/x/subspaces/types/msgs.pb.go @@ -32,8 +32,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type MsgCreateSubspace struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` - Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` - Treasury string `protobuf:"bytes,4,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + Treasury string `protobuf:"bytes,3,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + Owner string `protobuf:"bytes,4,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` Creator string `protobuf:"bytes,5,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` } @@ -120,8 +120,8 @@ type MsgEditSubspace struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` - Owner string `protobuf:"bytes,4,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` - Treasury string `protobuf:"bytes,5,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + Treasury string `protobuf:"bytes,4,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + Owner string `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` Signer string `protobuf:"bytes,6,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` } @@ -743,58 +743,57 @@ func init() { func init() { proto.RegisterFile("desmos/subspaces/v1/msgs.proto", fileDescriptor_c16a431ff9a3b35b) } var fileDescriptor_c16a431ff9a3b35b = []byte{ - // 803 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0xcf, 0x6f, 0xd3, 0x48, - 0x14, 0xc7, 0xe3, 0x24, 0xcd, 0xb6, 0xaf, 0x3f, 0xb2, 0x75, 0xb7, 0xdb, 0xd4, 0xbb, 0x6b, 0xaf, - 0xa6, 0x55, 0x77, 0xbb, 0xea, 0xc6, 0x6a, 0x76, 0x25, 0x50, 0x6f, 0x84, 0x16, 0x54, 0x89, 0x00, - 0x72, 0xe1, 0xc2, 0xa5, 0x72, 0xe2, 0xc1, 0xb5, 0x88, 0x33, 0x91, 0xc7, 0x09, 0xf4, 0xdc, 0x0b, - 0xc7, 0x4a, 0xfc, 0x03, 0xfd, 0x43, 0xb8, 0x22, 0x71, 0xec, 0x91, 0x93, 0x85, 0x52, 0x0e, 0xc0, - 0xd1, 0x7f, 0x01, 0xf2, 0xf8, 0x47, 0x1c, 0x27, 0xa6, 0x09, 0xca, 0x01, 0x71, 0xb3, 0xdf, 0xfb, - 0xcc, 0x8f, 0xf7, 0x7d, 0x33, 0xef, 0x0d, 0x88, 0x1a, 0xa6, 0x26, 0xa1, 0x32, 0xed, 0xd4, 0x69, - 0x5b, 0x6d, 0x60, 0x2a, 0x77, 0x77, 0x65, 0x93, 0xea, 0xb4, 0xdc, 0xb6, 0x88, 0x4d, 0xf8, 0x15, - 0xdf, 0x5f, 0x8e, 0xfc, 0xe5, 0xee, 0xae, 0xf0, 0x8b, 0x4e, 0x74, 0xc2, 0xfc, 0xb2, 0xf7, 0xe5, - 0xa3, 0x02, 0x1a, 0x35, 0x55, 0xf8, 0xe3, 0x33, 0xe8, 0x2c, 0x0b, 0xcb, 0x35, 0xaa, 0xdf, 0xb6, - 0xb0, 0x6a, 0xe3, 0xa3, 0xc0, 0xc7, 0x6f, 0x40, 0xbe, 0xa5, 0x9a, 0xb8, 0xc4, 0xfd, 0xc9, 0xfd, - 0x3d, 0x57, 0x2d, 0xba, 0x8e, 0x34, 0x7f, 0xaa, 0x9a, 0xcd, 0x3d, 0xe4, 0x59, 0x91, 0xc2, 0x9c, - 0xfc, 0x4d, 0x98, 0xd7, 0x30, 0x6d, 0x58, 0x46, 0xdb, 0x36, 0x48, 0xab, 0x94, 0x65, 0xec, 0xaf, - 0xae, 0x23, 0xf1, 0x3e, 0x1b, 0x73, 0x22, 0x25, 0x8e, 0xf2, 0x5b, 0x30, 0x43, 0x9e, 0xb7, 0xb0, - 0x55, 0xca, 0xb1, 0x31, 0x3f, 0xbb, 0x8e, 0xb4, 0xe0, 0x8f, 0x61, 0x66, 0xa4, 0xf8, 0x6e, 0x5e, - 0x86, 0x59, 0xdb, 0xc2, 0x2a, 0xed, 0x58, 0xa7, 0xa5, 0x3c, 0x43, 0x57, 0x5c, 0x47, 0x2a, 0xfa, - 0x68, 0xe8, 0x41, 0x4a, 0x04, 0xf1, 0x3b, 0xf0, 0x53, 0xc3, 0x8b, 0x84, 0x58, 0xa5, 0x19, 0xc6, - 0xf3, 0xae, 0x23, 0x2d, 0xf9, 0x7c, 0xe0, 0x40, 0x4a, 0x88, 0xec, 0xcd, 0xbe, 0xbc, 0x90, 0x32, - 0x1f, 0x2f, 0xa4, 0x0c, 0xaa, 0xc3, 0xfa, 0x90, 0x08, 0x0a, 0xa6, 0x6d, 0xd2, 0xa2, 0x98, 0x3f, - 0x80, 0xf9, 0x50, 0xb4, 0x63, 0x43, 0x63, 0x9a, 0xe4, 0xab, 0x9b, 0x3d, 0x47, 0x82, 0x10, 0x3d, - 0xdc, 0xef, 0x47, 0x1d, 0x43, 0x91, 0x02, 0xe1, 0xdf, 0xa1, 0x86, 0xde, 0x64, 0xa1, 0x58, 0xa3, - 0xfa, 0x81, 0x66, 0xd8, 0x91, 0xce, 0xd3, 0x99, 0x3a, 0x4a, 0x57, 0x76, 0x82, 0x74, 0xe5, 0xbe, - 0x21, 0x5d, 0xf9, 0xf1, 0xd3, 0x35, 0x33, 0x4e, 0xba, 0xb6, 0xa1, 0x40, 0x0d, 0xdd, 0x9b, 0xb9, - 0xc0, 0xf0, 0x65, 0xd7, 0x91, 0x16, 0x83, 0x58, 0x99, 0x1d, 0x29, 0x01, 0x10, 0xcb, 0xd5, 0x3a, - 0xac, 0x25, 0x64, 0x0c, 0x33, 0x85, 0xce, 0xb3, 0xc0, 0x47, 0x79, 0x7c, 0x4c, 0xb1, 0x75, 0xd7, - 0x22, 0x9d, 0xf6, 0xb4, 0x54, 0xfe, 0x1f, 0x40, 0xf7, 0xe6, 0x3b, 0x8e, 0x69, 0xbd, 0xea, 0x3a, - 0xd2, 0xb2, 0x3f, 0xae, 0xef, 0x43, 0xca, 0x1c, 0xfb, 0xb9, 0xef, 0xc9, 0xfe, 0x00, 0x56, 0x34, - 0xfc, 0x54, 0xed, 0x34, 0xed, 0xe3, 0x36, 0xb6, 0x4c, 0x83, 0x52, 0x83, 0xb4, 0x28, 0x93, 0x7f, - 0xb1, 0x2a, 0xba, 0x8e, 0x24, 0x84, 0xf2, 0x0f, 0x41, 0x48, 0xe1, 0x03, 0xeb, 0xc3, 0xbe, 0x31, - 0x7e, 0xc6, 0xf3, 0xd7, 0x9e, 0x71, 0xf4, 0x3b, 0x08, 0xc3, 0x8a, 0x44, 0x82, 0xbd, 0xe6, 0x98, - 0x60, 0xfb, 0xb8, 0x89, 0xbf, 0x1b, 0xc1, 0xfa, 0x87, 0x22, 0x77, 0xcd, 0xa1, 0x08, 0x82, 0x4b, - 0xec, 0x3e, 0x0a, 0xee, 0x03, 0x07, 0xab, 0x35, 0xaa, 0xdf, 0xd2, 0x34, 0xcf, 0xf7, 0x88, 0x4c, - 0x3d, 0xbe, 0x0d, 0xc8, 0x77, 0x28, 0xb6, 0x86, 0xaf, 0x9d, 0x67, 0x45, 0x0a, 0x73, 0x26, 0x44, - 0xc8, 0x4d, 0x2c, 0x42, 0xfe, 0x3a, 0x11, 0x24, 0xf8, 0x63, 0x64, 0x94, 0x91, 0x0e, 0x9f, 0x38, - 0x26, 0x93, 0x82, 0x4d, 0xd2, 0x65, 0x32, 0xdd, 0xb1, 0x88, 0xf9, 0x83, 0x8a, 0xb1, 0x09, 0x28, - 0x3d, 0xd4, 0x48, 0x91, 0xcf, 0x1c, 0x6b, 0x7a, 0x47, 0x78, 0xe0, 0x62, 0x4d, 0x49, 0x88, 0x6d, - 0x28, 0xd8, 0xaa, 0xa5, 0x63, 0x3b, 0x90, 0x22, 0xb6, 0x5b, 0xdf, 0x8e, 0x94, 0x00, 0xf0, 0x4a, - 0xf2, 0x70, 0x4d, 0x88, 0x95, 0xe4, 0x81, 0x5a, 0x10, 0x47, 0x27, 0x91, 0xe4, 0x37, 0xd6, 0xdb, - 0x06, 0x63, 0x0d, 0x95, 0xa8, 0xbc, 0x2a, 0x40, 0xae, 0x46, 0x75, 0xfe, 0x04, 0x96, 0x12, 0x4f, - 0x80, 0xad, 0xf2, 0x88, 0x87, 0x46, 0x79, 0xa8, 0x4b, 0x0a, 0xe5, 0xf1, 0xb8, 0xa8, 0x9b, 0xd6, - 0x61, 0x61, 0xa0, 0x05, 0x6e, 0xa6, 0x8d, 0x8f, 0x53, 0xc2, 0xce, 0x38, 0x54, 0xb4, 0xc6, 0x33, - 0x28, 0x26, 0x7b, 0xc0, 0x5f, 0x5f, 0xdf, 0x66, 0x04, 0x0a, 0xf2, 0x98, 0x60, 0x7c, 0xb1, 0x64, - 0xfd, 0x4c, 0x5d, 0x2c, 0x01, 0xa6, 0x2f, 0x96, 0x52, 0xd3, 0x78, 0x1b, 0xf8, 0x11, 0xf5, 0xec, - 0x9f, 0xb4, 0x69, 0x86, 0x59, 0xa1, 0x32, 0x3e, 0x1b, 0xad, 0x7a, 0xc6, 0xc1, 0x5a, 0x5a, 0xf9, - 0x48, 0x0d, 0x21, 0x65, 0x80, 0x70, 0x63, 0xc2, 0x01, 0xd1, 0x2e, 0x4e, 0x60, 0x29, 0x71, 0x63, - 0x53, 0xcf, 0xe8, 0x20, 0x97, 0x7e, 0x46, 0x47, 0xdf, 0x8a, 0xea, 0xbd, 0xb7, 0x3d, 0x91, 0xbb, - 0xec, 0x89, 0xdc, 0xfb, 0x9e, 0xc8, 0x9d, 0x5f, 0x89, 0x99, 0xcb, 0x2b, 0x31, 0xf3, 0xee, 0x4a, - 0xcc, 0x3c, 0xa9, 0xe8, 0x86, 0x7d, 0xd2, 0xa9, 0x97, 0x1b, 0xc4, 0x94, 0xfd, 0x39, 0xff, 0x6d, - 0xaa, 0x75, 0x1a, 0x7c, 0xcb, 0xdd, 0x8a, 0xfc, 0x22, 0xf6, 0xdc, 0xb6, 0x4f, 0xdb, 0x98, 0xd6, - 0x0b, 0xec, 0xa5, 0xfd, 0xdf, 0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0x70, 0x2c, 0x71, 0x68, 0xda, - 0x0b, 0x00, 0x00, + // 797 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0xc7, 0xe3, 0x24, 0x0d, 0xed, 0xf4, 0x23, 0xd4, 0xa5, 0x34, 0x35, 0x60, 0xa3, 0x6d, 0x55, + 0x28, 0x2a, 0xb1, 0x1a, 0x90, 0x40, 0xbd, 0x11, 0x5a, 0x50, 0x25, 0x02, 0xc8, 0x85, 0x0b, 0x97, + 0xca, 0x89, 0x17, 0xd7, 0x22, 0x8e, 0x23, 0xaf, 0x13, 0xe8, 0xb9, 0x17, 0x8e, 0x95, 0x78, 0x81, + 0x3e, 0x08, 0x57, 0x24, 0x8e, 0x3d, 0x72, 0xb2, 0x50, 0xca, 0x01, 0x38, 0xfa, 0x09, 0x90, 0xd7, + 0x1f, 0x71, 0x9c, 0xb8, 0x4d, 0x50, 0x0e, 0x88, 0x9b, 0x3d, 0xf3, 0xdb, 0x8f, 0xf9, 0xcf, 0xee, + 0xcc, 0x02, 0xaf, 0x60, 0xa2, 0x1b, 0x44, 0x24, 0xad, 0x2a, 0x69, 0xca, 0x35, 0x4c, 0xc4, 0xf6, + 0xa6, 0xa8, 0x13, 0x95, 0x14, 0x9b, 0xa6, 0x61, 0x19, 0xec, 0x82, 0xe7, 0x2f, 0x86, 0xfe, 0x62, + 0x7b, 0x93, 0xbb, 0xa2, 0x1a, 0xaa, 0x41, 0xfd, 0xa2, 0xfb, 0xe5, 0xa1, 0x1c, 0x1a, 0x34, 0x55, + 0xf0, 0xe3, 0x31, 0xe8, 0x28, 0x0d, 0xf3, 0x15, 0xa2, 0x3e, 0x36, 0xb1, 0x6c, 0xe1, 0x3d, 0xdf, + 0xc7, 0xae, 0x40, 0xb6, 0x21, 0xeb, 0xb8, 0xc0, 0xdc, 0x64, 0x6e, 0x4f, 0x95, 0xf3, 0x8e, 0x2d, + 0x4c, 0x1f, 0xca, 0x7a, 0x7d, 0x0b, 0xb9, 0x56, 0x24, 0x51, 0x27, 0xfb, 0x10, 0xa6, 0x15, 0x4c, + 0x6a, 0xa6, 0xd6, 0xb4, 0x34, 0xa3, 0x51, 0x48, 0x53, 0xf6, 0xaa, 0x63, 0x0b, 0xac, 0xc7, 0x46, + 0x9c, 0x48, 0x8a, 0xa2, 0xac, 0x08, 0x93, 0x96, 0x89, 0x65, 0xd2, 0x32, 0x0f, 0x0b, 0x19, 0x3a, + 0x6c, 0xc1, 0xb1, 0x85, 0xbc, 0x37, 0x2c, 0xf0, 0x20, 0x29, 0x84, 0xd8, 0x35, 0x98, 0x30, 0xde, + 0x37, 0xb0, 0x59, 0xc8, 0x52, 0xfa, 0xb2, 0x63, 0x0b, 0x33, 0x1e, 0x4d, 0xcd, 0x48, 0xf2, 0xdc, + 0xec, 0x06, 0x5c, 0xaa, 0xb9, 0x91, 0x18, 0x66, 0x61, 0x82, 0x92, 0xac, 0x63, 0x0b, 0x73, 0x1e, + 0xe9, 0x3b, 0x90, 0x14, 0x20, 0x5b, 0x93, 0x1f, 0x4f, 0x84, 0xd4, 0xcf, 0x13, 0x21, 0x85, 0xaa, + 0xb0, 0xdc, 0x27, 0x82, 0x84, 0x49, 0xd3, 0x68, 0x10, 0xcc, 0xee, 0xc0, 0x74, 0x20, 0xda, 0xbe, + 0xa6, 0x50, 0x4d, 0xb2, 0xe5, 0xd5, 0x8e, 0x2d, 0x40, 0x80, 0xee, 0x6e, 0x77, 0xa3, 0x8e, 0xa0, + 0x48, 0x82, 0xe0, 0x6f, 0x57, 0x41, 0x5f, 0xd2, 0x90, 0xaf, 0x10, 0x75, 0x47, 0xd1, 0xac, 0x50, + 0xe7, 0xf1, 0x4c, 0x1d, 0xa6, 0x2b, 0x3d, 0x42, 0xba, 0x32, 0x7f, 0x97, 0xae, 0xec, 0x48, 0xe9, + 0x9a, 0x38, 0x3f, 0x5d, 0xeb, 0x90, 0x23, 0x9a, 0xea, 0x82, 0x39, 0x0a, 0xce, 0x3b, 0xb6, 0x30, + 0xeb, 0xc7, 0x4a, 0xed, 0x48, 0xf2, 0x81, 0x48, 0xae, 0x96, 0x61, 0x29, 0x26, 0x63, 0x90, 0x29, + 0x74, 0x9c, 0x06, 0x36, 0xcc, 0xe3, 0x6b, 0x82, 0xcd, 0xa7, 0xa6, 0xd1, 0x6a, 0x8e, 0x4b, 0xe5, + 0xfb, 0x00, 0xaa, 0x3b, 0xdf, 0x7e, 0x44, 0xeb, 0x45, 0xc7, 0x16, 0xe6, 0xbd, 0x71, 0x5d, 0x1f, + 0x92, 0xa6, 0xe8, 0xcf, 0x73, 0x57, 0xf6, 0x17, 0xb0, 0xa0, 0xe0, 0xb7, 0x72, 0xab, 0x6e, 0xed, + 0x37, 0xb1, 0xa9, 0x6b, 0x84, 0x68, 0x46, 0x83, 0x50, 0xf9, 0x67, 0xcb, 0xbc, 0x63, 0x0b, 0x5c, + 0x20, 0x7f, 0x1f, 0x84, 0x24, 0xd6, 0xb7, 0xbe, 0xec, 0x1a, 0xa3, 0x67, 0x3c, 0x7b, 0xe1, 0x19, + 0x47, 0xd7, 0x81, 0xeb, 0x57, 0x24, 0x14, 0xec, 0x33, 0x43, 0x05, 0xdb, 0xc6, 0x75, 0xfc, 0xcf, + 0x08, 0xd6, 0x3d, 0x14, 0x99, 0x0b, 0x0e, 0x85, 0x1f, 0x5c, 0x6c, 0xf7, 0x61, 0x70, 0x3f, 0x18, + 0x58, 0xac, 0x10, 0xf5, 0x91, 0xa2, 0xb8, 0xbe, 0x57, 0xc6, 0xd8, 0xe3, 0x5b, 0x81, 0x6c, 0x8b, + 0x60, 0xb3, 0xff, 0xda, 0xb9, 0x56, 0x24, 0x51, 0x67, 0x4c, 0x84, 0xcc, 0xc8, 0x22, 0x64, 0x2f, + 0x12, 0x41, 0x80, 0x1b, 0x03, 0xa3, 0x0c, 0x75, 0xf8, 0xc5, 0x50, 0x99, 0x24, 0xac, 0x1b, 0x6d, + 0x2a, 0xd3, 0x13, 0xd3, 0xd0, 0xff, 0x53, 0x31, 0x56, 0x01, 0x25, 0x87, 0x1a, 0x2a, 0xf2, 0x9b, + 0xa1, 0x4d, 0x6f, 0x0f, 0xf7, 0x5c, 0xac, 0x31, 0x09, 0xb1, 0x0e, 0x39, 0x4b, 0x36, 0x55, 0x6c, + 0xf9, 0x52, 0x44, 0x76, 0xeb, 0xd9, 0x91, 0xe4, 0x03, 0x6e, 0x49, 0xee, 0xaf, 0x09, 0x91, 0x92, + 0xdc, 0x53, 0x0b, 0xa2, 0xe8, 0x28, 0x92, 0x5c, 0xa3, 0xbd, 0xad, 0x37, 0xd6, 0x40, 0x89, 0xd2, + 0xa7, 0x1c, 0x64, 0x2a, 0x44, 0x65, 0x0f, 0x60, 0x2e, 0xf6, 0x04, 0x58, 0x2b, 0x0e, 0x78, 0x68, + 0x14, 0xfb, 0xba, 0x24, 0x57, 0x1c, 0x8e, 0x0b, 0xbb, 0x69, 0x15, 0x66, 0x7a, 0x5a, 0xe0, 0x6a, + 0xd2, 0xf8, 0x28, 0xc5, 0x6d, 0x0c, 0x43, 0x85, 0x6b, 0xbc, 0x83, 0x7c, 0xbc, 0x07, 0xdc, 0x3a, + 0x7f, 0x9b, 0x21, 0xc8, 0x89, 0x43, 0x82, 0xd1, 0xc5, 0xe2, 0xf5, 0x33, 0x71, 0xb1, 0x18, 0x98, + 0xbc, 0x58, 0x42, 0x4d, 0x63, 0x2d, 0x60, 0x07, 0xd4, 0xb3, 0x3b, 0x49, 0xd3, 0xf4, 0xb3, 0x5c, + 0x69, 0x78, 0x36, 0x5c, 0xf5, 0x88, 0x81, 0xa5, 0xa4, 0xf2, 0x91, 0x18, 0x42, 0xc2, 0x00, 0xee, + 0xc1, 0x88, 0x03, 0xc2, 0x5d, 0x1c, 0xc0, 0x5c, 0xec, 0xc6, 0x26, 0x9e, 0xd1, 0x5e, 0x2e, 0xf9, + 0x8c, 0x0e, 0xbe, 0x15, 0xe5, 0x67, 0x5f, 0x3b, 0x3c, 0x73, 0xda, 0xe1, 0x99, 0xef, 0x1d, 0x9e, + 0x39, 0x3e, 0xe3, 0x53, 0xa7, 0x67, 0x7c, 0xea, 0xdb, 0x19, 0x9f, 0x7a, 0x53, 0x52, 0x35, 0xeb, + 0xa0, 0x55, 0x2d, 0xd6, 0x0c, 0x5d, 0xf4, 0xe6, 0xbc, 0x5b, 0x97, 0xab, 0xc4, 0xff, 0x16, 0xdb, + 0x25, 0xf1, 0x43, 0xe4, 0xb9, 0x6d, 0x1d, 0x36, 0x31, 0xa9, 0xe6, 0xe8, 0x4b, 0xfb, 0xde, 0x9f, + 0x00, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x41, 0x4a, 0xae, 0xda, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1136,18 +1135,18 @@ func (m *MsgCreateSubspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x2a } - if len(m.Treasury) > 0 { - i -= len(m.Treasury) - copy(dAtA[i:], m.Treasury) - i = encodeVarintMsgs(dAtA, i, uint64(len(m.Treasury))) - i-- - dAtA[i] = 0x22 - } if len(m.Owner) > 0 { i -= len(m.Owner) copy(dAtA[i:], m.Owner) i = encodeVarintMsgs(dAtA, i, uint64(len(m.Owner))) i-- + dAtA[i] = 0x22 + } + if len(m.Treasury) > 0 { + i -= len(m.Treasury) + copy(dAtA[i:], m.Treasury) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Treasury))) + i-- dAtA[i] = 0x1a } if len(m.Description) > 0 { @@ -1222,18 +1221,18 @@ func (m *MsgEditSubspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x32 } - if len(m.Treasury) > 0 { - i -= len(m.Treasury) - copy(dAtA[i:], m.Treasury) - i = encodeVarintMsgs(dAtA, i, uint64(len(m.Treasury))) - i-- - dAtA[i] = 0x2a - } if len(m.Owner) > 0 { i -= len(m.Owner) copy(dAtA[i:], m.Owner) i = encodeVarintMsgs(dAtA, i, uint64(len(m.Owner))) i-- + dAtA[i] = 0x2a + } + if len(m.Treasury) > 0 { + i -= len(m.Treasury) + copy(dAtA[i:], m.Treasury) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Treasury))) + i-- dAtA[i] = 0x22 } if len(m.Description) > 0 { @@ -1655,11 +1654,11 @@ func (m *MsgCreateSubspace) Size() (n int) { if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } - l = len(m.Owner) + l = len(m.Treasury) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } - l = len(m.Treasury) + l = len(m.Owner) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } @@ -1699,11 +1698,11 @@ func (m *MsgEditSubspace) Size() (n int) { if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } - l = len(m.Owner) + l = len(m.Treasury) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } - l = len(m.Treasury) + l = len(m.Owner) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } @@ -1983,7 +1982,7 @@ func (m *MsgCreateSubspace) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2011,11 +2010,11 @@ func (m *MsgCreateSubspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Owner = string(dAtA[iNdEx:postIndex]) + m.Treasury = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2043,7 +2042,7 @@ func (m *MsgCreateSubspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Treasury = string(dAtA[iNdEx:postIndex]) + m.Owner = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { @@ -2281,7 +2280,7 @@ func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2309,11 +2308,11 @@ func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Owner = string(dAtA[iNdEx:postIndex]) + m.Treasury = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2341,7 +2340,7 @@ func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Treasury = string(dAtA[iNdEx:postIndex]) + m.Owner = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 6: if wireType != 2 { diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go index 5311d67f13..4ff7595d21 100644 --- a/x/subspaces/types/permissions.go +++ b/x/subspaces/types/permissions.go @@ -17,11 +17,11 @@ const ( // PermissionModerateContent allows users to moderate contents of other users (e.g. deleting it) PermissionModerateContent = Permission(0b000010) - // PermissionAddLink allows to add a link for this subspace - PermissionAddLink = Permission(0b000100) - // PermissionChangeInfo allows to change the information of the subspace - PermissionChangeInfo = Permission(0b001000) + PermissionChangeInfo = Permission(0b000100) + + // PermissionManageGroups allows users to manage user groups and members + PermissionManageGroups = Permission(0b001000) // PermissionSetPermissions allows to set other users' permissions (except PermissionSetPermissions). // This includes managing user groups and the associated permissions diff --git a/x/subspaces/types/permissions_test.go b/x/subspaces/types/permissions_test.go index abbb9505d9..86d7d6b354 100644 --- a/x/subspaces/types/permissions_test.go +++ b/x/subspaces/types/permissions_test.go @@ -21,7 +21,7 @@ func TestMarshalPermission(t *testing.T) { }, { name: "non-zero permission", - permission: types.PermissionAddLink, + permission: types.PermissionManageGroups, expected: []byte{0, 0, 0, 4}, }, { @@ -98,13 +98,13 @@ func TestCheckPermission(t *testing.T) { }, { name: "combined permission returns true when contains", - permissions: types.PermissionWrite | types.PermissionModerateContent | types.PermissionAddLink, + permissions: types.PermissionWrite | types.PermissionModerateContent | types.PermissionManageGroups, permission: types.PermissionModerateContent, expResult: true, }, { name: "combined permission returns false when does not contain", - permissions: types.PermissionWrite | types.PermissionModerateContent | types.PermissionAddLink, + permissions: types.PermissionWrite | types.PermissionModerateContent | types.PermissionManageGroups, permission: types.PermissionSetPermissions, expResult: false, }, @@ -142,8 +142,8 @@ func TestCombinePermissions(t *testing.T) { }, { name: "combining different permissions returns the correct result", - permissions: []types.Permission{types.PermissionWrite, types.PermissionAddLink, types.PermissionSetPermissions}, - expResult: types.PermissionWrite | types.PermissionAddLink | types.PermissionSetPermissions, + permissions: []types.Permission{types.PermissionWrite, types.PermissionManageGroups, types.PermissionSetPermissions}, + expResult: types.PermissionWrite | types.PermissionManageGroups | types.PermissionSetPermissions, }, } diff --git a/x/subspaces/types/query.go b/x/subspaces/types/query.go index cef6250862..7a93397d8e 100644 --- a/x/subspaces/types/query.go +++ b/x/subspaces/types/query.go @@ -15,3 +15,30 @@ func NewQuerySubspacesRequest(pagination *query.PageRequest) *QuerySubspacesRequ Pagination: pagination, } } + +// NewQueryUserGroupsRequest returns a new QueryUserGroupsRequest instance +func NewQueryUserGroupsRequest(subspaceID uint64, pagination *query.PageRequest) *QueryUserGroupsRequest { + return &QueryUserGroupsRequest{ + SubspaceId: subspaceID, + Pagination: pagination, + } +} + +// NewQueryUserGroupMembersRequest returns a new QueryUserGroupMembersRequest instance +func NewQueryUserGroupMembersRequest( + subspaceID uint64, groupName string, pagination *query.PageRequest, +) *QueryUserGroupMembersRequest { + return &QueryUserGroupMembersRequest{ + SubspaceId: subspaceID, + GroupName: groupName, + Pagination: pagination, + } +} + +// NewQueryPermissionsRequest returns a new QueryPermissionsRequest instance +func NewQueryPermissionsRequest(subspaceID uint64, target string) *QueryPermissionsRequest { + return &QueryPermissionsRequest{ + SubspaceId: subspaceID, + Target: target, + } +} diff --git a/x/subspaces/types/subspace.go b/x/subspaces/types/subspace.go index ed99dbd358..7b73500e12 100644 --- a/x/subspaces/types/subspace.go +++ b/x/subspaces/types/subspace.go @@ -9,14 +9,14 @@ import ( ) // NewSubspace is a constructor for the Subspace type -func NewSubspace(subspaceID uint64, name, description, owner, creator, treasury string, creationTime time.Time) Subspace { +func NewSubspace(subspaceID uint64, name, description, treasury, owner, creator string, creationTime time.Time) Subspace { return Subspace{ ID: subspaceID, Name: name, Description: description, + Treasury: treasury, Owner: owner, Creator: creator, - Treasury: treasury, CreationTime: creationTime, } } @@ -62,17 +62,17 @@ func (sub Subspace) Validate() error { type SubspaceUpdate struct { Name string Description string - Owner string Treasury string + Owner string } // NewSubspaceUpdate builds a new SubspaceUpdate instance containing the given data -func NewSubspaceUpdate(name, description, owner, treasury string) *SubspaceUpdate { +func NewSubspaceUpdate(name, description, treasury, owner string) *SubspaceUpdate { return &SubspaceUpdate{ Name: name, Description: description, - Owner: owner, Treasury: treasury, + Owner: owner, } } @@ -88,21 +88,21 @@ func (sub Subspace) Update(update *SubspaceUpdate) Subspace { update.Description = sub.Description } - if update.Owner == DoNotModify { - update.Owner = sub.Owner - } - if update.Treasury == DoNotModify { update.Treasury = sub.Treasury } + if update.Owner == DoNotModify { + update.Owner = sub.Owner + } + return NewSubspace( sub.ID, update.Name, update.Description, + update.Treasury, update.Owner, sub.Creator, - update.Treasury, sub.CreationTime, ) } diff --git a/x/subspaces/types/subspace.pb.go b/x/subspaces/types/subspace.pb.go index 5290e4edff..ddb8b23622 100644 --- a/x/subspaces/types/subspace.pb.go +++ b/x/subspaces/types/subspace.pb.go @@ -35,13 +35,13 @@ type Subspace struct { Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // Optional description of this subspace Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` - // Address of the user that owns the subspace - Owner string `protobuf:"bytes,4,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` - // Address of the subspace creator - Creator string `protobuf:"bytes,5,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` // Represents the account that is associated with the subspace and // should be used to connect external applications to verify this subspace - Treasury string `protobuf:"bytes,6,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + Treasury string `protobuf:"bytes,4,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + // Address of the user that owns the subspace + Owner string `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` + // Address of the subspace creator + Creator string `protobuf:"bytes,6,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` // the creation time of the subspace CreationTime time.Time `protobuf:"bytes,7,opt,name=creation_time,json=creationTime,proto3,stdtime" json:"creation_time" yaml:"creation_time"` } @@ -100,23 +100,23 @@ func (m *Subspace) GetDescription() string { return "" } -func (m *Subspace) GetOwner() string { +func (m *Subspace) GetTreasury() string { if m != nil { - return m.Owner + return m.Treasury } return "" } -func (m *Subspace) GetCreator() string { +func (m *Subspace) GetOwner() string { if m != nil { - return m.Creator + return m.Owner } return "" } -func (m *Subspace) GetTreasury() string { +func (m *Subspace) GetCreator() string { if m != nil { - return m.Treasury + return m.Creator } return "" } @@ -143,27 +143,27 @@ var fileDescriptor_64b466175177a54c = []byte{ 0x09, 0x75, 0x80, 0x58, 0x57, 0x16, 0x74, 0x63, 0xc5, 0x82, 0xc4, 0x14, 0x98, 0x58, 0x90, 0x93, 0x98, 0x60, 0xa9, 0x89, 0xa3, 0xd8, 0x29, 0x74, 0xe5, 0x13, 0xdc, 0xc8, 0x78, 0x1f, 0xe7, 0xc6, 0x8e, 0x4c, 0x06, 0xa5, 0x0b, 0x73, 0x3e, 0xc1, 0x29, 0x76, 0x53, 0x65, 0xfb, 0xff, 0xdf, 0xfb, - 0xbd, 0xe8, 0xaf, 0x17, 0x43, 0x92, 0x70, 0x95, 0x49, 0x45, 0x55, 0x15, 0xa9, 0x82, 0xc5, 0x5c, + 0xbd, 0xbf, 0xa2, 0x17, 0x43, 0x92, 0x70, 0x95, 0x49, 0x45, 0x55, 0x15, 0xa9, 0x82, 0xc5, 0x5c, 0xd1, 0xcd, 0xed, 0x71, 0x09, 0x8a, 0x52, 0x6a, 0x89, 0xa6, 0x8e, 0x09, 0x8e, 0x4c, 0xb0, 0xb9, 0x9d, 0x5d, 0xa7, 0x32, 0x95, 0xd6, 0xa7, 0xed, 0xe4, 0xd0, 0x19, 0x4e, 0xa5, 0x4c, 0xd7, 0x9c, 0xda, 0x2d, 0xaa, 0xbe, 0x51, 0x2d, 0x32, 0xae, 0x34, 0xcb, 0x0a, 0x07, 0x90, 0x5f, 0x27, 0x70, - 0xfc, 0xe9, 0xf0, 0x1d, 0x74, 0x03, 0x87, 0x22, 0xf1, 0xc0, 0x1c, 0x2c, 0x46, 0xab, 0x69, 0x6d, - 0xf0, 0xf0, 0xc3, 0xfb, 0xc6, 0xe0, 0x8b, 0x2d, 0xcb, 0xd6, 0x77, 0x44, 0x24, 0x24, 0x1c, 0x8a, - 0x04, 0xdd, 0xc0, 0x51, 0xce, 0x32, 0xee, 0x0d, 0xe7, 0x60, 0x71, 0xb1, 0xba, 0x6a, 0x0c, 0x9e, - 0x38, 0xa0, 0x55, 0x49, 0x68, 0x4d, 0xf4, 0x0e, 0x4e, 0x12, 0xae, 0xe2, 0x52, 0x14, 0x5a, 0xc8, - 0xdc, 0x3b, 0xb1, 0xec, 0xcb, 0xc6, 0x60, 0xe4, 0xd8, 0x9e, 0x49, 0xc2, 0x3e, 0x8a, 0x5e, 0xc1, - 0x53, 0xf9, 0x23, 0xe7, 0xa5, 0x37, 0xb2, 0x99, 0x17, 0x8d, 0xc1, 0x97, 0x2e, 0x63, 0x65, 0x12, - 0x3a, 0x1b, 0xbd, 0x86, 0xe7, 0x71, 0xc9, 0x99, 0x96, 0xa5, 0x77, 0x6a, 0x49, 0xd4, 0x18, 0xfc, - 0xdc, 0x91, 0x07, 0x83, 0x84, 0x1d, 0x82, 0x28, 0x1c, 0xeb, 0x92, 0x33, 0x55, 0x95, 0x5b, 0xef, - 0xcc, 0xe2, 0xd3, 0xc6, 0xe0, 0x2b, 0x87, 0x77, 0x0e, 0x09, 0x8f, 0x10, 0x62, 0xf0, 0x99, 0xcd, - 0x0a, 0x99, 0x7f, 0x6d, 0x3b, 0xf3, 0xce, 0xe7, 0x60, 0x31, 0x59, 0xce, 0x02, 0x57, 0x68, 0xd0, - 0x15, 0x1a, 0x7c, 0xee, 0x0a, 0x5d, 0xcd, 0x1f, 0x0d, 0x1e, 0x34, 0x06, 0x5f, 0xf7, 0x8e, 0xe8, - 0xe2, 0xe4, 0xfe, 0x2f, 0x06, 0xe1, 0x65, 0xa7, 0xb5, 0xa1, 0xbb, 0xf1, 0xef, 0x07, 0x0c, 0xfe, - 0x3f, 0x60, 0xb0, 0xfa, 0xf8, 0x58, 0xfb, 0x60, 0x57, 0xfb, 0xe0, 0x5f, 0xed, 0x83, 0xfb, 0xbd, - 0x3f, 0xd8, 0xed, 0xfd, 0xc1, 0x9f, 0xbd, 0x3f, 0xf8, 0xb2, 0x4c, 0x85, 0xfe, 0x5e, 0x45, 0x41, - 0x2c, 0x33, 0xea, 0xfe, 0xfa, 0x9b, 0x35, 0x8b, 0xd4, 0x61, 0xa6, 0x9b, 0x25, 0xfd, 0xd9, 0x7b, - 0x2a, 0x7a, 0x5b, 0x70, 0x15, 0x9d, 0xd9, 0xdb, 0xde, 0x3e, 0x05, 0x00, 0x00, 0xff, 0xff, 0x57, - 0xc9, 0xd6, 0x66, 0x4b, 0x02, 0x00, 0x00, + 0xfc, 0xe9, 0x70, 0x07, 0xdd, 0xc0, 0xa1, 0x48, 0x3c, 0x30, 0x07, 0x8b, 0xd1, 0x6a, 0x5a, 0x1b, + 0x3c, 0xfc, 0xf0, 0xbe, 0x31, 0xf8, 0x62, 0xcb, 0xb2, 0xf5, 0x1d, 0x11, 0x09, 0x09, 0x87, 0x22, + 0x41, 0x37, 0x70, 0x94, 0xb3, 0x8c, 0x7b, 0xc3, 0x39, 0x58, 0x5c, 0xac, 0xae, 0x1a, 0x83, 0x27, + 0x0e, 0x68, 0x55, 0x12, 0x5a, 0x13, 0xbd, 0x83, 0x93, 0x84, 0xab, 0xb8, 0x14, 0x85, 0x16, 0x32, + 0xf7, 0x4e, 0x2c, 0xfb, 0xb2, 0x31, 0x18, 0x39, 0xb6, 0x67, 0x92, 0xb0, 0x8f, 0x22, 0x0a, 0xc7, + 0xba, 0xe4, 0x4c, 0x55, 0xe5, 0xd6, 0x1b, 0xd9, 0xd8, 0xb4, 0x31, 0xf8, 0xca, 0xc5, 0x3a, 0x87, + 0x84, 0x47, 0x08, 0xbd, 0x82, 0xa7, 0xf2, 0x47, 0xce, 0x4b, 0xef, 0xd4, 0xd2, 0x2f, 0x1a, 0x83, + 0x2f, 0x1d, 0x6d, 0x65, 0x12, 0x3a, 0x1b, 0xbd, 0x86, 0xe7, 0x71, 0xc9, 0x99, 0x96, 0xa5, 0x77, + 0x66, 0x49, 0xd4, 0x18, 0xfc, 0xdc, 0x91, 0x07, 0x83, 0x84, 0x1d, 0x82, 0x18, 0x7c, 0x66, 0x47, + 0x21, 0xf3, 0xaf, 0x6d, 0x67, 0xde, 0xf9, 0x1c, 0x2c, 0x26, 0xcb, 0x59, 0xe0, 0x0a, 0x0d, 0xba, + 0x42, 0x83, 0xcf, 0x5d, 0xa1, 0xab, 0xf9, 0xa3, 0xc1, 0x83, 0xc6, 0xe0, 0xeb, 0xde, 0xcd, 0x2e, + 0x4e, 0xee, 0xff, 0x62, 0x10, 0x5e, 0x76, 0x5a, 0x1b, 0xba, 0x1b, 0xff, 0x7e, 0xc0, 0xe0, 0xff, + 0x03, 0x06, 0xab, 0x8f, 0x8f, 0xb5, 0x0f, 0x76, 0xb5, 0x0f, 0xfe, 0xd5, 0x3e, 0xb8, 0xdf, 0xfb, + 0x83, 0xdd, 0xde, 0x1f, 0xfc, 0xd9, 0xfb, 0x83, 0x2f, 0xcb, 0x54, 0xe8, 0xef, 0x55, 0x14, 0xc4, + 0x32, 0xa3, 0xee, 0xaf, 0xbf, 0x59, 0xb3, 0x48, 0x1d, 0x66, 0xba, 0x59, 0xd2, 0x9f, 0xbd, 0xa7, + 0xa2, 0xb7, 0x05, 0x57, 0xd1, 0x99, 0xfd, 0xb6, 0xb7, 0x4f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa1, + 0x97, 0xf2, 0x18, 0x4b, 0x02, 0x00, 0x00, } func (this *Subspace) Equal(that interface{}) bool { @@ -194,13 +194,13 @@ func (this *Subspace) Equal(that interface{}) bool { if this.Description != that1.Description { return false } - if this.Owner != that1.Owner { + if this.Treasury != that1.Treasury { return false } - if this.Creator != that1.Creator { + if this.Owner != that1.Owner { return false } - if this.Treasury != that1.Treasury { + if this.Creator != that1.Creator { return false } if !this.CreationTime.Equal(that1.CreationTime) { @@ -236,25 +236,25 @@ func (m *Subspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintSubspace(dAtA, i, uint64(n1)) i-- dAtA[i] = 0x3a - if len(m.Treasury) > 0 { - i -= len(m.Treasury) - copy(dAtA[i:], m.Treasury) - i = encodeVarintSubspace(dAtA, i, uint64(len(m.Treasury))) - i-- - dAtA[i] = 0x32 - } if len(m.Creator) > 0 { i -= len(m.Creator) copy(dAtA[i:], m.Creator) i = encodeVarintSubspace(dAtA, i, uint64(len(m.Creator))) i-- - dAtA[i] = 0x2a + dAtA[i] = 0x32 } if len(m.Owner) > 0 { i -= len(m.Owner) copy(dAtA[i:], m.Owner) i = encodeVarintSubspace(dAtA, i, uint64(len(m.Owner))) i-- + dAtA[i] = 0x2a + } + if len(m.Treasury) > 0 { + i -= len(m.Treasury) + copy(dAtA[i:], m.Treasury) + i = encodeVarintSubspace(dAtA, i, uint64(len(m.Treasury))) + i-- dAtA[i] = 0x22 } if len(m.Description) > 0 { @@ -307,15 +307,15 @@ func (m *Subspace) Size() (n int) { if l > 0 { n += 1 + l + sovSubspace(uint64(l)) } - l = len(m.Owner) + l = len(m.Treasury) if l > 0 { n += 1 + l + sovSubspace(uint64(l)) } - l = len(m.Creator) + l = len(m.Owner) if l > 0 { n += 1 + l + sovSubspace(uint64(l)) } - l = len(m.Treasury) + l = len(m.Creator) if l > 0 { n += 1 + l + sovSubspace(uint64(l)) } @@ -444,7 +444,7 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -472,11 +472,11 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Owner = string(dAtA[iNdEx:postIndex]) + m.Treasury = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -504,11 +504,11 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Creator = string(dAtA[iNdEx:postIndex]) + m.Owner = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 6: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -536,7 +536,7 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Treasury = string(dAtA[iNdEx:postIndex]) + m.Creator = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 7: if wireType != 2 { From 3fe18f4df3701200643c5ab3ca1afd05ad76fce7 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Fri, 21 Jan 2022 11:23:59 +0100 Subject: [PATCH 08/47] completed tests for the types package Signed-off-by: Riccardo Montagnin --- proto/desmos/subspaces/v1/genesis.proto | 2 +- x/subspaces/keeper/genesis.go | 2 +- x/subspaces/module.go | 20 +- x/subspaces/types/genesis.go | 93 +- x/subspaces/types/genesis.pb.go | 74 +- x/subspaces/types/genesis_test.go | 454 ++++---- x/subspaces/types/msgs.go | 97 +- x/subspaces/types/msgs_test.go | 1415 ++++++++++------------- x/subspaces/types/permissions.go | 6 +- x/subspaces/types/subspace.go | 14 +- x/subspaces/types/subspace_test.go | 427 +++---- 11 files changed, 1266 insertions(+), 1338 deletions(-) diff --git a/proto/desmos/subspaces/v1/genesis.proto b/proto/desmos/subspaces/v1/genesis.proto index 0c78bc1ca9..3a84b86e0e 100644 --- a/proto/desmos/subspaces/v1/genesis.proto +++ b/proto/desmos/subspaces/v1/genesis.proto @@ -26,7 +26,7 @@ message ACLEntry { option (gogoproto.goproto_stringer) = true; // Either group name or user address - uint64 subspace_id = 1; + uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID" ]; string target = 2; uint32 permissions = 3; } diff --git a/x/subspaces/keeper/genesis.go b/x/subspaces/keeper/genesis.go index 6200f60ce9..9d9adc059f 100644 --- a/x/subspaces/keeper/genesis.go +++ b/x/subspaces/keeper/genesis.go @@ -80,6 +80,6 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { // Initialize the permissions for _, entry := range data.ACL { - k.SetPermissions(ctx, entry.SubspaceId, entry.Target, entry.Permissions) + k.SetPermissions(ctx, entry.SubspaceID, entry.Target, entry.Permissions) } } diff --git a/x/subspaces/module.go b/x/subspaces/module.go index 471c3a3118..5ad862f845 100644 --- a/x/subspaces/module.go +++ b/x/subspaces/module.go @@ -6,9 +6,7 @@ import ( "fmt" "math/rand" - "github.com/desmos-labs/desmos/v2/x/subspaces/client/cli" "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" - "github.com/desmos-labs/desmos/v2/x/subspaces/simulation" "github.com/desmos-labs/desmos/v2/x/subspaces/types" "github.com/cosmos/cosmos-sdk/client" @@ -71,12 +69,16 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // GetTxCmd returns the root tx command for the subspaces module. func (AppModuleBasic) GetTxCmd() *cobra.Command { - return cli.NewTxCmd() + // TODO + //return cli.NewTxCmd() + return nil } // GetQueryCmd returns the root query command for the subspaces module. func (AppModuleBasic) GetQueryCmd() *cobra.Command { - return cli.GetQueryCmd() + // TODO + //return cli.GetQueryCmd() + return nil } // RegisterInterfaces registers interfaces and implementations of the subspaces module. @@ -180,7 +182,8 @@ type AppModuleSimulation struct{} // GenerateGenesisState creates a randomized GenState of the bank module. func (AppModule) GenerateGenesisState(simState *module.SimulationState) { - simulation.RandomizeGenState(simState) + // TODO + //simulation.RandomizeGenState(simState) } // ProposalContents doesn't return any content functions for governance proposals. @@ -195,10 +198,13 @@ func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { // RegisterStoreDecoder performs a no-op. func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - sdr[types.ModuleName] = simulation.NewDecodeStore(am.cdc) + // TODO + //sdr[types.ModuleName] = simulation.NewDecodeStore(am.cdc) } // WeightedOperations returns the all the subspaces module operations with their respective weights. func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { - return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keeper, am.ak, am.bk) + // TODO + //return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keeper, am.ak, am.bk) + return nil } diff --git a/x/subspaces/types/genesis.go b/x/subspaces/types/genesis.go index cfca3586ed..74fe707071 100644 --- a/x/subspaces/types/genesis.go +++ b/x/subspaces/types/genesis.go @@ -1,16 +1,29 @@ package types -import "fmt" +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) // NewACLEntry returns a new ACLEntry instance func NewACLEntry(subspaceID uint64, target string, permissions Permission) ACLEntry { return ACLEntry{ - SubspaceId: subspaceID, + SubspaceID: subspaceID, Target: target, Permissions: permissions, } } +// Validate returns an error if something is wrong within the entry data +func (entry ACLEntry) Validate() error { + if entry.SubspaceID == 0 { + return fmt.Errorf("invalid subspace id: %d", entry.SubspaceID) + } + + return nil +} + // NewUserGroup returns a new UserGroup instance func NewUserGroup(subspaceID uint64, groupName string, members []string) UserGroup { return UserGroup{ @@ -20,6 +33,26 @@ func NewUserGroup(subspaceID uint64, groupName string, members []string) UserGro } } +// Validate returns an error if something is wrong within the group data +func (group UserGroup) Validate() error { + if group.SubspaceID == 0 { + return fmt.Errorf("invalid subspace id: %d", group.SubspaceID) + } + + if group.Name == "" { + return fmt.Errorf("invalid group name: %s", group.Name) + } + + for _, member := range group.Members { + _, err := sdk.AccAddressFromBech32(member) + if err != nil { + return fmt.Errorf("invalid group member address: %s", member) + } + } + + return nil +} + // ------------------------------------------------------------------------------------------------------------------- // NewGenesisState creates a new genesis state @@ -46,21 +79,71 @@ func ValidateGenesis(data *GenesisState) error { } for _, subspace := range data.Subspaces { + err := subspace.Validate() + if err != nil { + return err + } + if containsDuplicatedSubspace(data.Subspaces, subspace) { return fmt.Errorf("duplicated subspace: %d", subspace.ID) } } - // TODO + for _, entry := range data.ACL { + err := entry.Validate() + if err != nil { + return err + } + + if containsDuplicatedACLEntry(data.ACL, entry) { + return fmt.Errorf("duplicated ACL entry for subspace %d: %s", entry.SubspaceID, entry.Target) + } + } + + for _, group := range data.UserGroups { + err := group.Validate() + if err != nil { + return err + } + + if containsDuplicatedGroups(data.UserGroups, group) { + return fmt.Errorf("duplicated group for subspace %d: %s", group.SubspaceID, group.Name) + } + } return nil } -// containsDuplicatedSubspace tells whether the given subspaces slice contain duplicates of the provided subspace +// containsDuplicatedSubspace tells whether the given subspaces slice contains two or more +// subspaces with the same id of the given subspace func containsDuplicatedSubspace(subspaces []Subspace, subspace Subspace) bool { var count = 0 for _, s := range subspaces { - if s.Equal(subspace) { + if s.ID == subspace.ID { + count++ + } + } + return count > 1 +} + +// containsDuplicatedACLEntry tells whether the given entries slice contains two or more +// entries for the same target and subspace +func containsDuplicatedACLEntry(entries []ACLEntry, entry ACLEntry) bool { + var count = 0 + for _, e := range entries { + if e.SubspaceID == entry.SubspaceID && e.Target == entry.Target { + count++ + } + } + return count > 1 +} + +// containsDuplicatedGroups tells whether the given groups slice contains two or more +// groups for the same subspace having the same name +func containsDuplicatedGroups(groups []UserGroup, group UserGroup) bool { + var count = 0 + for _, g := range groups { + if g.SubspaceID == group.SubspaceID && g.Name == group.Name { count++ } } diff --git a/x/subspaces/types/genesis.pb.go b/x/subspaces/types/genesis.pb.go index 32f50bd6bc..e459f68dd4 100644 --- a/x/subspaces/types/genesis.pb.go +++ b/x/subspaces/types/genesis.pb.go @@ -87,7 +87,7 @@ func (m *GenesisState) GetUserGroups() []UserGroup { // ACL represents a single Access Control List entry type ACLEntry struct { // Either group name or user address - SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` Target string `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty"` Permissions uint32 `protobuf:"varint,3,opt,name=permissions,proto3" json:"permissions,omitempty"` } @@ -125,9 +125,9 @@ func (m *ACLEntry) XXX_DiscardUnknown() { var xxx_messageInfo_ACLEntry proto.InternalMessageInfo -func (m *ACLEntry) GetSubspaceId() uint64 { +func (m *ACLEntry) GetSubspaceID() uint64 { if m != nil { - return m.SubspaceId + return m.SubspaceID } return 0 } @@ -217,32 +217,32 @@ func init() { func init() { proto.RegisterFile("desmos/subspaces/v1/genesis.proto", fileDescriptor_bce8af665337782b) } var fileDescriptor_bce8af665337782b = []byte{ - // 394 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x92, 0xbf, 0x8a, 0xdb, 0x40, - 0x10, 0xc6, 0xb5, 0x27, 0x73, 0x39, 0xad, 0x92, 0x14, 0x9b, 0x10, 0xc4, 0x41, 0x24, 0xc5, 0x95, - 0x9a, 0x68, 0x39, 0xa7, 0x0b, 0x69, 0x2c, 0xc7, 0x18, 0x83, 0x2b, 0x99, 0x34, 0x69, 0x8c, 0x64, - 0x2f, 0x8a, 0xc0, 0xd2, 0x8a, 0x9d, 0x95, 0x89, 0xdf, 0x22, 0x65, 0x4a, 0x3f, 0x8e, 0x4b, 0x97, - 0xa9, 0x8c, 0x91, 0x9b, 0x3c, 0x46, 0xd0, 0x3f, 0xdb, 0x01, 0x71, 0xdd, 0xcc, 0xec, 0xf7, 0x7d, - 0xbf, 0x61, 0x58, 0xfc, 0x61, 0xc5, 0x20, 0xe1, 0x40, 0x21, 0x0f, 0x21, 0x0b, 0x96, 0x0c, 0xe8, - 0xe6, 0x89, 0x46, 0x2c, 0x65, 0x10, 0x83, 0x9b, 0x09, 0x2e, 0x39, 0x79, 0x53, 0x4b, 0xdc, 0x8b, - 0xc4, 0xdd, 0x3c, 0x3d, 0xbe, 0x8d, 0x78, 0xc4, 0xab, 0x77, 0x5a, 0x56, 0xb5, 0xf4, 0xb1, 0xdf, - 0x95, 0xd6, 0x36, 0xb5, 0xa6, 0x7f, 0x42, 0xf8, 0xe5, 0xa4, 0x06, 0xcc, 0x65, 0x20, 0x19, 0x19, - 0x62, 0xed, 0xa2, 0x37, 0x90, 0xad, 0x3a, 0xfa, 0xe0, 0xbd, 0xdb, 0xc1, 0x74, 0xe7, 0x4d, 0xe3, - 0xf5, 0xf6, 0x47, 0x4b, 0xf1, 0xaf, 0x2e, 0xf2, 0x05, 0xab, 0xc1, 0x72, 0x6d, 0xa8, 0xcf, 0x98, - 0x87, 0xa3, 0xd9, 0x38, 0x95, 0x62, 0xeb, 0xe9, 0xa5, 0xb9, 0x38, 0x5a, 0xea, 0x70, 0x34, 0xf3, - 0x4b, 0x1b, 0x19, 0x63, 0x3d, 0x07, 0x26, 0x16, 0x91, 0xe0, 0x79, 0x06, 0xc6, 0x5d, 0x95, 0x62, - 0x76, 0xa6, 0x7c, 0x03, 0x26, 0x26, 0xa5, 0xac, 0xd9, 0x01, 0xe7, 0xed, 0x00, 0x3e, 0x3f, 0xfc, - 0xde, 0x59, 0xe8, 0xef, 0xce, 0x42, 0x7d, 0x8e, 0x1f, 0x5a, 0x1c, 0xb1, 0xb0, 0xde, 0x26, 0x2c, - 0xe2, 0x95, 0x81, 0x6c, 0xe4, 0xf4, 0x7c, 0xdc, 0x8e, 0xa6, 0x2b, 0xf2, 0x0e, 0xdf, 0xcb, 0x40, - 0x44, 0x4c, 0x1a, 0x77, 0x36, 0x72, 0x34, 0xbf, 0xe9, 0x88, 0x8d, 0xf5, 0x8c, 0x89, 0x24, 0x06, - 0x88, 0x79, 0x0a, 0x86, 0x6a, 0x23, 0xe7, 0x95, 0x7f, 0x3b, 0xba, 0x01, 0x4a, 0xac, 0x5d, 0x36, - 0x23, 0xb4, 0x83, 0xe8, 0xbd, 0x2e, 0x8e, 0x16, 0x6e, 0x0f, 0x38, 0xfd, 0xfa, 0xdf, 0x06, 0x04, - 0xf7, 0xd2, 0x20, 0x61, 0x0d, 0xbf, 0xaa, 0x89, 0x81, 0x5f, 0x24, 0x2c, 0x09, 0x99, 0x80, 0xea, - 0xaa, 0x9a, 0xdf, 0xb6, 0x57, 0xaa, 0x37, 0xdb, 0x17, 0x26, 0x3a, 0x14, 0x26, 0x3a, 0x15, 0x26, - 0xfa, 0x75, 0x36, 0x95, 0xc3, 0xd9, 0x54, 0xfe, 0x9c, 0x4d, 0xe5, 0xfb, 0x20, 0x8a, 0xe5, 0x8f, - 0x3c, 0x74, 0x97, 0x3c, 0xa1, 0xf5, 0x19, 0x3f, 0xae, 0x83, 0x10, 0x9a, 0x9a, 0x6e, 0x06, 0xf4, - 0xe7, 0xcd, 0x1f, 0x91, 0xdb, 0x8c, 0x41, 0x78, 0x5f, 0x7d, 0x8f, 0x4f, 0xff, 0x02, 0x00, 0x00, - 0xff, 0xff, 0x91, 0xf4, 0x05, 0xa7, 0x92, 0x02, 0x00, 0x00, + // 390 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x3f, 0xcf, 0xd2, 0x40, + 0x18, 0xef, 0xbd, 0x25, 0xaf, 0x6f, 0xaf, 0xea, 0x70, 0x1a, 0xd3, 0x90, 0xd8, 0x56, 0xa6, 0x2e, + 0xf6, 0x02, 0x6e, 0xc6, 0x85, 0x22, 0x21, 0x24, 0x4c, 0x25, 0x2e, 0x2e, 0xa4, 0x85, 0x4b, 0x6d, + 0x42, 0x7b, 0xcd, 0x3d, 0x57, 0x22, 0x93, 0x5f, 0xc1, 0xd1, 0x91, 0x8f, 0xc3, 0xc8, 0xe8, 0x44, + 0x48, 0x59, 0xfc, 0x18, 0xa6, 0xff, 0x80, 0x81, 0x98, 0xb8, 0x3d, 0xbf, 0xeb, 0xef, 0x5f, 0x9f, + 0x3c, 0xf8, 0xdd, 0x8a, 0x41, 0xc2, 0x81, 0x42, 0x1e, 0x42, 0x16, 0x2c, 0x19, 0xd0, 0x4d, 0x9f, + 0x46, 0x2c, 0x65, 0x10, 0x83, 0x9b, 0x09, 0x2e, 0x39, 0x79, 0x55, 0x53, 0xdc, 0x0b, 0xc5, 0xdd, + 0xf4, 0xbb, 0xaf, 0x23, 0x1e, 0xf1, 0xea, 0x3b, 0x2d, 0xa7, 0x9a, 0xda, 0xed, 0xdd, 0x73, 0x6b, + 0x41, 0xcd, 0xe9, 0x9d, 0x10, 0x7e, 0x3e, 0xa9, 0x03, 0xe6, 0x32, 0x90, 0x8c, 0x0c, 0xb1, 0x76, + 0xe1, 0x1b, 0xc8, 0x56, 0x1d, 0x7d, 0xf0, 0xd6, 0xbd, 0x93, 0xe9, 0xce, 0x1b, 0xe0, 0x75, 0xf6, + 0x47, 0x4b, 0xf1, 0xaf, 0x2a, 0xf2, 0x09, 0xab, 0xc1, 0x72, 0x6d, 0xa8, 0xff, 0x10, 0x0f, 0x47, + 0xb3, 0x71, 0x2a, 0xc5, 0xd6, 0xd3, 0x4b, 0x71, 0x71, 0xb4, 0xd4, 0xe1, 0x68, 0xe6, 0x97, 0x32, + 0x32, 0xc6, 0x7a, 0x0e, 0x4c, 0x2c, 0x22, 0xc1, 0xf3, 0x0c, 0x8c, 0x87, 0xca, 0xc5, 0xbc, 0xeb, + 0xf2, 0x05, 0x98, 0x98, 0x94, 0xb4, 0xa6, 0x03, 0xce, 0xdb, 0x07, 0xf8, 0xf8, 0xf4, 0x6b, 0x67, + 0xa1, 0x3f, 0x3b, 0x0b, 0xf5, 0x7e, 0xe0, 0xa7, 0x36, 0x8e, 0x50, 0xac, 0xb7, 0x0e, 0x8b, 0x78, + 0x65, 0x20, 0x1b, 0x39, 0x1d, 0xef, 0x65, 0x71, 0xb4, 0x70, 0xfb, 0x3b, 0xd3, 0xcf, 0x3e, 0x6e, + 0x29, 0xd3, 0x15, 0x79, 0x83, 0x1f, 0x65, 0x20, 0x22, 0x26, 0x8d, 0x07, 0x1b, 0x39, 0x9a, 0xdf, + 0x20, 0x62, 0x63, 0x3d, 0x63, 0x22, 0x89, 0x01, 0x62, 0x9e, 0x82, 0xa1, 0xda, 0xc8, 0x79, 0xe1, + 0xdf, 0x3e, 0xdd, 0x14, 0x90, 0x58, 0xbb, 0x34, 0xfd, 0xff, 0x06, 0x04, 0x77, 0xd2, 0x20, 0x61, + 0x4d, 0x7e, 0x35, 0x13, 0x03, 0x3f, 0x4b, 0x58, 0x12, 0x32, 0x01, 0xd5, 0x96, 0x35, 0xbf, 0x85, + 0xd7, 0x54, 0x6f, 0xb6, 0x2f, 0x4c, 0x74, 0x28, 0x4c, 0x74, 0x2a, 0x4c, 0xf4, 0xf3, 0x6c, 0x2a, + 0x87, 0xb3, 0xa9, 0xfc, 0x3e, 0x9b, 0xca, 0xd7, 0x41, 0x14, 0xcb, 0x6f, 0x79, 0xe8, 0x2e, 0x79, + 0x42, 0xeb, 0xb5, 0xbe, 0x5f, 0x07, 0x21, 0x34, 0x33, 0xdd, 0x0c, 0xe8, 0xf7, 0x9b, 0x9b, 0x91, + 0xdb, 0x8c, 0x41, 0xf8, 0x58, 0x9d, 0xcb, 0x87, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x22, 0xa6, + 0x52, 0xfa, 0xa2, 0x02, 0x00, 0x00, } func (this *GenesisState) Equal(that interface{}) bool { @@ -309,7 +309,7 @@ func (this *ACLEntry) Equal(that interface{}) bool { } else if this == nil { return false } - if this.SubspaceId != that1.SubspaceId { + if this.SubspaceID != that1.SubspaceID { return false } if this.Target != that1.Target { @@ -452,8 +452,8 @@ func (m *ACLEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x12 } - if m.SubspaceId != 0 { - i = encodeVarintGenesis(dAtA, i, uint64(m.SubspaceId)) + if m.SubspaceID != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.SubspaceID)) i-- dAtA[i] = 0x8 } @@ -548,8 +548,8 @@ func (m *ACLEntry) Size() (n int) { } var l int _ = l - if m.SubspaceId != 0 { - n += 1 + sovGenesis(uint64(m.SubspaceId)) + if m.SubspaceID != 0 { + n += 1 + sovGenesis(uint64(m.SubspaceID)) } l = len(m.Target) if l > 0 { @@ -772,9 +772,9 @@ func (m *ACLEntry) Unmarshal(dAtA []byte) error { switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SubspaceId", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) } - m.SubspaceId = 0 + m.SubspaceID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -784,7 +784,7 @@ func (m *ACLEntry) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.SubspaceId |= uint64(b&0x7F) << shift + m.SubspaceID |= uint64(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/subspaces/types/genesis_test.go b/x/subspaces/types/genesis_test.go index 846349ec1a..079a4dc20a 100644 --- a/x/subspaces/types/genesis_test.go +++ b/x/subspaces/types/genesis_test.go @@ -1,197 +1,261 @@ package types_test -// -//import ( -// "testing" -// "time" -// -// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" -// -// "github.com/stretchr/testify/require" -//) -// -//func TestValidateGenesis(t *testing.T) { -// date, err := time.Parse(time.RFC3339, "2050-01-01T15:15:00.000Z") -// require.NoError(t, err) -// -// tests := []struct { -// name string -// genesis *types2.GenesisState -// shouldErr bool -// }{ -// { -// name: "Default genesis does not error", -// genesis: types2.DefaultGenesisState(), -// shouldErr: false, -// }, -// { -// name: "Genesis with invalid subspaces returns error", -// genesis: types2.NewGenesisState( -// []types2.Subspace{ -// types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "", -// "", -// "", -// types2.SubspaceTypeOpen, -// time.Time{}, -// ), -// }, -// nil, -// nil, -// nil, -// ), -// shouldErr: true, -// }, -// { -// name: "Genesis with duplicated subspaces returns error", -// genesis: types2.NewGenesisState( -// []types2.Subspace{ -// types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "name", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// types2.SubspaceTypeOpen, -// date, -// ), -// types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "name", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// types2.SubspaceTypeOpen, -// date, -// ), -// }, -// nil, -// nil, -// nil, -// ), -// shouldErr: true, -// }, -// { -// name: "Genesis with duplicated admins entry returns error", -// genesis: types2.NewGenesisState( -// nil, -// []types2.UsersEntry{ -// types2.NewUsersEntry( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, -// ), -// types2.NewUsersEntry( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, -// ), -// }, -// nil, -// nil, -// ), -// shouldErr: true, -// }, -// { -// name: "Genesis with duplicated admins returns error", -// genesis: types2.NewGenesisState( -// nil, -// []types2.UsersEntry{ -// types2.NewUsersEntry( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// []string{ -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// }, -// ), -// }, -// nil, -// nil, -// ), -// shouldErr: true, -// }, -// { -// name: "Genesis with duplicated registered users entry returns error", -// genesis: types2.NewGenesisState( -// nil, -// nil, -// []types2.UsersEntry{ -// types2.NewUsersEntry( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, -// ), -// types2.NewUsersEntry( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, -// ), -// }, -// nil, -// ), -// shouldErr: true, -// }, -// { -// name: "Genesis with duplicated registered users returns error", -// genesis: types2.NewGenesisState( -// nil, -// nil, -// []types2.UsersEntry{ -// types2.NewUsersEntry( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// []string{ -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// }, -// ), -// }, -// nil, -// ), -// shouldErr: true, -// }, -// { -// name: "Genesis with duplicated banned users entry returns error", -// genesis: types2.NewGenesisState( -// nil, -// nil, -// nil, -// []types2.UsersEntry{ -// types2.NewUsersEntry( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// []string{"cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4"}, -// ), -// types2.NewUsersEntry( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// []string{"cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn"}, -// ), -// }, -// ), -// shouldErr: true, -// }, -// { -// name: "Genesis with duplicated banned users returns error", -// genesis: types2.NewGenesisState( -// nil, -// nil, -// nil, -// []types2.UsersEntry{ -// types2.NewUsersEntry( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// []string{ -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// }, -// ), -// }, -// ), -// shouldErr: true, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err = types2.ValidateGenesis(test.genesis) -// if test.shouldErr { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} +import ( + "testing" + "time" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + "github.com/stretchr/testify/require" +) + +func TestACLEntry_Validate(t *testing.T) { + testCases := []struct { + name string + entry types.ACLEntry + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + entry: types.NewACLEntry( + 0, + "group", + types.PermissionWrite, + ), + shouldErr: true, + }, + { + name: "valid group entry returns no error", + entry: types.NewACLEntry( + 1, + "group", + types.PermissionWrite, + ), + shouldErr: false, + }, + { + name: "valid user entry returns no error", + entry: types.NewACLEntry( + 1, + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + types.PermissionEverything, + ), + shouldErr: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.entry.Validate() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestUserGroup_Validate(t *testing.T) { + testCases := []struct { + name string + group types.UserGroup + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + group: types.NewUserGroup(0, "group", nil), + shouldErr: true, + }, + { + name: "invalid group name returns error", + group: types.NewUserGroup(1, "", nil), + shouldErr: true, + }, + { + name: "invalid member returns error", + group: types.NewUserGroup(1, "group", []string{ + "another-group", + }), + shouldErr: true, + }, + { + name: "valid group returns no error", + group: types.NewUserGroup(1, "group", []string{ + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + }), + shouldErr: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.group.Validate() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestValidateGenesis(t *testing.T) { + testCases := []struct { + name string + genesis *types.GenesisState + shouldErr bool + }{ + { + name: "invalid subspace returns error", + genesis: types.NewGenesisState( + []types.Subspace{ + types.NewSubspace( + 1, + "", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + nil, + nil, + ), + shouldErr: true, + }, + { + name: "duplicated subspace returns error", + genesis: types.NewGenesisState( + []types.Subspace{ + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + types.NewSubspace( + 1, + "Another test subspace", + "This is another test subspace", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + nil, + nil, + ), + shouldErr: true, + }, + { + name: "invalid ACL entry returns error", + genesis: types.NewGenesisState( + nil, + []types.ACLEntry{ + types.NewACLEntry(0, "group", types.PermissionWrite), + }, + nil, + ), + shouldErr: true, + }, + { + name: "duplicated ACL entry returns error", + genesis: types.NewGenesisState( + nil, + []types.ACLEntry{ + types.NewACLEntry(1, "group", types.PermissionWrite), + types.NewACLEntry(1, "group", types.PermissionSetPermissions), + }, + nil, + ), + shouldErr: true, + }, + { + name: "invalid group returns error", + genesis: types.NewGenesisState( + nil, + nil, + []types.UserGroup{ + types.NewUserGroup(0, "group", nil), + }, + ), + shouldErr: true, + }, + { + name: "duplicated group returns error", + genesis: types.NewGenesisState( + nil, + nil, + []types.UserGroup{ + types.NewUserGroup(1, "group", nil), + types.NewUserGroup(1, "group", nil), + }, + ), + shouldErr: true, + }, + { + name: "default genesis returns no error", + genesis: types.DefaultGenesisState(), + shouldErr: false, + }, + { + name: "valid genesis state returns no error", + genesis: types.NewGenesisState( + []types.Subspace{ + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + }, + []types.ACLEntry{ + types.NewACLEntry(1, "group", types.PermissionWrite), + types.NewACLEntry(2, "another-group", types.PermissionManageGroups), + }, + []types.UserGroup{ + types.NewUserGroup(1, "group", []string{ + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + }), + types.NewUserGroup(2, "another-group", []string{ + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + }), + }, + ), + shouldErr: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := types.ValidateGenesis(tc.genesis) + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/x/subspaces/types/msgs.go b/x/subspaces/types/msgs.go index a8a7a69bd7..2e17060832 100644 --- a/x/subspaces/types/msgs.go +++ b/x/subspaces/types/msgs.go @@ -31,27 +31,27 @@ func (msg MsgCreateSubspace) Type() string { return ActionCreateSubspace } // ValidateBasic implements sdk.Msg func (msg MsgCreateSubspace) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(msg.Creator) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address") - } - - _, err = sdk.AccAddressFromBech32(msg.Owner) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid owner address") - } - if strings.TrimSpace(msg.Name) == "" { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "subspace name cannot be empty or blank") } if msg.Treasury != "" { - _, err = sdk.AccAddressFromBech32(msg.Treasury) + _, err := sdk.AccAddressFromBech32(msg.Treasury) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid treasury address") } } + _, err := sdk.AccAddressFromBech32(msg.Owner) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid owner address") + } + + _, err = sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address") + } + return nil } @@ -88,18 +88,15 @@ func (msg MsgEditSubspace) Type() string { return ActionEditSubspace } // ValidateBasic implements sdk.Msg func (msg MsgEditSubspace) ValidateBasic() error { + if msg.SubspaceID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) + } + _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") } - if strings.TrimSpace(msg.Owner) != "" { - _, err = sdk.AccAddressFromBech32(msg.Owner) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid owner address") - } - } - return nil } @@ -134,15 +131,19 @@ func (msg MsgCreateUserGroup) Type() string { return ActionCreateUserGroup } // ValidateBasic implements sdk.Msg func (msg MsgCreateUserGroup) ValidateBasic() error { + if msg.SubspaceID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) + } + + if strings.TrimSpace(msg.GroupName) == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group name: %s", msg.GroupName) + } + _, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address") } - if strings.TrimSpace(msg.GroupName) != "" { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group name cannot be empty or blank") - } - return nil } @@ -176,15 +177,19 @@ func (msg MsgDeleteUserGroup) Type() string { return ActionDeleteUserGroup } // ValidateBasic implements sdk.Msg func (msg MsgDeleteUserGroup) ValidateBasic() error { + if msg.SubspaceID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) + } + + if strings.TrimSpace(msg.GroupName) == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group name: %s", msg.GroupName) + } + _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") } - if strings.TrimSpace(msg.GroupName) != "" { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group name cannot be empty or blank") - } - return nil } @@ -219,18 +224,22 @@ func (msg MsgAddUserToUserGroup) Type() string { return ActionAddUserToUserGroup // ValidateBasic implements sdk.Msg func (msg MsgAddUserToUserGroup) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(msg.Signer) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + if msg.SubspaceID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) + } + + if strings.TrimSpace(msg.GroupName) == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group name: %s", msg.GroupName) } - _, err = sdk.AccAddressFromBech32(msg.User) + _, err := sdk.AccAddressFromBech32(msg.User) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address") } - if strings.TrimSpace(msg.GroupName) != "" { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group name cannot be empty or blank") + _, err = sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") } return nil @@ -267,18 +276,22 @@ func (msg MsgRemoveUserFromUserGroup) Type() string { return ActionRemoveUserFro // ValidateBasic implements sdk.Msg func (msg MsgRemoveUserFromUserGroup) ValidateBasic() error { - _, err := sdk.AccAddressFromBech32(msg.Signer) - if err != nil { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + if msg.SubspaceID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) + } + + if strings.TrimSpace(msg.GroupName) == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group name: %s", msg.GroupName) } - _, err = sdk.AccAddressFromBech32(msg.User) + _, err := sdk.AccAddressFromBech32(msg.User) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address") } - if strings.TrimSpace(msg.GroupName) != "" { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group name cannot be empty or blank") + _, err = sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") } return nil @@ -315,6 +328,14 @@ func (msg MsgSetPermissions) Type() string { return ActionSetPermissions } // ValidateBasic implements sdk.Msg func (msg MsgSetPermissions) ValidateBasic() error { + if msg.SubspaceID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) + } + + if strings.TrimSpace(msg.Target) == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid target: %s", msg.Target) + } + _, err := sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") diff --git a/x/subspaces/types/msgs_test.go b/x/subspaces/types/msgs_test.go index 36f6981a0e..633093d959 100644 --- a/x/subspaces/types/msgs_test.go +++ b/x/subspaces/types/msgs_test.go @@ -1,811 +1,608 @@ package types_test -// -//import ( -// "testing" -// -// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -// "github.com/stretchr/testify/require" -//) -// -//func TestMsgCreateSubspace_Route(t *testing.T) { -// msg := types2.NewMsgCreateSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "mooncake", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ) -// require.Equal(t, "subspaces", msg.Route()) -//} -// -//func TestMsgCreateSubspace_Type(t *testing.T) { -// msg := types2.NewMsgCreateSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "mooncake", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ) -// require.Equal(t, "create_subspace", msg.Type()) -//} -// -//func TestMsgCreateSubspace_ValidateBasic(t *testing.T) { -// tests := []struct { -// name string -// msg *types2.MsgCreateSubspace -// expErr bool -// }{ -// { -// name: "invalid subspace id returns error", -// msg: types2.NewMsgCreateSubspace( -// "", -// "mooncake", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace creator address returns error", -// msg: types2.NewMsgCreateSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "mooncake", -// "", -// types2.SubspaceTypeOpen, -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace name returns error", -// msg: types2.NewMsgCreateSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ), -// expErr: true, -// }, -// { -// name: "valid message returns no error", -// msg: types2.NewMsgCreateSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "mooncake", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ), -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err := test.msg.ValidateBasic() -// if test.expErr { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} -// -//func TestMsgCreateSubspace_GetSignBytes(t *testing.T) { -// msg := types2.NewMsgCreateSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "mooncake", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ) -// expected := `{"creator":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","name":"mooncake","subspace_type":1}` -// require.Equal(t, expected, string(msg.GetSignBytes())) -//} -// -//func TestMsgCreateSubspace_GetSigners(t *testing.T) { -// msg := types2.NewMsgCreateSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "mooncake", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ) -// addr, _ := sdk.AccAddressFromBech32(msg.Creator) -// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -//} -// -//func TestMsgEditSubspace_Route(t *testing.T) { -// msg := types2.NewMsgEditSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "star", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ) -// require.Equal(t, "subspaces", msg.Route()) -//} -// -//func TestMsgEditSubspace_Type(t *testing.T) { -// msg := types2.NewMsgEditSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "star", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ) -// require.Equal(t, "edit_subspace", msg.Type()) -//} -// -//func TestMsgEditSubspace_ValidateBasic(t *testing.T) { -// tests := []struct { -// name string -// msg *types2.MsgEditSubspace -// expErr bool -// }{ -// { -// name: "invalid subspace id returns error", -// msg: types2.NewMsgEditSubspace( -// "", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "star", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace owner address returns error", -// msg: types2.NewMsgEditSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "star", -// "", -// types2.SubspaceTypeOpen, -// ), -// expErr: true, -// }, -// { -// name: "equal subspace owner and new owner addresses returns error", -// msg: types2.NewMsgEditSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// "star", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ), -// expErr: true, -// }, -// { -// name: "valid message returns no error", -// msg: types2.NewMsgEditSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "star", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ), -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err := test.msg.ValidateBasic() -// if test.expErr { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} -// -//func TestMsgEditSubspace_GetSignBytes(t *testing.T) { -// msg := types2.NewMsgEditSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "star", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ) -// expected := `{"editor":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","name":"star","owner":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","subspace_type":1}` -// require.Equal(t, expected, string(msg.GetSignBytes())) -//} -// -//func TestMsgEditSubspace_GetSigners(t *testing.T) { -// msg := types2.NewMsgEditSubspace( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "star", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// types2.SubspaceTypeOpen, -// ) -// addr, _ := sdk.AccAddressFromBech32(msg.Editor) -// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -//} -// -//func TestMsgAddAdmin_Route(t *testing.T) { -// msg := types2.NewMsgAddAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "subspaces", msg.Route()) -//} -// -//func TestMsgAddAdmin_Type(t *testing.T) { -// msg := types2.NewMsgAddAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "add_admin", msg.Type()) -//} -// -//func TestMsgAddAdmin_ValidateBasic(t *testing.T) { -// tests := []struct { -// name string -// msg *types2.MsgAddAdmin -// expErr bool -// }{ -// { -// name: "invalid subspace id returns error", -// msg: types2.NewMsgAddAdmin( -// "", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "equals owner and admin addresses returns error", -// msg: types2.NewMsgAddAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace owner address returns error", -// msg: types2.NewMsgAddAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace new admin address returns error", -// msg: types2.NewMsgAddAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "valid message returns no error", -// msg: types2.NewMsgAddAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: false, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err := test.msg.ValidateBasic() -// if test.expErr { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} -// -//func TestMsgAddAdmin_GetSignBytes(t *testing.T) { -// msg := types2.NewMsgAddAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// expected := `{"admin":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","owner":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af"}` -// require.Equal(t, expected, string(msg.GetSignBytes())) -//} -// -//func TestMsgAddAdmin_GetSigners(t *testing.T) { -// msg := types2.NewMsgAddAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// addr, _ := sdk.AccAddressFromBech32(msg.Owner) -// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -//} -// -//func TestMsgRemoveAdmin_Route(t *testing.T) { -// msg := types2.NewMsgRemoveAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "subspaces", msg.Route()) -//} -// -//func TestMsgRemoveAdmin_Type(t *testing.T) { -// msg := types2.NewMsgRemoveAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "remove_admin", msg.Type()) -//} -// -//func TestMsgRemoveAdmin_ValidateBasic(t *testing.T) { -// tests := []struct { -// name string -// msg *types2.MsgRemoveAdmin -// expErr bool -// }{ -// { -// name: "invalid subspace id returns error", -// msg: types2.NewMsgRemoveAdmin( -// "", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "equals owner and admin addresses returns error", -// msg: types2.NewMsgRemoveAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace owner address returns error", -// msg: types2.NewMsgRemoveAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace admin address returns error", -// msg: types2.NewMsgRemoveAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "valid message returns no error", -// msg: types2.NewMsgRemoveAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: false, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err := test.msg.ValidateBasic() -// if test.expErr { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} -// -//func TestMsgRemoveAdmin_GetSignBytes(t *testing.T) { -// msg := types2.NewMsgRemoveAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// expected := `{"admin":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h","owner":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af"}` -// require.Equal(t, expected, string(msg.GetSignBytes())) -//} -// -//func TestMsgRemoveAdmin_GetSigners(t *testing.T) { -// msg := types2.NewMsgRemoveAdmin( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// addr, _ := sdk.AccAddressFromBech32(msg.Owner) -// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -//} -// -//func TestMsgRegisterUser_Route(t *testing.T) { -// msg := types2.NewMsgRegisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "subspaces", msg.Route()) -//} -// -//func TestMsgRegisterUser_Type(t *testing.T) { -// msg := types2.NewMsgRegisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "register_user", msg.Type()) -//} -// -//func TestMsgRegisterUser_ValidateBasic(t *testing.T) { -// tests := []struct { -// name string -// msg *types2.MsgRegisterUser -// expErr bool -// }{ -// { -// name: "invalid subspace id returns error", -// msg: types2.NewMsgRegisterUser( -// "", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace admin address returns error", -// msg: types2.NewMsgRegisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace user address returns error", -// msg: types2.NewMsgRegisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "valid message returns no error", -// msg: types2.NewMsgRegisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: false, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err := test.msg.ValidateBasic() -// if test.expErr { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} -// -//func TestMsgRegisterUser_GetSignBytes(t *testing.T) { -// msg := types2.NewMsgRegisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` -// require.Equal(t, expected, string(msg.GetSignBytes())) -//} -// -//func TestMsgRegisterUser_GetSigners(t *testing.T) { -// msg := types2.NewMsgRegisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// addr, _ := sdk.AccAddressFromBech32(msg.Admin) -// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -//} -// -//func TestMsgUnregisterUser_Route(t *testing.T) { -// msg := types2.NewMsgUnregisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "subspaces", msg.Route()) -//} -// -//func TestMsgUnregisterUser_Type(t *testing.T) { -// msg := types2.NewMsgUnregisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "unregister_user", msg.Type()) -//} -// -//func TestMsgUnregisterUser_ValidateBasic(t *testing.T) { -// tests := []struct { -// name string -// msg *types2.MsgUnregisterUser -// expErr bool -// }{ -// { -// name: "invalid subspace id returns error", -// msg: types2.NewMsgUnregisterUser( -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace admin address returns error", -// msg: types2.NewMsgUnregisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace user address returns error", -// msg: types2.NewMsgUnregisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "valid message returns no error", -// msg: types2.NewMsgUnregisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: false, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err := test.msg.ValidateBasic() -// if test.expErr { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} -// -//func TestMsgUnregisterUser_GetSignBytes(t *testing.T) { -// msg := types2.NewMsgUnregisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` -// require.Equal(t, expected, string(msg.GetSignBytes())) -//} -// -//func TestMsgUnregisterUser_GetSigners(t *testing.T) { -// msg := types2.NewMsgUnregisterUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// addr, _ := sdk.AccAddressFromBech32(msg.Admin) -// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -//} -// -//func TestMsgBanUser_Route(t *testing.T) { -// msg := types2.NewMsgBanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "subspaces", msg.Route()) -//} -// -//func TestMsgBanUser_Type(t *testing.T) { -// msg := types2.NewMsgBanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "block_user", msg.Type()) -//} -// -//func TestMsgBanUser_ValidateBasic(t *testing.T) { -// tests := []struct { -// name string -// msg *types2.MsgBanUser -// expErr bool -// }{ -// { -// name: "invalid subspace id returns error", -// msg: types2.NewMsgBanUser( -// "", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace admin address returns error", -// msg: types2.NewMsgBanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace user address returns error", -// msg: types2.NewMsgBanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "valid message returns no error", -// msg: types2.NewMsgBanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: false, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err := test.msg.ValidateBasic() -// if test.expErr { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} -// -//func TestMsgBanUser_GetSignBytes(t *testing.T) { -// msg := types2.NewMsgBanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` -// require.Equal(t, expected, string(msg.GetSignBytes())) -//} -// -//func TestMsgBanUser_GetSigners(t *testing.T) { -// msg := types2.NewMsgBanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// addr, _ := sdk.AccAddressFromBech32(msg.Admin) -// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -//} -// -//func TestTestMsgUnbanUser_Route(t *testing.T) { -// msg := types2.NewMsgUnbanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "subspaces", msg.Route()) -//} -// -//func TestTestMsgUnbanUser_Type(t *testing.T) { -// msg := types2.NewMsgUnbanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// require.Equal(t, "unblock_user", msg.Type()) -//} -// -//func TestTestMsgUnbanUser_ValidateBasic(t *testing.T) { -// tests := []struct { -// name string -// msg *types2.MsgUnbanUser -// expErr bool -// }{ -// { -// name: "invalid subspace id returns error", -// msg: types2.NewMsgUnbanUser( -// "", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace admin address returns error", -// msg: types2.NewMsgUnbanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "", -// ), -// expErr: true, -// }, -// { -// name: "invalid subspace user address returns error", -// msg: types2.NewMsgUnbanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: true, -// }, -// { -// name: "valid message returns no error", -// msg: types2.NewMsgUnbanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ), -// expErr: false, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err := test.msg.ValidateBasic() -// if test.expErr { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} -// -//func TestTestMsgUnbanUser_GetSignBytes(t *testing.T) { -// msg := types2.NewMsgUnbanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// expected := `{"admin":"cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns","subspace_id":"19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af","user":"cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h"}` -// require.Equal(t, expected, string(msg.GetSignBytes())) -//} -// -//func TestTestMsgUnbanUser_GetSigners(t *testing.T) { -// msg := types2.NewMsgUnbanUser( -// "19de02e105c68a60e45c289bff19fde745bca9c63c38f2095b59e8e8090ae1af", -// "cosmos16vphdl9nhm26murvfrrp8gdsknvfrxctl6y29h", -// "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", -// ) -// addr, _ := sdk.AccAddressFromBech32(msg.Admin) -// require.Equal(t, []sdk.AccAddress{addr}, msg.GetSigners()) -//} +import ( + "testing" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +var msgCreateSubspace = types.NewMsgCreateSubspace( + "Test subspace", + "This is a test subspace", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + "cosmos1lv3e0l66rr68k5l74mnrv4j9kyny6cz27pvnez", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", +) + +func TestMsgCreateSubspace_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgCreateSubspace.Route()) +} + +func TestMsgCreateSubspace_Type(t *testing.T) { + require.Equal(t, types.ActionCreateSubspace, msgCreateSubspace.Type()) +} + +func TestMsgCreateSubspace_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgCreateSubspace + shouldErr bool + }{ + { + name: "invalid name returns error", + msg: types.NewMsgCreateSubspace( + "", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + ), + shouldErr: true, + }, + { + name: "invalid treasury returns error", + msg: types.NewMsgCreateSubspace( + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + ), + shouldErr: true, + }, + { + name: "invalid owner returns error", + msg: types.NewMsgCreateSubspace( + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4ye", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + ), + shouldErr: true, + }, + { + name: "invalid creator returns error", + msg: types.NewMsgCreateSubspace( + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "", + ), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgCreateSubspace, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgCreateSubspace_GetSignBytes(t *testing.T) { + expected := `{"creator":"cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69","description":"This is a test subspace","name":"Test subspace","owner":"cosmos1lv3e0l66rr68k5l74mnrv4j9kyny6cz27pvnez","treasury":"cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0"}` + require.Equal(t, expected, string(msgCreateSubspace.GetSignBytes())) +} + +func TestMsgCreateSubspace_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgCreateSubspace.Creator) + require.Equal(t, []sdk.AccAddress{addr}, msgCreateSubspace.GetSigners()) +} + +// -------------------------------------------------------------------------------------------------------------------- + +var msgEditSubspace = types.NewMsgEditSubspace( + 1, + "This is a new name", + "This is a new description", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", +) + +func TestMsgEditSubspace_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgEditSubspace.Route()) +} + +func TestMsgEditSubspace_Type(t *testing.T) { + require.Equal(t, types.ActionEditSubspace, msgEditSubspace.Type()) +} + +func TestMsgEditSubspace_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgEditSubspace + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types.NewMsgEditSubspace( + 0, + "This is a new name", + "This is a new description", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid signer returns error", + msg: types.NewMsgEditSubspace( + 1, + "This is a new name", + "This is a new description", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3z", + ), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgEditSubspace, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgEditSubspace_GetSignBytes(t *testing.T) { + expected := `{"description":"This is a new description","name":"This is a new name","owner":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","treasury":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"}` + require.Equal(t, expected, string(msgEditSubspace.GetSignBytes())) +} + +func TestMsgEditSubspace_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgEditSubspace.Signer) + require.Equal(t, []sdk.AccAddress{addr}, msgEditSubspace.GetSigners()) +} + +// -------------------------------------------------------------------------------------------------------------------- + +var msgCreateUserGroup = types.NewMsgCreateUserGroup( + 1, + "group", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", +) + +func TestMsgCreateUserGroup_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgCreateUserGroup.Route()) +} + +func TestMsgCreateUserGroup_Type(t *testing.T) { + require.Equal(t, types.ActionCreateUserGroup, msgCreateUserGroup.Type()) +} + +func TestMsgCreateUserGroup_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgCreateUserGroup + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types.NewMsgCreateUserGroup( + 0, + "group", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid group name returns error", + msg: types.NewMsgCreateUserGroup( + 1, + "", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid creator returns error", + msg: types.NewMsgCreateUserGroup( + 1, + "group", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kl", + ), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgCreateUserGroup, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgCreateUserGroup_GetSignBytes(t *testing.T) { + expected := `{"creator":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","default_permissions":1,"group_name":"group","subspace_id":"1"}` + require.Equal(t, expected, string(msgCreateUserGroup.GetSignBytes())) +} + +func TestMsgCreateUserGroup_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgCreateUserGroup.Creator) + require.Equal(t, []sdk.AccAddress{addr}, msgCreateUserGroup.GetSigners()) +} + +// -------------------------------------------------------------------------------------------------------------------- + +var msgDeleteUserGroup = types.NewMsgDeleteUserGroup( + 1, + "group", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", +) + +func TestMsgDeleteUserGroup_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgDeleteUserGroup.Route()) +} + +func TestMsgDeleteUserGroup_Type(t *testing.T) { + require.Equal(t, types.ActionDeleteUserGroup, msgDeleteUserGroup.Type()) +} + +func TestMsgDeleteUserGroup_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgDeleteUserGroup + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types.NewMsgDeleteUserGroup( + 0, + "group", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid group name returns error", + msg: types.NewMsgDeleteUserGroup( + 1, + "", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid signer returns error", + msg: types.NewMsgDeleteUserGroup( + 1, + "group", + "cosmos1m0czrla04f7rp3zg7dsgc4kl", + ), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgDeleteUserGroup, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgDeleteUserGroup_GetSignBytes(t *testing.T) { + expected := `{"group_name":"group","signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1"}` + require.Equal(t, expected, string(msgDeleteUserGroup.GetSignBytes())) +} + +func TestMsgDeleteUserGroup_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgDeleteUserGroup.Signer) + require.Equal(t, []sdk.AccAddress{addr}, msgDeleteUserGroup.GetSigners()) +} + +// -------------------------------------------------------------------------------------------------------------------- + +var msgAddUserToGroup = types.NewMsgAddUserToUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", +) + +func TestMsgAddUserToUserGroup_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgAddUserToGroup.Route()) +} + +func TestMsgAddUserToUserGroup_Type(t *testing.T) { + require.Equal(t, types.ActionAddUserToUserGroup, msgAddUserToGroup.Type()) +} + +func TestMsgAddUserToUserGroup_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgAddUserToUserGroup + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types.NewMsgAddUserToUserGroup( + 0, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid group name returns error", + msg: types.NewMsgAddUserToUserGroup( + 1, + "", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid user returns error", + msg: types.NewMsgAddUserToUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znn", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid signer returns error", + msg: types.NewMsgAddUserToUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7d", + ), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgAddUserToGroup, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgAddUserToUserGroup_GetSignBytes(t *testing.T) { + expected := `{"group_name":"group","signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","user":"cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"}` + require.Equal(t, expected, string(msgAddUserToGroup.GetSignBytes())) +} + +func TestMsgAddUserToUserGroup_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgAddUserToGroup.Signer) + require.Equal(t, []sdk.AccAddress{addr}, msgAddUserToGroup.GetSigners()) +} + +// -------------------------------------------------------------------------------------------------------------------- + +var msgRemoveUserFromUserGroup = types.NewMsgRemoveUserFromUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", +) + +func TestMsgRemoveUserFromUserGroup_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgRemoveUserFromUserGroup.Route()) +} + +func TestMsgRemoveUserFromUserGroup_Type(t *testing.T) { + require.Equal(t, types.ActionRemoveUserFromUserGroup, msgRemoveUserFromUserGroup.Type()) +} + +func TestMsgRemoveUserFromUserGroup_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgRemoveUserFromUserGroup + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types.NewMsgRemoveUserFromUserGroup( + 0, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid group name returns error", + msg: types.NewMsgRemoveUserFromUserGroup( + 1, + "", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid user returns error", + msg: types.NewMsgRemoveUserFromUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znn", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid signer returns error", + msg: types.NewMsgRemoveUserFromUserGroup( + 1, + "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7d", + ), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgRemoveUserFromUserGroup, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgRemoveUserFromUserGroup_GetSignBytes(t *testing.T) { + expected := `{"group_name":"group","signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","user":"cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"}` + require.Equal(t, expected, string(msgRemoveUserFromUserGroup.GetSignBytes())) +} + +func TestMsgRemoveUserFromUserGroup_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgRemoveUserFromUserGroup.Signer) + require.Equal(t, []sdk.AccAddress{addr}, msgRemoveUserFromUserGroup.GetSigners()) +} + +// -------------------------------------------------------------------------------------------------------------------- +var msgSetPermissions = types.NewMsgSetPermissions( + 1, + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", +) + +func TestMsgSetPermissions_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgSetPermissions.Route()) +} + +func TestMsgSetPermissions_Type(t *testing.T) { + require.Equal(t, types.ActionSetPermissions, msgSetPermissions.Type()) +} + +func TestMsgSetPermissions_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgSetPermissions + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types.NewMsgSetPermissions( + 0, + "group", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid target returns error", + msg: types.NewMsgSetPermissions( + 1, + "", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid signer returns error", + msg: types.NewMsgSetPermissions( + 1, + "group", + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7d", + ), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgSetPermissions, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgSetPermissions_GetSignBytes(t *testing.T) { + expected := `{"permissions":1,"signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","target":"cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"}` + require.Equal(t, expected, string(msgSetPermissions.GetSignBytes())) +} + +func TestMsgSetPermissions_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgSetPermissions.Signer) + require.Equal(t, []sdk.AccAddress{addr}, msgSetPermissions.GetSigners()) +} diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go index 4ff7595d21..654645b738 100644 --- a/x/subspaces/types/permissions.go +++ b/x/subspaces/types/permissions.go @@ -8,7 +8,7 @@ import ( type Permission = uint32 const ( - // PermissionNothing represents hte permission to do nothing + // PermissionNothing represents the permission to do nothing PermissionNothing = Permission(0b000000) // PermissionWrite identifies users that can create content inside the subspace @@ -23,7 +23,7 @@ const ( // PermissionManageGroups allows users to manage user groups and members PermissionManageGroups = Permission(0b001000) - // PermissionSetPermissions allows to set other users' permissions (except PermissionSetPermissions). + // PermissionSetPermissions allows users to set other users' permissions (except PermissionSetPermissions). // This includes managing user groups and the associated permissions PermissionSetPermissions = Permission(0b010000) @@ -56,7 +56,7 @@ func CheckPermission(permissions Permission, permission Permission) bool { func CombinePermissions(permissions ...Permission) Permission { result := PermissionNothing for _, permission := range permissions { - result = result | permission + result |= permission } return result } diff --git a/x/subspaces/types/subspace.go b/x/subspaces/types/subspace.go index 7b73500e12..423d62bea7 100644 --- a/x/subspaces/types/subspace.go +++ b/x/subspaces/types/subspace.go @@ -31,6 +31,13 @@ func (sub Subspace) Validate() error { return fmt.Errorf("subspace name cannot be empty or blank") } + if sub.Treasury != "" { + _, err := sdk.AccAddressFromBech32(sub.Treasury) + if err != nil { + return fmt.Errorf("invalid treasury address: %s", sub.Treasury) + } + } + _, err := sdk.AccAddressFromBech32(sub.Owner) if err != nil { return fmt.Errorf("invalid owner address: %s", sub.Owner) @@ -41,13 +48,6 @@ func (sub Subspace) Validate() error { return fmt.Errorf("invalid creator address: %s", sub.Creator) } - if sub.Treasury != "" { - _, err = sdk.AccAddressFromBech32(sub.Treasury) - if err != nil { - return fmt.Errorf("invalid treasury address: %s", sub.Treasury) - } - } - if sub.CreationTime.IsZero() { return fmt.Errorf("invalid subspace creation time: %s", sub.CreationTime) } diff --git a/x/subspaces/types/subspace_test.go b/x/subspaces/types/subspace_test.go index a9cfcf1eb8..118632cce3 100644 --- a/x/subspaces/types/subspace_test.go +++ b/x/subspaces/types/subspace_test.go @@ -1,237 +1,194 @@ package types_test -// -//import ( -// "fmt" -// "testing" -// "time" -// -// types2 "github.com/desmos-labs/desmos/v2/x/subspaces/types" -// -// "github.com/stretchr/testify/require" -//) -// -//func TestSubspace_WithName(t *testing.T) { -// sub := types2.NewSubspace( -// "123", -// "name", -// "", -// "", -// types2.SubspaceTypeOpen, -// time.Unix(1, 2), -// ).WithName("sub") -// require.Equal(t, "sub", sub.Name) -//} -// -//func TestSubspace_WithOwner(t *testing.T) { -// sub := types2.NewSubspace( -// "123", -// "name", -// "", -// "", -// types2.SubspaceTypeOpen, -// time.Unix(1, 2), -// ).WithOwner("owner") -// require.Equal(t, "owner", sub.Owner) -//} -// -//func TestSubspace_WithSubspaceType(t *testing.T) { -// sub := types2.NewSubspace( -// "123", -// "name", -// "", -// "", -// types2.SubspaceTypeOpen, -// time.Unix(1, 2), -// ).WithSubspaceType(types2.SubspaceTypeClosed) -// require.Equal(t, types2.SubspaceTypeClosed, sub.Type) -//} -// -//func TestSubspace_Validate(t *testing.T) { -// date := time.Date(2050, 01, 01, 15, 15, 00, 000, time.UTC) -// tests := []struct { -// name string -// subspace types2.Subspace -// expError bool -// }{ -// { -// name: "Invalid ID returns error", -// subspace: types2.NewSubspace( -// "123", -// "", -// "", -// "", -// types2.SubspaceTypeOpen, -// time.Time{}, -// ), -// expError: true, -// }, -// { -// name: "Invalid name returns error", -// subspace: types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "", -// "", -// "", -// types2.SubspaceTypeOpen, -// time.Time{}, -// ), -// expError: true, -// }, -// { -// name: "Invalid owner returns error", -// subspace: types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "", -// "", -// types2.SubspaceTypeOpen, -// time.Time{}, -// ), -// expError: true, -// }, -// { -// name: "Invalid creator returns error", -// subspace: types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// "", -// types2.SubspaceTypeOpen, -// time.Time{}, -// ), -// expError: true, -// }, -// { -// name: "Invalid creation time returns error", -// subspace: types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// types2.SubspaceTypeOpen, -// time.Time{}, -// ), -// expError: true, -// }, -// { -// name: "Valid subspace returns no error", -// subspace: types2.NewSubspace( -// "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", -// "test", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", -// types2.SubspaceTypeOpen, -// date, -// ), -// expError: false, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// err := test.subspace.Validate() -// if test.expError { -// require.Error(t, err) -// } else { -// require.NoError(t, err) -// } -// }) -// } -//} -// -//func Test_IsValidSubspaceType(t *testing.T) { -// tests := []struct { -// name string -// subType types2.SubspaceType -// expValid bool -// }{ -// { -// name: "valid open type returns true", -// subType: types2.SubspaceTypeOpen, -// expValid: true, -// }, -// { -// name: "valid close type returns true", -// subType: types2.SubspaceTypeClosed, -// expValid: true, -// }, -// { -// name: "invalid type returns false", -// subType: types2.SubspaceTypeUnspecified, -// expValid: false, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// require.Equal(t, test.expValid, types2.IsValidSubspaceType(test.subType)) -// }) -// } -//} -// -//func Test_NormalizeSubspaceType(t *testing.T) { -// tests := []struct { -// name string -// subType string -// expSubType string -// }{ -// { -// name: "Valid Open subspace Type", -// subType: "open", -// expSubType: types2.SubspaceTypeOpen.String(), -// }, -// { -// name: "Valid Close subspace type", -// subType: "Close", -// expSubType: types2.SubspaceTypeClosed.String(), -// }, -// { -// name: "Invalid subspace type", -// subType: "Invalid", -// expSubType: "Invalid", -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// -// subspaceType := types2.NormalizeSubspaceType(test.subType) -// require.Equal(t, test.expSubType, subspaceType) -// }) -// } -//} -// -//func Test_SubspaceTypeFromString(t *testing.T) { -// tests := []struct { -// name string -// subType string -// expSubType types2.SubspaceType -// expError error -// }{ -// { -// name: "Invalid subspace type", -// subType: "invalid", -// expSubType: types2.SubspaceTypeUnspecified, -// expError: fmt.Errorf("'invalid' is not a valid subspace type"), -// }, -// { -// name: "Valid subspace type", -// subType: types2.SubspaceTypeOpen.String(), -// expSubType: types2.SubspaceTypeOpen, -// expError: nil, -// }, -// } -// -// for _, test := range tests { -// test := test -// t.Run(test.name, func(t *testing.T) { -// res, err := types2.SubspaceTypeFromString(test.subType) -// require.Equal(t, test.expError, err) -// require.Equal(t, test.expSubType, res) -// }) -// } -//} +import ( + "testing" + "time" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" + + "github.com/stretchr/testify/require" +) + +func TestSubspace_Validate(t *testing.T) { + testCases := []struct { + name string + subspace types.Subspace + shouldErr bool + }{ + { + name: "invalid id returns error", + subspace: types.NewSubspace( + 0, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + shouldErr: true, + }, + { + name: "invalid name returns error", + subspace: types.NewSubspace( + 1, + "", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + shouldErr: true, + }, + { + name: "invalid treasury returns error", + subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsx", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + shouldErr: true, + }, + { + name: "invalid owner returns error", + subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + shouldErr: true, + }, + { + name: "invalid creator returns error", + subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zw", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + shouldErr: true, + }, + { + name: "invalid creation time returns error", + subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Time{}, + ), + shouldErr: true, + }, + { + name: "valid subspace returns no error", + subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + shouldErr: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.subspace.Validate() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestSubspace_Update(t *testing.T) { + testCases := []struct { + name string + subspace types.Subspace + update *types.SubspaceUpdate + expResult types.Subspace + }{ + { + name: "nothing is updated when using DoNotModify", + subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + update: types.NewSubspaceUpdate( + types.DoNotModify, + types.DoNotModify, + types.DoNotModify, + types.DoNotModify, + ), + expResult: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + { + name: "each field is updated when edited", + subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + update: types.NewSubspaceUpdate( + "New subspace name", + "New subspace description", + "cosmos1l6rkljkrh5g0vyeh9m8tsl4cy626shunv6ksz7", + "cosmos10ya9y35qkf4puaklx5fs07sxfxqncx9usgsnz6", + ), + expResult: types.NewSubspace( + 1, + "New subspace name", + "New subspace description", + "cosmos1l6rkljkrh5g0vyeh9m8tsl4cy626shunv6ksz7", + "cosmos10ya9y35qkf4puaklx5fs07sxfxqncx9usgsnz6", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + result := tc.subspace.Update(tc.update) + require.Equal(t, tc.expResult, result) + }) + } +} From 735a1fd122166e91e69210a14aa8153897f54e75 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Fri, 21 Jan 2022 14:18:56 +0100 Subject: [PATCH 09/47] added the CLI tests Signed-off-by: Riccardo Montagnin --- app/app.go | 18 +- x/subspaces/client/cli/cli_test.go | 642 +++++++++++++++++++++++++++++ x/subspaces/client/cli/query.go | 192 +++++++++ x/subspaces/client/cli/tx.go | 383 +++++++++++++++++ x/subspaces/keeper/common_test.go | 2 +- x/subspaces/keeper/keeper.go | 2 +- x/subspaces/module.go | 14 +- x/subspaces/types/permissions.go | 23 ++ 8 files changed, 1263 insertions(+), 13 deletions(-) create mode 100644 x/subspaces/client/cli/cli_test.go create mode 100644 x/subspaces/client/cli/query.go create mode 100644 x/subspaces/client/cli/tx.go diff --git a/app/app.go b/app/app.go index bc508d1fec..cab05e543f 100644 --- a/app/app.go +++ b/app/app.go @@ -8,6 +8,8 @@ import ( "path/filepath" "strings" + "github.com/desmos-labs/desmos/v2/x/subspaces" + "github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/x/auth/vesting" @@ -84,6 +86,8 @@ import ( "github.com/desmos-labs/desmos/v2/x/profiles" profileskeeper "github.com/desmos-labs/desmos/v2/x/profiles/keeper" profilestypes "github.com/desmos-labs/desmos/v2/x/profiles/types" + subspaceskeeper "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + subspacestypes "github.com/desmos-labs/desmos/v2/x/subspaces/types" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" @@ -209,6 +213,7 @@ var ( // Custom modules profiles.AppModuleBasic{}, + subspaces.AppModuleBasic{}, ) // Module account permissions @@ -268,7 +273,8 @@ type DesmosApp struct { ScopedWasmKeeper capabilitykeeper.ScopedKeeper // Custom modules - ProfileKeeper profileskeeper.Keeper + ProfileKeeper profileskeeper.Keeper + SubspacesKeeper subspaceskeeper.Keeper // Module Manager mm *module.Manager @@ -315,7 +321,7 @@ func NewDesmosApp( authzkeeper.StoreKey, wasm.StoreKey, // Custom modules - profilestypes.StoreKey, + profilestypes.StoreKey, subspacestypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -417,6 +423,9 @@ func NewDesmosApp( ) profilesModule := profiles.NewAppModule(appCodec, legacyAmino, app.ProfileKeeper, app.AccountKeeper, app.BankKeeper) + // Create subspaces keeper + app.SubspacesKeeper = subspaceskeeper.NewKeeper(app.appCodec, keys[subspacestypes.StoreKey]) + // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule) @@ -514,6 +523,7 @@ func NewDesmosApp( // Custom modules profilesModule, + subspaces.NewAppModule(appCodec, app.SubspacesKeeper, app.AccountKeeper, app.BankKeeper), ) // During begin block slashing happens after distr.BeginBlocker so that @@ -524,6 +534,7 @@ func NewDesmosApp( app.mm.SetOrderBeginBlockers( upgradetypes.ModuleName, capabilitytypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName, evidencetypes.ModuleName, stakingtypes.ModuleName, ibchost.ModuleName, + // TODO: See if we need a BeginBlocker for the subspaces module ) app.mm.SetOrderEndBlockers(crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName) @@ -540,7 +551,7 @@ func NewDesmosApp( feegrant.ModuleName, wasm.ModuleName, // Custom modules - profilestypes.ModuleName, + profilestypes.ModuleName, subspacestypes.ModuleName, crisistypes.ModuleName, ) @@ -576,6 +587,7 @@ func NewDesmosApp( // Custom modules profiles.NewAppModule(app.appCodec, legacyAmino, app.ProfileKeeper, app.AccountKeeper, app.BankKeeper), + // TODO: Add the subspaces module here ) app.sm.RegisterStoreDecoders() diff --git a/x/subspaces/client/cli/cli_test.go b/x/subspaces/client/cli/cli_test.go new file mode 100644 index 0000000000..175e24e1f1 --- /dev/null +++ b/x/subspaces/client/cli/cli_test.go @@ -0,0 +1,642 @@ +package cli_test + +import ( + "fmt" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/gogo/protobuf/proto" + + "github.com/desmos-labs/desmos/v2/x/subspaces/client/cli" + + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/cosmos/cosmos-sdk/testutil/network" + "github.com/stretchr/testify/suite" + tmcli "github.com/tendermint/tendermint/libs/cli" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/desmos-labs/desmos/v2/testutil" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +func TestIntegrationTestSuite(t *testing.T) { + suite.Run(t, new(IntegrationTestSuite)) +} + +type IntegrationTestSuite struct { + suite.Suite + + cfg network.Config + network *network.Network +} + +func (s *IntegrationTestSuite) SetupSuite() { + s.T().Log("setting up integration test suite") + + cfg := testutil.DefaultConfig() + genesisState := cfg.GenesisState + cfg.NumValidators = 2 + + // Initialize the module genesis data + var subspacesData types.GenesisState + s.Require().NoError(cfg.Codec.UnmarshalJSON(genesisState[types.ModuleName], &subspacesData)) + + subspacesData.Subspaces = []types.Subspace{ + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + } + subspacesData.ACL = []types.ACLEntry{ + types.NewACLEntry(1, "group", types.PermissionWrite), + types.NewACLEntry(2, "another-group", types.PermissionManageGroups), + } + subspacesData.UserGroups = []types.UserGroup{ + types.NewUserGroup(1, "group", []string{ + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + }), + types.NewUserGroup(2, "another-group", []string{ + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + }), + types.NewUserGroup(2, "third-group", nil), + } + + // Store the genesis data + subspacesDataBz, err := cfg.Codec.MarshalJSON(&subspacesData) + s.Require().NoError(err) + genesisState[types.ModuleName] = subspacesDataBz + cfg.GenesisState = genesisState + + s.cfg = cfg + s.network = network.New(s.T(), cfg) + + _, err = s.network.WaitForHeight(1) + s.Require().NoError(err) +} + +func (s *IntegrationTestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() +} + +// -------------------------------------------------------------------------------------------------------------------- + +func (s *IntegrationTestSuite) TestCmdQuerySubspace() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + expResponse types.QuerySubspaceResponse + }{ + { + name: "non existing subspace returns error", + args: []string{ + "10", + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + shouldErr: true, + }, + { + name: "existing subspace is returned correctly", + args: []string{ + "1", + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + shouldErr: false, + expResponse: types.QuerySubspaceResponse{ + Subspace: types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + cmd := cli.GetCmdQuerySubspace() + clientCtx := val.ClientCtx + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + + var response types.QuerySubspaceResponse + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), &response), out.String()) + s.Require().Equal(response.Subspace, tc.expResponse.Subspace) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdQuerySubspaces() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + expResponse types.QuerySubspacesResponse + }{ + { + name: "subspaces are returned correctly", + args: []string{ + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + shouldErr: false, + expResponse: types.QuerySubspacesResponse{ + Subspaces: []types.Subspace{ + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + }, + }, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + cmd := cli.GetCmdQuerySubspaces() + clientCtx := val.ClientCtx + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + + var response types.QuerySubspacesResponse + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), &response), out.String()) + s.Require().Equal(tc.expResponse.Subspaces, response.Subspaces) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdQueryUserGroups() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + expResponse types.QueryUserGroupsResponse + }{ + { + name: "subspaces are returned correctly", + args: []string{ + "2", + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + shouldErr: false, + expResponse: types.QueryUserGroupsResponse{ + Groups: []string{"another-group", "third-group"}, + }, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + cmd := cli.GetCmdQueryUserGroups() + clientCtx := val.ClientCtx + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + + var response types.QueryUserGroupsResponse + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), &response), out.String()) + s.Require().Equal(tc.expResponse.Groups, response.Groups) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdCreateSubspace() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + expErr bool + respType proto.Message + }{ + { + name: "invalid name returns error", + args: []string{ + "", + }, + expErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "Test subspace", + fmt.Sprintf("--%s=%s", cli.FlagDescription, "This is a test subspace"), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + expErr: false, + respType: &sdk.TxResponse{}, + }, + { + name: "valid data returns no error with custom treasury and owner", + args: []string{ + "Another test subspace", + fmt.Sprintf("--%s=%s", cli.FlagDescription, "Another test subspace"), + fmt.Sprintf("--%s=%s", cli.FlagTreasury, "cosmos1lqjd4p6uxvsvus6kf3gf00uz7luj4jcxpyahul"), + fmt.Sprintf("--%s=%s", cli.FlagOwner, "cosmos1et50whs236j9dacacz7feh05jjum9jk04cdt9u"), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + expErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdCreateSubspace() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.expErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdEditSubspace() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + respType proto.Message + }{ + { + name: "invalid subspace id returns error", + args: []string{"subspace"}, + shouldErr: true, + }, + { + name: "invalid name returns error", + args: []string{ + "1", + fmt.Sprintf("--%s=%s", cli.FlagName, ""), + }, + shouldErr: true, + }, + { + name: "invalid owner flag returns error", + args: []string{ + "1", + fmt.Sprintf("--%s=%s", cli.FlagOwner, "abd"), + }, + shouldErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "1", + fmt.Sprintf("--%s=%s", cli.FlagName, "Edited name"), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + shouldErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdEditSubspace() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdCreateUserGroup() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + respType proto.Message + }{ + { + name: "invalid subspace id returns error", + args: []string{"id", "testing-group"}, + shouldErr: true, + }, + { + name: "invalid name returns error", + args: []string{"1", ""}, + shouldErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "2", "testing-group", + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + shouldErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdCreateUserGroup() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdDeleteUserGroup() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + respType proto.Message + }{ + { + name: "invalid subspace id returns error", + args: []string{"subspace-id", "testing-group"}, + shouldErr: true, + }, + { + name: "invalid name returns error", + args: []string{"1", ""}, + shouldErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "2", "testing-group", + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + shouldErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdDeleteUserGroup() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdAddUserToUserGroup() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + respType proto.Message + }{ + { + name: "invalid subspace id returns error", + args: []string{"subspace-id", "testing-group"}, + shouldErr: true, + }, + { + name: "invalid name returns error", + args: []string{"1", ""}, + shouldErr: true, + }, + { + name: "invalid user returns error", + args: []string{"1", "group", ""}, + shouldErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "2", "testing-group", "cosmos1et50whs236j9dacacz7feh05jjum9jk04cdt9u", + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + shouldErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdAddUserToUserGroup() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdRemoveUserFromUserGroup() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + respType proto.Message + }{ + { + name: "invalid subspace id returns error", + args: []string{"subspace-id", "testing-group"}, + shouldErr: true, + }, + { + name: "invalid name returns error", + args: []string{"1", ""}, + shouldErr: true, + }, + { + name: "invalid user returns error", + args: []string{"1", "group", ""}, + shouldErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "2", "testing-group", "cosmos1et50whs236j9dacacz7feh05jjum9jk04cdt9u", + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + shouldErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdRemoveUserFromUserGroup() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdSetPermissions() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + respType proto.Message + }{ + { + name: "invalid subspace id returns error", + args: []string{"id", "group", "Write"}, + shouldErr: true, + }, + { + name: "invalid target returns error", + args: []string{"1", "", "Write"}, + shouldErr: true, + }, + { + name: "invalid permission returns error", + args: []string{"1", "group", "NonExistingPermission"}, + shouldErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "1", "group", "Write", + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + shouldErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdSetPermissions() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} diff --git a/x/subspaces/client/cli/query.go b/x/subspaces/client/cli/query.go new file mode 100644 index 0000000000..529f4fbc63 --- /dev/null +++ b/x/subspaces/client/cli/query.go @@ -0,0 +1,192 @@ +package cli + +import ( + "context" + "fmt" + "strconv" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/version" + "github.com/spf13/cobra" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// DONTCOVER + +// GetQueryCmd returns the command allowing to perform queries +func GetQueryCmd() *cobra.Command { + subspaceQueryCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Querying commands for the subspaces module", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + subspaceQueryCmd.AddCommand( + GetCmdQuerySubspace(), + GetCmdQuerySubspaces(), + GetCmdQueryUserGroups(), + GetCmdQueryUserGroupMembers(), + ) + return subspaceQueryCmd +} + +// GetCmdQuerySubspace returns the command to query the subspace with the given id +func GetCmdQuerySubspace() *cobra.Command { + cmd := &cobra.Command{ + Use: "subspace [id]", + Short: "Query the subspace with the given id", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + subspaceID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid subspace id: %s", err) + } + + res, err := queryClient.Subspace(context.Background(), types.NewQuerySubspaceRequest(subspaceID)) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +// GetCmdQuerySubspaces returns the command to query all the subspaces +func GetCmdQuerySubspaces() *cobra.Command { + cmd := &cobra.Command{ + Use: "subspaces", + Short: "Query subspaces with optional pagination", + Example: fmt.Sprintf(` +%s query subspaces subspaces --page=2 --limit=100`, + version.AppName), + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + res, err := queryClient.Subspaces(context.Background(), types.NewQuerySubspacesRequest(pageReq)) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "subspaces") + + return cmd +} + +// GetCmdQueryUserGroups returns the command to query the user groups of a subspace +func GetCmdQueryUserGroups() *cobra.Command { + cmd := &cobra.Command{ + Use: "user-groups [subspace-id]", + Short: "Query subspaces with optional pagination", + Example: fmt.Sprintf(` +%s query subspaces user-groups 1 --page=2 --limit=100`, + version.AppName), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + subspaceID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid subspace id: %s", err) + } + + res, err := queryClient.UserGroups( + context.Background(), + types.NewQueryUserGroupsRequest(subspaceID, pageReq), + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "user groups") + + return cmd +} + +// GetCmdQueryUserGroupMembers returns the command to query the members of a specific user group +func GetCmdQueryUserGroupMembers() *cobra.Command { + cmd := &cobra.Command{ + Use: "user-group-members [subspace-id] [group-name]", + Short: "Query subspaces with optional pagination", + Example: fmt.Sprintf(` +%s query subspaces user-group-members 1 "Admins" --page=2 --limit=100`, + version.AppName), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + subspaceID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid subspace id: %s", err) + } + + groupName := args[1] + + res, err := queryClient.UserGroupMembers( + context.Background(), + types.NewQueryUserGroupMembersRequest(subspaceID, groupName, pageReq), + ) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + flags.AddPaginationFlagsToCmd(cmd, "user group members") + + return cmd +} diff --git a/x/subspaces/client/cli/tx.go b/x/subspaces/client/cli/tx.go new file mode 100644 index 0000000000..b1f9ddf423 --- /dev/null +++ b/x/subspaces/client/cli/tx.go @@ -0,0 +1,383 @@ +package cli + +import ( + "fmt" + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/cosmos/cosmos-sdk/version" + "github.com/spf13/cobra" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// DONTCOVER + +const ( + FlagName = "name" + FlagDescription = "description" + FlagTreasury = "treasury" + FlagOwner = "owner" +) + +// NewTxCmd returns a new command to perform subspaces transactions +func NewTxCmd() *cobra.Command { + subspacesTxCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Subspaces transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + subspacesTxCmd.AddCommand( + GetCmdCreateSubspace(), + GetCmdEditSubspace(), + GetCmdCreateUserGroup(), + GetCmdDeleteUserGroup(), + GetCmdAddUserToUserGroup(), + GetCmdRemoveUserFromUserGroup(), + GetCmdSetPermissions(), + ) + + return subspacesTxCmd +} + +// GetCmdCreateSubspace returns the command used to create a subspace +func GetCmdCreateSubspace() *cobra.Command { + cmd := &cobra.Command{ + Use: "create [name]", + Args: cobra.ExactArgs(1), + Short: "Create a new subspace", + Long: `Create a new subspace. +The name must be a human readable name.`, + Example: fmt.Sprintf(` +%s tx subspaces create "Desmos" \ + --description "The official subspace of Desmos" \ + --treasury desmos1jqk5p244yl4ktukq5xhavvlfzl8z4we4qfmuyh \ + --owner desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ + --from alice +`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + name := args[0] + + description, err := cmd.Flags().GetString(FlagDescription) + if err != nil { + return err + } + + treasury, err := cmd.Flags().GetString(FlagTreasury) + if err != nil { + return err + } + + owner, err := cmd.Flags().GetString(FlagOwner) + if err != nil { + return err + } + + msg := types.NewMsgCreateSubspace(name, description, treasury, owner, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().String(FlagDescription, "", "Description of the subspace") + cmd.Flags().String(FlagTreasury, "", "Treasury of the subspace") + cmd.Flags().String(FlagOwner, "", "Owner of the subspace") + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdEditSubspace returns the command to edit a subspace +func GetCmdEditSubspace() *cobra.Command { + cmd := &cobra.Command{ + Use: "edit [subspace-id]", + Args: cobra.ExactArgs(1), + Short: "Edit the subspace with the given id", + Example: fmt.Sprintf(` +%s tx subspaces edit 1 \ + --name "Desmos - Democratizing social networks" + --description "The official subspace of Desmos" \ + --treasury desmos1jqk5p244yl4ktukq5xhavvlfzl8z4we4qfmuyh \ + --owner desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ + --from alice +`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + subspaceID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid subspace id: %s", err) + } + + name, err := cmd.Flags().GetString(FlagName) + if err != nil { + return err + } + + description, err := cmd.Flags().GetString(FlagDescription) + if err != nil { + return err + } + + treasury, err := cmd.Flags().GetString(FlagTreasury) + if err != nil { + return err + } + + owner, err := cmd.Flags().GetString(FlagOwner) + if err != nil { + return err + } + + msg := types.NewMsgEditSubspace(subspaceID, name, description, treasury, owner, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().String(FlagName, types.DoNotModify, "New human readable name of the subspace") + cmd.Flags().String(FlagDescription, types.DoNotModify, "Description of the subspace") + cmd.Flags().String(FlagTreasury, types.DoNotModify, "Treasury of the subspace") + cmd.Flags().String(FlagOwner, types.DoNotModify, "Owner of the subspace") + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdCreateUserGroup returns the command to create a user group +func GetCmdCreateUserGroup() *cobra.Command { + cmd := &cobra.Command{ + Use: "create-user-group [subspace-id] [group-name] [[permissions]]", + Args: cobra.MinimumNArgs(2), + Short: "Create a new user group within a subspace", + Long: fmt.Sprintf(`Create a new user group within the subspace having the provided id. +The permissions this group can be set using the third (optional) parameter. +If no permissions are set, the default PermissionNothing will be used instead. +Multiple permissions must be specified separating them with a comma (,).`), + Example: fmt.Sprintf(` +%s tx subspaces create-user-group 1 "Admins" "Write,ModerateContent,SetPermissions" \ + --from alice +`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + subspaceID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid subspace id: %s", err) + } + + name := args[1] + + permission := types.PermissionNothing + if len(args) > 2 { + for _, permArg := range strings.Split(args[2], ",") { + perm, err := types.ParsePermission(permArg) + if err != nil { + return err + } + permission = types.CombinePermissions(permission, perm) + } + } + + msg := types.NewMsgCreateUserGroup(subspaceID, name, permission, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdDeleteUserGroup returns the command to delete a user group +func GetCmdDeleteUserGroup() *cobra.Command { + cmd := &cobra.Command{ + Use: "delete-user-group [subspace-id] [group-name]", + Args: cobra.ExactArgs(2), + Short: "Delete a user group from a subspace", + Example: fmt.Sprintf(` +%s tx subspaces delete-user-group 1 "Admins" --from alice +`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + subspaceID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid subspace id: %s", err) + } + + name := args[1] + + msg := types.NewMsgDeleteUserGroup(subspaceID, name, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdAddUserToUserGroup returns the command to add a user to a user group +func GetCmdAddUserToUserGroup() *cobra.Command { + cmd := &cobra.Command{ + Use: "add-user-to-group [subspace-id] [group-name] [user]", + Args: cobra.ExactArgs(3), + Short: "Add a user to a user group", + Example: fmt.Sprintf(` +%s tx subspaces add-user-to-user-group 1 "Admins" desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ + --from alice +`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + subspaceID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid subspace id: %s", err) + } + + name := args[1] + user := args[2] + + msg := types.NewMsgAddUserToUserGroup(subspaceID, name, user, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdRemoveUserFromUserGroup returns the command to remove a user from a user group +func GetCmdRemoveUserFromUserGroup() *cobra.Command { + cmd := &cobra.Command{ + Use: "remove-user-from-group [subspace-id] [group-name] [user]", + Args: cobra.ExactArgs(3), + Short: "Remove a user from a user group", + Example: fmt.Sprintf(` +%s tx subspaces remove-user-from-user-group 1 "Admins" desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ + --from alice +`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + subspaceID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid subspace id: %s", err) + } + + name := args[1] + user := args[2] + + msg := types.NewMsgRemoveUserFromUserGroup(subspaceID, name, user, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdSetPermissions returns the command to set the permissions for a target +func GetCmdSetPermissions() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-permissions [subspace-id] [target] [permissions]", + Args: cobra.MinimumNArgs(3), + Short: "Set the permissions for a specific target", + Long: `Set the permissions for a specific target inside a given subspace. +The target can be either a group (in this case the name should be used), +or a user (in this case the address should be used). + +In both cases, it is mandatory to specify at least one permission to be set. +When specifying multiple permissions, they must be separated by a comma (,).`, + Example: fmt.Sprintf(` +%s tx subspaces set-permissions 1 "Admins" "Write,ModerateContent,SetPermissions" \ + --from alice +`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + subspaceID, err := strconv.ParseUint(args[0], 10, 64) + if err != nil { + return fmt.Errorf("invalid subspace id: %s", err) + } + + target := args[1] + + permission := types.PermissionNothing + for _, arg := range strings.Split(args[2], ",") { + perm, err := types.ParsePermission(arg) + if err != nil { + return err + } + permission = types.CombinePermissions(permission, perm) + } + + msg := types.NewMsgSetPermissions(subspaceID, target, permission, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/subspaces/keeper/common_test.go b/x/subspaces/keeper/common_test.go index 8bff55144e..aadb4fc4a0 100644 --- a/x/subspaces/keeper/common_test.go +++ b/x/subspaces/keeper/common_test.go @@ -51,7 +51,7 @@ func (suite *KeeperTestsuite) SetupTest() { suite.cdc, suite.legacyAminoCdc = app.MakeCodecs() // Define keeper - suite.k = keeper.NewKeeper(suite.storeKey, suite.cdc) + suite.k = keeper.NewKeeper(suite.cdc, suite.storeKey) } func TestKeeperTestSuite(t *testing.T) { diff --git a/x/subspaces/keeper/keeper.go b/x/subspaces/keeper/keeper.go index 3c73377256..0f5c1b369f 100644 --- a/x/subspaces/keeper/keeper.go +++ b/x/subspaces/keeper/keeper.go @@ -14,7 +14,7 @@ type Keeper struct { } // NewKeeper creates new instances of the subspaces keeper -func NewKeeper(storeKey sdk.StoreKey, cdc codec.BinaryCodec) Keeper { +func NewKeeper(cdc codec.BinaryCodec, storeKey sdk.StoreKey) Keeper { return Keeper{ storeKey: storeKey, cdc: cdc, diff --git a/x/subspaces/module.go b/x/subspaces/module.go index 5ad862f845..41e7d24277 100644 --- a/x/subspaces/module.go +++ b/x/subspaces/module.go @@ -6,6 +6,8 @@ import ( "fmt" "math/rand" + "github.com/desmos-labs/desmos/v2/x/subspaces/client/cli" + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" "github.com/desmos-labs/desmos/v2/x/subspaces/types" @@ -69,16 +71,12 @@ func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *r // GetTxCmd returns the root tx command for the subspaces module. func (AppModuleBasic) GetTxCmd() *cobra.Command { - // TODO - //return cli.NewTxCmd() - return nil + return cli.NewTxCmd() } // GetQueryCmd returns the root query command for the subspaces module. func (AppModuleBasic) GetQueryCmd() *cobra.Command { - // TODO - //return cli.GetQueryCmd() - return nil + return cli.GetQueryCmd() } // RegisterInterfaces registers interfaces and implementations of the subspaces module. @@ -140,7 +138,7 @@ func (am AppModule) QuerierRoute() string { } // LegacyQuerierHandler returns the subspaces module sdk.Querier. -func (am AppModule) LegacyQuerierHandler(legacyQuerierCdc *codec.LegacyAmino) sdk.Querier { +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { return nil } @@ -192,7 +190,7 @@ func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedP } // RandomizedParams creates randomized subspaces param changes for the simulator. -func (AppModule) RandomizedParams(r *rand.Rand) []simtypes.ParamChange { +func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { return nil } diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go index 654645b738..039a90ec0d 100644 --- a/x/subspaces/types/permissions.go +++ b/x/subspaces/types/permissions.go @@ -2,6 +2,8 @@ package types import ( "encoding/binary" + "fmt" + "strings" ) // Permission represents a permission that can be set to a user or user group @@ -32,6 +34,27 @@ const ( PermissionEverything = Permission(0b111111) ) +// ParsePermission parses the given permission string as a single Permissions instance +func ParsePermission(permission string) (Permission, error) { + if strings.EqualFold(permission, "nothing") { + return PermissionNothing, nil + } else if strings.EqualFold(permission, "Write") { + return PermissionWrite, nil + } else if strings.EqualFold(permission, "ModerateContent") { + return PermissionModerateContent, nil + } else if strings.EqualFold(permission, "ChangeInfo") { + return PermissionChangeInfo, nil + } else if strings.EqualFold(permission, "ManageGroups") { + return PermissionManageGroups, nil + } else if strings.EqualFold(permission, "SetPermissions") { + return PermissionSetPermissions, nil + } else if strings.EqualFold(permission, "Everything") { + return PermissionEverything, nil + } + + return 0, fmt.Errorf("invalid permission value: %s", permission) +} + // MarshalPermission marshals the given permission to a byte array func MarshalPermission(permission Permission) (permissionBytes []byte) { permissionBytes = make([]byte, 4) From a4d22bd1eca42b7005b0e72db2ea75cc6b00ff6d Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 24 Jan 2022 12:11:04 +0100 Subject: [PATCH 10/47] added the integration tests Signed-off-by: Riccardo Montagnin --- app/params/weights.go | 24 +- x/subspaces/client/cli/tx.go | 4 +- x/subspaces/keeper/alias_functions.go | 20 ++ x/subspaces/keeper/genesis.go | 2 +- x/subspaces/keeper/genesis_test.go | 10 +- x/subspaces/keeper/permissions.go | 32 ++ x/subspaces/module.go | 16 +- x/subspaces/simulation/decoder.go | 46 +++ x/subspaces/simulation/decoder_test.go | 90 ++++++ x/subspaces/simulation/genesis.go | 179 ++++++++++++ x/subspaces/simulation/operations.go | 117 ++++++++ x/subspaces/simulation/operations_groups.go | 276 ++++++++++++++++++ .../simulation/operations_permissions.go | 87 ++++++ .../simulation/operations_subspaces.go | 150 ++++++++++ x/subspaces/simulation/utils.go | 102 +++++++ x/subspaces/types/genesis.go | 4 +- x/subspaces/types/genesis_test.go | 16 +- x/subspaces/types/permissions.go | 21 +- x/subspaces/types/permissions_test.go | 4 +- 19 files changed, 1147 insertions(+), 53 deletions(-) create mode 100644 x/subspaces/simulation/decoder.go create mode 100644 x/subspaces/simulation/decoder_test.go create mode 100644 x/subspaces/simulation/genesis.go create mode 100644 x/subspaces/simulation/operations.go create mode 100644 x/subspaces/simulation/operations_groups.go create mode 100644 x/subspaces/simulation/operations_permissions.go create mode 100644 x/subspaces/simulation/operations_subspaces.go create mode 100644 x/subspaces/simulation/utils.go diff --git a/app/params/weights.go b/app/params/weights.go index adcd8cf183..ba458e51e1 100644 --- a/app/params/weights.go +++ b/app/params/weights.go @@ -2,13 +2,6 @@ package params // Default simulation operation weights for messages const ( - DefaultWeightMsgCreatePost int = 100 - DefaultWeightMsgEditPost int = 75 - DefaultWeightMsgAddReaction int = 80 - DefaultWeightMsgRemoveReaction int = 40 - DefaultWeightMsgAnswerPoll int = 20 - DefaultWeightMsgRegisterReaction int = 50 - DefaultWeightMsgSaveProfile int = 80 DefaultWeightMsgDeleteProfile int = 20 DefaultWeightMsgRequestDTagTransfer int = 85 @@ -21,14 +14,11 @@ const ( DefaultWeightMsgBlockUser int = 50 DefaultWeightMsgUnblockUser int = 50 - DefaultWeightMsgReportPost int = 50 - - DefaultWeightMsgCreateSubspace int = 100 - DefaultWeightMsgEditSubspace int = 75 - DefaultWeightMsgAddAmin int = 40 - DefaultWeightMsgRemoveAdmin int = 40 - DefaultWeightMsgRegisterUser int = 60 - DefaultWeightMsgUnregisterUser int = 50 - DefaultWeightMsgBanUser int = 30 - DefaultWeightMsgUnbanUser int = 20 + DefaultWeightMsgCreateSubspace int = 80 + DefaultWeightMsgEditSubspace int = 30 + DefaultWeightMsgCreateUserGroup int = 10 + DefaultWeightMsgDeleteUserGroup int = 5 + DefaultWeightMsgAddUserToUserGroup int = 7 + DefaultWeightMsgRemoveUserFromUserGroup int = 3 + DefaultWeightMsgSetPermissions int = 85 ) diff --git a/x/subspaces/client/cli/tx.go b/x/subspaces/client/cli/tx.go index b1f9ddf423..efc91535a3 100644 --- a/x/subspaces/client/cli/tx.go +++ b/x/subspaces/client/cli/tx.go @@ -172,10 +172,10 @@ func GetCmdCreateUserGroup() *cobra.Command { Use: "create-user-group [subspace-id] [group-name] [[permissions]]", Args: cobra.MinimumNArgs(2), Short: "Create a new user group within a subspace", - Long: fmt.Sprintf(`Create a new user group within the subspace having the provided id. + Long: `Create a new user group within the subspace having the provided id. The permissions this group can be set using the third (optional) parameter. If no permissions are set, the default PermissionNothing will be used instead. -Multiple permissions must be specified separating them with a comma (,).`), +Multiple permissions must be specified separating them with a comma (,).`, Example: fmt.Sprintf(` %s tx subspaces create-user-group 1 "Admins" "Write,ModerateContent,SetPermissions" \ --from alice diff --git a/x/subspaces/keeper/alias_functions.go b/x/subspaces/keeper/alias_functions.go index 7881f5f083..48477d2c47 100644 --- a/x/subspaces/keeper/alias_functions.go +++ b/x/subspaces/keeper/alias_functions.go @@ -58,6 +58,16 @@ func (k Keeper) IterateSubspaceGroups( } } +// GetSubspaceGroups returns the list of all groups present inside a given subspace +func (k Keeper) GetSubspaceGroups(ctx sdk.Context, subspaceID uint64) []string { + var groups []string + k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, groupName string) (stop bool) { + groups = append(groups, groupName) + return false + }) + return groups +} + // IterateGroupMembers iterates over all the members of the group with the given name present inside the given subspace func (k Keeper) IterateGroupMembers( ctx sdk.Context, subspaceID uint64, groupName string, fn func(index int64, member sdk.AccAddress) (stop bool), @@ -79,6 +89,16 @@ func (k Keeper) IterateGroupMembers( } } +// GetGroupMembers iterates returns all the members of a group inside a specific subspace +func (k Keeper) GetGroupMembers(ctx sdk.Context, subspaceID uint64, groupName string) []sdk.AccAddress { + var members []sdk.AccAddress + k.IterateGroupMembers(ctx, subspaceID, groupName, func(index int64, member sdk.AccAddress) (stop bool) { + members = append(members, member) + return false + }) + return members +} + // -------------------------------------------------------------------------------------------------------------------- // IteratePermissions iterates over all the permissions set for the subspace with the given id diff --git a/x/subspaces/keeper/genesis.go b/x/subspaces/keeper/genesis.go index 9d9adc059f..3651baa7bf 100644 --- a/x/subspaces/keeper/genesis.go +++ b/x/subspaces/keeper/genesis.go @@ -10,8 +10,8 @@ import ( func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { return types.NewGenesisState( k.GetAllSubspaces(ctx), - k.GetAllPermissions(ctx), k.GetAllUserGroups(ctx), + k.GetAllPermissions(ctx), ) } diff --git a/x/subspaces/keeper/genesis_test.go b/x/subspaces/keeper/genesis_test.go index 29537d0100..f4dae5284d 100644 --- a/x/subspaces/keeper/genesis_test.go +++ b/x/subspaces/keeper/genesis_test.go @@ -108,11 +108,11 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), ), }, + nil, []types.ACLEntry{ types.NewACLEntry(1, "group", types.PermissionWrite), types.NewACLEntry(2, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", types.PermissionSetPermissions), }, - nil, ), }, { @@ -174,10 +174,6 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), ), }, - []types.ACLEntry{ - types.NewACLEntry(1, "group", types.PermissionWrite), - types.NewACLEntry(2, "another-group", types.PermissionManageGroups), - }, []types.UserGroup{ types.NewUserGroup(1, "group", []string{ "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", @@ -187,6 +183,10 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", }), }, + []types.ACLEntry{ + types.NewACLEntry(1, "group", types.PermissionWrite), + types.NewACLEntry(2, "another-group", types.PermissionManageGroups), + }, ), }, } diff --git a/x/subspaces/keeper/permissions.go b/x/subspaces/keeper/permissions.go index 8b49dd264b..6db33bf626 100644 --- a/x/subspaces/keeper/permissions.go +++ b/x/subspaces/keeper/permissions.go @@ -26,6 +26,38 @@ func (k Keeper) GetGroupsInheritedPermissions(ctx sdk.Context, subspaceID uint64 return types.CombinePermissions(permissions...) } +// GetUsersWithPermission returns all the users that have a given permission inside the specified subspace +func (k Keeper) GetUsersWithPermission(ctx sdk.Context, subspaceID uint64, permission types.Permission) ([]sdk.AccAddress, error) { + subspace, found := k.GetSubspace(ctx, subspaceID) + if !found { + return nil, nil + } + + // The owner must always be included as they have all the permissions + ownerAddr, err := sdk.AccAddressFromBech32(subspace.Owner) + if err != nil { + return nil, err + } + + users := []sdk.AccAddress{ownerAddr} + k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, groupName string) (stop bool) { + if !k.HasPermission(ctx, subspaceID, groupName, permission) { + // Return early if the group does not have the permission. We will check other groups anyway + return false + } + + // If the group has the permission, get all the members + k.IterateGroupMembers(ctx, subspaceID, groupName, func(index int64, member sdk.AccAddress) (stop bool) { + users = append(users, member) + return false + }) + + return false + }) + + return users, nil +} + // HasPermission checks whether the specific target has the given permission inside a specific subspace func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, target string, permission types.Permission) bool { // Get the subspace to make sure the request is valid diff --git a/x/subspaces/module.go b/x/subspaces/module.go index 41e7d24277..a1d73ac769 100644 --- a/x/subspaces/module.go +++ b/x/subspaces/module.go @@ -6,6 +6,8 @@ import ( "fmt" "math/rand" + "github.com/desmos-labs/desmos/v2/x/subspaces/simulation" + "github.com/desmos-labs/desmos/v2/x/subspaces/client/cli" "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" @@ -84,7 +86,7 @@ func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) types.RegisterInterfaces(registry) } -//____________________________________________________________________________ +// -------------------------------------------------------------------------------------------------------------------- // AppModule implements an application module for the subspaces module. type AppModule struct { @@ -173,15 +175,14 @@ func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Valid return []abci.ValidatorUpdate{} } -//____________________________________________________________________________ +// -------------------------------------------------------------------------------------------------------------------- // AppModuleSimulation defines the module simulation functions used by the subspaces module. type AppModuleSimulation struct{} // GenerateGenesisState creates a randomized GenState of the bank module. func (AppModule) GenerateGenesisState(simState *module.SimulationState) { - // TODO - //simulation.RandomizeGenState(simState) + simulation.RandomizeGenState(simState) } // ProposalContents doesn't return any content functions for governance proposals. @@ -196,13 +197,10 @@ func (AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { // RegisterStoreDecoder performs a no-op. func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { - // TODO - //sdr[types.ModuleName] = simulation.NewDecodeStore(am.cdc) + sdr[types.ModuleName] = simulation.NewDecodeStore(am.cdc) } // WeightedOperations returns the all the subspaces module operations with their respective weights. func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { - // TODO - //return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keeper, am.ak, am.bk) - return nil + return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keeper, am.ak, am.bk) } diff --git a/x/subspaces/simulation/decoder.go b/x/subspaces/simulation/decoder.go new file mode 100644 index 0000000000..874fa6c309 --- /dev/null +++ b/x/subspaces/simulation/decoder.go @@ -0,0 +1,46 @@ +package simulation + +import ( + "bytes" + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/types/kv" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// NewDecodeStore returns a new decoder that unmarshals the KVPair's Value +// to the corresponding subspaces type +func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string { + return func(kvA, kvB kv.Pair) string { + switch { + case bytes.HasPrefix(kvA.Key, types.SubspaceIDKey): + var idA, idB uint64 + idA = types.GetSubspaceIDFromBytes(kvA.Value) + idB = types.GetSubspaceIDFromBytes(kvB.Value) + return fmt.Sprintf("SubspaceIDA: %d\nSubspaceIDB: %d\n", idA, idB) + + case bytes.HasPrefix(kvA.Key, types.SubspacePrefix): + var subspaceA, subspaceB types.Subspace + cdc.MustUnmarshal(kvA.Value, &subspaceA) + cdc.MustUnmarshal(kvB.Value, &subspaceB) + return fmt.Sprintf("SubspaceA: %s\nSubspaceB: %s\n", subspaceA.String(), subspaceB.String()) + + case bytes.HasPrefix(kvA.Key, types.GroupsPrefix): + return fmt.Sprintf("GroupKeyA: %s\nGroupKeyB: %s\n", kvA.Key, kvB.Key) + + case bytes.HasPrefix(kvA.Key, types.GroupMembersStorePrefix): + return fmt.Sprintf("GroupMemberKeyA: %s\nGroupMemberKeyB: %s\n", kvA.Key, kvB.Key) + + case bytes.HasPrefix(kvA.Key, types.PermissionsStorePrefix): + var permissionA, permissionB uint32 + permissionA = types.UnmarshalPermission(kvA.Value) + permissionB = types.UnmarshalPermission(kvB.Value) + return fmt.Sprintf("PermissionKeyA: %d\nPermissionKeyB: %d\n", permissionA, permissionB) + + default: + panic(fmt.Sprintf("unexpected %s key %X (%s)", types.ModuleName, kvA.Key, kvA.Key)) + } + } +} diff --git a/x/subspaces/simulation/decoder_test.go b/x/subspaces/simulation/decoder_test.go new file mode 100644 index 0000000000..bce18a1b3c --- /dev/null +++ b/x/subspaces/simulation/decoder_test.go @@ -0,0 +1,90 @@ +package simulation_test + +import ( + "fmt" + "testing" + "time" + + "github.com/desmos-labs/desmos/v2/x/subspaces/simulation" + + "github.com/cosmos/cosmos-sdk/types/kv" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/desmos-labs/desmos/v2/app" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +func TestDecodeStore(t *testing.T) { + cdc, _ := app.MakeCodecs() + decoder := simulation.NewDecodeStore(cdc) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos19r59nc7wfgc5gjnu5ga5yztkvr5qssj24krx2f") + require.NoError(t, err) + + subspace := types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ) + kvPairs := kv.Pairs{Pairs: []kv.Pair{ + { + Key: types.SubspaceIDKey, + Value: types.GetSubspaceIDBytes(1), + }, + { + Key: types.SubspaceKey(subspace.ID), + Value: cdc.MustMarshal(&subspace), + }, + { + Key: types.GroupStoreKey(1, "group"), + Value: []byte{0x01}, + }, + { + Key: types.GroupMemberStoreKey(1, "group", sdkAddr), + Value: []byte{0x01}, + }, + { + Key: types.PermissionStoreKey(1, "group"), + Value: types.MarshalPermission(types.PermissionWrite), + }, + { + Key: []byte("Unknown key"), + Value: nil, + }, + }} + + testCases := []struct { + name string + expectedLog string + }{ + {"Subspace ID", fmt.Sprintf("SubspaceIDA: %d\nSubspaceIDB: %d\n", + 1, 1)}, + {"Subspace", fmt.Sprintf("SubspaceA: %s\nSubspaceB: %s\n", + subspace.String(), subspace.String())}, + {"Group", fmt.Sprintf("GroupKeyA: %s\nGroupKeyB: %s\n", + types.GroupStoreKey(1, "group"), types.GroupStoreKey(1, "group"))}, + {"Group member", fmt.Sprintf("GroupMemberKeyA: %s\nGroupMemberKeyB: %s\n", + types.GroupMemberStoreKey(1, "group", sdkAddr), types.GroupMemberStoreKey(1, "group", sdkAddr))}, + {"Permission", fmt.Sprintf("PermissionKeyA: %d\nPermissionKeyB: %d\n", + types.PermissionWrite, types.PermissionWrite)}, + {"other", ""}, + } + + for i, tc := range testCases { + i, tc := i, tc + t.Run(tc.name, func(t *testing.T) { + switch i { + case len(testCases) - 1: + require.Panics(t, func() { decoder(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tc.name) + default: + require.Equal(t, tc.expectedLog, decoder(kvPairs.Pairs[i], kvPairs.Pairs[i]), tc.name) + } + }) + } +} diff --git a/x/subspaces/simulation/genesis.go b/x/subspaces/simulation/genesis.go new file mode 100644 index 0000000000..21b43fc2f4 --- /dev/null +++ b/x/subspaces/simulation/genesis.go @@ -0,0 +1,179 @@ +package simulation + +// DONTCOVER + +import ( + "fmt" + "math/rand" + + "github.com/cosmos/cosmos-sdk/types/module" + + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// RandomizeGenState generates a random GenesisState for subspaces +func RandomizeGenState(simState *module.SimulationState) { + subspaces := randomSubspaces(simState.Rand, simState.Accounts) + groups := randomUserGroups(simState.Rand, simState.Accounts, subspaces) + acl := randomACL(simState.Rand, simState.Accounts, subspaces, groups) + + // Create the genesis and sanitize it + subspacesGenesis := types.NewGenesisState(subspaces, groups, acl) + subspacesGenesis = sanitizeGenesis(subspacesGenesis) + + simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(subspacesGenesis) +} + +// randomSubspaces returns randomly generated genesis account +func randomSubspaces(r *rand.Rand, accs []simtypes.Account) (subspaces []types.Subspace) { + subspacesNumber := r.Intn(100) + subspaces = make([]types.Subspace, subspacesNumber) + for index := 0; index < subspacesNumber; index++ { + subspaces[index] = GenerateRandomSubspace(r, accs) + } + return subspaces +} + +// randomUserGroups generates random slice of user group details +func randomUserGroups(r *rand.Rand, accounts []simtypes.Account, subspaces []types.Subspace) (groups []types.UserGroup) { + groupsNumber := r.Intn(30) + groups = make([]types.UserGroup, groupsNumber) + for i := 0; i < groupsNumber; i++ { + subspace, _ := RandomSubspace(r, subspaces) + + // Get a random number of members + membersNumber := r.Intn(5) + members := make([]string, membersNumber) + for j := 0; j < membersNumber; j++ { + members[j] = RandomAccount(r, accounts).Address.String() + } + members = sanitizeStrings(members) + + // Build the group details + groups[i] = types.NewUserGroup(subspace.ID, RandomName(r), members) + } + + return groups +} + +// randomACL generates a random slice of ACL entries +func randomACL(r *rand.Rand, accounts []simtypes.Account, subspaces []types.Subspace, groups []types.UserGroup) (entries []types.ACLEntry) { + aclEntriesNumber := r.Intn(40) + entries = make([]types.ACLEntry, aclEntriesNumber) + for index := 0; index < aclEntriesNumber; index++ { + subspace, _ := RandomSubspace(r, subspaces) + target := RandomAccount(r, accounts).Address.String() + + // 50% of chance of selecting a group rather than an account + if r.Intn(101) <= 50 { + target = RandomGroup(r, groups).Name + } + + // Get a random permission + permission := RandomPermission(r, []types.Permission{ + types.PermissionNothing, + types.PermissionWrite, + types.PermissionManageGroups, + types.PermissionEverything, + }) + + // Crete the entry + entries[index] = types.NewACLEntry(subspace.ID, target, permission) + } + + return entries +} + +// -------------------------------------------------------------------------------------------------------------------- + +// sanitizeGenesis sanitizes the given genesis by removing all the double subspaces, +// groups or ACL entries that might be there +func sanitizeGenesis(genesis *types.GenesisState) *types.GenesisState { + return types.NewGenesisState( + sanitizeSubspaces(genesis.Subspaces), + sanitizeUserGroups(genesis.UserGroups), + sanitizeACLEntry(genesis.ACL), + ) +} + +// sanitizeSubspaces sanitizes the given slice by removing all the double subspaces +func sanitizeSubspaces(slice []types.Subspace) []types.Subspace { + ids := map[uint64]int{} + for _, value := range slice { + ids[value.ID] = 1 + } + + var unique []types.Subspace + for id := range ids { + SubspaceLoop: + for _, subspace := range slice { + if id == subspace.ID { + unique = append(unique, subspace) + break SubspaceLoop + } + } + } + + return unique +} + +// sanitizeUserGroups sanitizes the given slice by removing all the double groups +func sanitizeUserGroups(slice []types.UserGroup) []types.UserGroup { + groups := map[string]int{} + for _, value := range slice { + groups[fmt.Sprintf("%d%s", value.SubspaceID, value.Name)] = 1 + } + + var unique []types.UserGroup + for id := range groups { + EntryLoop: + for _, group := range slice { + if id == fmt.Sprintf("%d%s", group.SubspaceID, group.Name) { + unique = append(unique, group) + break EntryLoop + } + } + } + + return unique +} + +// sanitizeSubspaces sanitizes the given slice by removing all the double entries +func sanitizeACLEntry(slice []types.ACLEntry) []types.ACLEntry { + entries := map[string]int{} + for _, value := range slice { + entries[fmt.Sprintf("%d%s", value.SubspaceID, value.Target)] = 1 + } + + var unique []types.ACLEntry + for id := range entries { + EntryLoop: + for _, entry := range slice { + if id == fmt.Sprintf("%d%s", entry.SubspaceID, entry.Target) { + unique = append(unique, entry) + break EntryLoop + } + } + } + + return unique +} + +// sanitizeStrings sanitizes the given slice by removing all duplicated values +func sanitizeStrings(slice []string) []string { + values := map[string]int{} + for _, value := range slice { + values[value] = 1 + } + + count := 0 + unique := make([]string, len(values)) + for value := range values { + unique[count] = value + count++ + } + + return unique +} diff --git a/x/subspaces/simulation/operations.go b/x/subspaces/simulation/operations.go new file mode 100644 index 0000000000..ae30f055bf --- /dev/null +++ b/x/subspaces/simulation/operations.go @@ -0,0 +1,117 @@ +package simulation + +// DONTCOVER + +import ( + "math/rand" + + "github.com/cosmos/cosmos-sdk/codec" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + sim "github.com/cosmos/cosmos-sdk/x/simulation" + + "github.com/desmos-labs/desmos/v2/app/params" + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" +) + +// Simulation operation weights constants +// #nosec G101 -- This is a false positive +const ( + OpWeightMsgCreateSubspace = "op_weight_msg_create_subspace" + OpWeightMsgEditSubspace = "op_weight_msg_edit_subspace" + OpWeightMsgCreateUserGroup = "op_weight_msg_create_user_group" + OpWeightMsgDeleteUserGroup = "op_weight_msg_delete_user_group" + OpWeightMsgAddUserToUserGroup = "op_weight_msg_add_user_to_user_group" + OpWeightMsgRemoveUserFromUserGroup = "op_weight_msg_remove_user_from_user_group" + OpWeightMsgSetPermissions = "op_weight_msg_set_permissions" + + DefaultGasValue = 200_000 +) + +// WeightedOperations returns all the operations from the module with their respective weights +func WeightedOperations( + appParams simtypes.AppParams, cdc codec.JSONCodec, + k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, +) sim.WeightedOperations { + + var weightMsgCreateSubspace int + appParams.GetOrGenerate(cdc, OpWeightMsgCreateSubspace, &weightMsgCreateSubspace, nil, + func(_ *rand.Rand) { + weightMsgCreateSubspace = params.DefaultWeightMsgCreateSubspace + }, + ) + + var weightMsgEditSubspace int + appParams.GetOrGenerate(cdc, OpWeightMsgEditSubspace, &weightMsgEditSubspace, nil, + func(_ *rand.Rand) { + weightMsgEditSubspace = params.DefaultWeightMsgEditSubspace + }, + ) + + var weightMsgCreateUserGroup int + appParams.GetOrGenerate(cdc, OpWeightMsgCreateUserGroup, &weightMsgCreateUserGroup, nil, + func(_ *rand.Rand) { + weightMsgCreateUserGroup = params.DefaultWeightMsgCreateUserGroup + }, + ) + + var weightMsgDeleteUserGroup int + appParams.GetOrGenerate(cdc, OpWeightMsgDeleteUserGroup, &weightMsgDeleteUserGroup, nil, + func(_ *rand.Rand) { + weightMsgDeleteUserGroup = params.DefaultWeightMsgDeleteUserGroup + }, + ) + + var weightMsgAddUserToUserGroup int + appParams.GetOrGenerate(cdc, OpWeightMsgAddUserToUserGroup, &weightMsgAddUserToUserGroup, nil, + func(_ *rand.Rand) { + weightMsgAddUserToUserGroup = params.DefaultWeightMsgAddUserToUserGroup + }, + ) + + var weightMsgRemoveUserFromUserGroup int + appParams.GetOrGenerate(cdc, OpWeightMsgRemoveUserFromUserGroup, &weightMsgRemoveUserFromUserGroup, nil, + func(_ *rand.Rand) { + weightMsgRemoveUserFromUserGroup = params.DefaultWeightMsgRemoveUserFromUserGroup + }, + ) + + var weightMsgSetPermissions int + appParams.GetOrGenerate(cdc, OpWeightMsgSetPermissions, &weightMsgSetPermissions, nil, + func(_ *rand.Rand) { + weightMsgSetPermissions = params.DefaultWeightMsgSetPermissions + }, + ) + + return sim.WeightedOperations{ + sim.NewWeightedOperation( + weightMsgCreateSubspace, + SimulateMsgCreateSubspace(ak, bk), + ), + sim.NewWeightedOperation( + weightMsgEditSubspace, + SimulateMsgEditSubspace(k, ak, bk), + ), + sim.NewWeightedOperation( + weightMsgCreateUserGroup, + SimulateMsgCreateUserGroup(k, ak, bk), + ), + sim.NewWeightedOperation( + weightMsgDeleteUserGroup, + SimulateMsgDeleteUserGroup(k, ak, bk), + ), + sim.NewWeightedOperation( + weightMsgAddUserToUserGroup, + SimulateMsgAddUserToUserGroup(k, ak, bk), + ), + sim.NewWeightedOperation( + weightMsgRemoveUserFromUserGroup, + SimulateMsgRemoveUserFromUserGroup(k, ak, bk), + ), + sim.NewWeightedOperation( + weightMsgSetPermissions, + SimulateMsgSetPermissions(k, ak, bk), + ), + } +} diff --git a/x/subspaces/simulation/operations_groups.go b/x/subspaces/simulation/operations_groups.go new file mode 100644 index 0000000000..94a1b65516 --- /dev/null +++ b/x/subspaces/simulation/operations_groups.go @@ -0,0 +1,276 @@ +package simulation + +import ( + "math/rand" + + "github.com/desmos-labs/desmos/v2/testutil/simtesting" + + "github.com/cosmos/cosmos-sdk/baseapp" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// SimulateMsgCreateUserGroup tests and runs a single MsgCreateUserGroup +func SimulateMsgCreateUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspaceID, groupName, permissions, creator, skip := randomCreateUserGroupFields(r, ctx, accs, k) + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgCreateUserGroup"), nil, nil + } + + // Build the message + msg := types.NewMsgCreateUserGroup(subspaceID, groupName, permissions, creator.Address.String()) + + // Send the message + err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{creator.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgCreateUserGroup"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgCreateUserGroup", nil), nil, nil + } +} + +// randomCreateUserGroupFields returns the data used to build a random MsgCreateUserGroup +func randomCreateUserGroupFields( + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, +) (subspaceID uint64, groupName string, permissions types.Permission, account simtypes.Account, skip bool) { + // Get a subspace id + subspaces := k.GetAllSubspaces(ctx) + if len(subspaces) == 0 { + // Skip because there are no subspaces + skip = true + return + } + subspace, _ := RandomSubspace(r, subspaces) + subspaceID = subspace.ID + + // Get a group name + groupName = RandomName(r) + if k.HasUserGroup(ctx, subspaceID, groupName) { + // Skip if the group already exists + skip = true + return + } + + // Get a default permission + permissions = RandomPermission(r, []types.Permission{ + types.PermissionWrite, + types.PermissionChangeInfo, + types.PermissionEverything, + }) + + // Get a signer + signers, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionManageGroups) + acc := GetAccount(RandomAddress(r, signers), accs) + if acc == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + account = *acc + + return subspaceID, groupName, permissions, account, false +} + +// -------------------------------------------------------------------------------------------------------------------- + +// SimulateMsgDeleteUserGroup tests and runs a single MsgDeleteUserGroup +func SimulateMsgDeleteUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspaceID, groupName, signer, skip := randomDeleteUserGroupFields(r, ctx, accs, k) + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgDeleteUserGroup"), nil, nil + } + + // Build the message + msg := types.NewMsgDeleteUserGroup(subspaceID, groupName, signer.Address.String()) + + // Send the message + err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{signer.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgDeleteUserGroup"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgDeleteUserGroup", nil), nil, nil + } +} + +// randomDeleteUserGroupFields returns the data used to build a random MsgDeleteUserGroup +func randomDeleteUserGroupFields( + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, +) (subspaceID uint64, groupName string, account simtypes.Account, skip bool) { + // Get a subspace id + subspaces := k.GetAllSubspaces(ctx) + if len(subspaces) == 0 { + // Skip because there are no subspaces + skip = true + return + } + subspace, _ := RandomSubspace(r, subspaces) + subspaceID = subspace.ID + + // Get a group name + groups := k.GetSubspaceGroups(ctx, subspace.ID) + groupName = RandomString(r, groups) + + // Get a signer + signers, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionManageGroups) + acc := GetAccount(RandomAddress(r, signers), accs) + if acc == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + account = *acc + + return subspaceID, groupName, account, false +} + +// -------------------------------------------------------------------------------------------------------------------- + +// SimulateMsgAddUserToUserGroup tests and runs a single MsgAddUserToUserGroup +func SimulateMsgAddUserToUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspaceID, groupName, user, signer, skip := randomAddUserToUserGroupFields(r, ctx, accs, k, ak) + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgAddUserToUserGroup"), nil, nil + } + + // Build the message + msg := types.NewMsgAddUserToUserGroup(subspaceID, groupName, user, signer.Address.String()) + + // Send the message + err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{signer.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgAddUserToUserGroup"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgAddUserToUserGroup", nil), nil, nil + } +} + +// randomAddUserToUserGroupFields returns the data used to build a random MsgAddUserToUserGroup +func randomAddUserToUserGroupFields( + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, ak authkeeper.AccountKeeper, +) (subspaceID uint64, groupName string, user string, account simtypes.Account, skip bool) { + // Get a subspace id + subspaces := k.GetAllSubspaces(ctx) + if len(subspaces) == 0 { + // Skip because there are no subspaces + skip = true + return + } + subspace, _ := RandomSubspace(r, subspaces) + subspaceID = subspace.ID + + // Get a group + groups := k.GetSubspaceGroups(ctx, subspace.ID) + groupName = RandomString(r, groups) + + // Get a user + accounts := ak.GetAllAccounts(ctx) + userAccount := RandomAuthAccount(r, accounts) + if k.IsMemberOfGroup(ctx, subspace.ID, groupName, userAccount.GetAddress()) { + // Skip if the user is already part of group + skip = true + return + } + user = userAccount.GetAddress().String() + + // Get a signer + signers, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionSetPermissions) + acc := GetAccount(RandomAddress(r, signers), accs) + if acc == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + account = *acc + + return subspaceID, groupName, user, account, false +} + +// -------------------------------------------------------------------------------------------------------------------- + +// SimulateMsgRemoveUserFromUserGroup tests and runs a single MsgRemoveUserFromUserGroup +func SimulateMsgRemoveUserFromUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspaceID, groupName, user, signer, skip := randomRemoveUserFromUserGroupFields(r, ctx, accs, k) + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgRemoveUserFromUserGroup"), nil, nil + } + + // Build the message + msg := types.NewMsgRemoveUserFromUserGroup(subspaceID, groupName, user, signer.Address.String()) + + // Send the message + err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{signer.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgRemoveUserFromUserGroup"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgRemoveUserFromUserGroup", nil), nil, nil + } +} + +// randomRemoveUserFromUserGroupFields returns the data used to build a random MsgRemoveUserFromUserGroup +func randomRemoveUserFromUserGroupFields( + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, +) (subspaceID uint64, groupName string, user string, account simtypes.Account, skip bool) { + // Get a subspace id + subspaces := k.GetAllSubspaces(ctx) + if len(subspaces) == 0 { + // Skip because there are no subspaces + skip = true + return + } + subspace, _ := RandomSubspace(r, subspaces) + subspaceID = subspace.ID + + // Get a group + groups := k.GetSubspaceGroups(ctx, subspace.ID) + groupName = RandomString(r, groups) + + // Get a user + members := k.GetGroupMembers(ctx, subspace.ID, groupName) + user = RandomAddress(r, members).String() + + // Get a signer + signers, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionSetPermissions) + acc := GetAccount(RandomAddress(r, signers), accs) + if acc == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + account = *acc + + return subspaceID, groupName, user, account, false +} diff --git a/x/subspaces/simulation/operations_permissions.go b/x/subspaces/simulation/operations_permissions.go new file mode 100644 index 0000000000..007c6222ec --- /dev/null +++ b/x/subspaces/simulation/operations_permissions.go @@ -0,0 +1,87 @@ +package simulation + +import ( + "math/rand" + + "github.com/desmos-labs/desmos/v2/testutil/simtesting" + + "github.com/cosmos/cosmos-sdk/baseapp" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// SimulateMsgSetPermissions tests and runs a single MsgSetPermissions +func SimulateMsgSetPermissions(k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspaceID, target, permissions, creator, skip := randomSetPermissionsFields(r, ctx, accs, k, ak) + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgSetPermissions"), nil, nil + } + + // Build the message + msg := types.NewMsgSetPermissions(subspaceID, target, permissions, creator.Address.String()) + + // Send the message + err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{creator.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgSetPermissions"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgSetPermissions", nil), nil, nil + } +} + +// randomSetPermissionsFields returns the data used to build a random MsgSetPermissions +func randomSetPermissionsFields( + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, ak authkeeper.AccountKeeper, +) (subspaceID uint64, target string, permissions types.Permission, account simtypes.Account, skip bool) { + // Get a subspace id + subspaces := k.GetAllSubspaces(ctx) + if len(subspaces) == 0 { + // Skip because there are no subspaces + skip = true + return + } + subspace, _ := RandomSubspace(r, subspaces) + subspaceID = subspace.ID + + // Get a target + accounts := ak.GetAllAccounts(ctx) + var targets = make([]string, len(accounts)) + for i, account := range accounts { + targets[i] = account.String() + } + targets = append(targets, k.GetSubspaceGroups(ctx, subspace.ID)...) + target = RandomString(r, targets) + + // Get a permission + permissions = RandomPermission(r, []types.Permission{ + types.PermissionWrite, + types.PermissionModerateContent, + types.PermissionChangeInfo, + types.PermissionManageGroups, + }) + + // Get a signer + signers, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionSetPermissions) + acc := GetAccount(RandomAddress(r, signers), accs) + if acc == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + account = *acc + + return subspaceID, target, permissions, account, false +} diff --git a/x/subspaces/simulation/operations_subspaces.go b/x/subspaces/simulation/operations_subspaces.go new file mode 100644 index 0000000000..996b5af772 --- /dev/null +++ b/x/subspaces/simulation/operations_subspaces.go @@ -0,0 +1,150 @@ +package simulation + +// DONTCOVER + +import ( + "math/rand" + + "github.com/desmos-labs/desmos/v2/testutil/simtesting" + + "github.com/cosmos/cosmos-sdk/baseapp" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// SimulateMsgCreateSubspace tests and runs a single MsgCreateSubspace +func SimulateMsgCreateSubspace(ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspace, creator, skip, err := randomSubspaceCreateFields(r, accs) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgCreateSubspace"), nil, err + } + + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgCreateSubspace"), nil, nil + } + + // Build the message + msg := types.NewMsgCreateSubspace( + subspace.Name, + subspace.Description, + subspace.Treasury, + subspace.Owner, + subspace.Creator, + ) + + // Send the message + err = simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{creator.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgCreateSubspace"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgCreateSubspace", nil), nil, nil + } +} + +// randomSubspaceCreateFields returns the data used to build a random MsgCreateSubspace +func randomSubspaceCreateFields( + r *rand.Rand, accs []simtypes.Account, +) (subspace types.Subspace, creator simtypes.Account, skip bool, err error) { + // Get the subspace data + subspace = GenerateRandomSubspace(r, accs) + + // Get the creator + sdkAddr, err := sdk.AccAddressFromBech32(subspace.Creator) + if err != nil { + return + } + account := GetAccount(sdkAddr, accs) + if account == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + creator = *account + + return +} + +// ___________________________________________________________________________________________________________________ + +// SimulateMsgEditSubspace tests and runs a single msg edit subspace +func SimulateMsgEditSubspace( + k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, +) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspaceID, update, editor, skip := randomEditSubspaceFields(r, ctx, accs, k) + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgEditSubspace"), nil, nil + } + + // Build the message + msg := types.NewMsgEditSubspace( + subspaceID, + update.Name, + update.Description, + update.Treasury, + update.Owner, + editor.Address.String(), + ) + + // Send the data + err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{editor.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgEditSubspace"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgEditSubspace", nil), nil, nil + } +} + +// randomEditSubspaceFields returns the data needed to edit a subspace +func randomEditSubspaceFields( + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, +) (subspaceID uint64, update *types.SubspaceUpdate, account simtypes.Account, skip bool) { + // Get a subspace id + subspaces := k.GetAllSubspaces(ctx) + if len(subspaces) == 0 { + // Skip because there are no subspaces + skip = true + return + } + subspace, _ := RandomSubspace(r, subspaces) + subspaceID = subspace.ID + + // Build the update data + update = types.NewSubspaceUpdate( + RandomName(r), + RandomDescription(r), + account.Address.String(), + account.Address.String(), + ) + + // Get an editor + editors, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionChangeInfo) + acc := GetAccount(RandomAddress(r, editors), accs) + if acc == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + account = *acc + + return subspaceID, update, account, false +} diff --git a/x/subspaces/simulation/utils.go b/x/subspaces/simulation/utils.go new file mode 100644 index 0000000000..47bcb427fc --- /dev/null +++ b/x/subspaces/simulation/utils.go @@ -0,0 +1,102 @@ +package simulation + +// DONTCOVER + +import ( + "math/rand" + "time" + + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// RandomSubspace picks a random subspace from an array and returns its position as well as value. +func RandomSubspace(r *rand.Rand, subspaces []types.Subspace) (types.Subspace, int) { + idx := r.Intn(len(subspaces)) + return subspaces[idx], idx +} + +// GenerateRandomSubspace generates a new subspace containing random data +func GenerateRandomSubspace(r *rand.Rand, accs []simtypes.Account) types.Subspace { + simAccount, _ := simtypes.RandomAcc(r, accs) + creator := simAccount.Address.String() + + return types.NewSubspace( + RandomID(r), + RandomName(r), + RandomDescription(r), + creator, + creator, + creator, + RandomDate(r), + ) +} + +// RandomID returns a new random ID +func RandomID(r *rand.Rand) uint64 { + return r.Uint64() +} + +// RandomName returns a random subspace name +func RandomName(r *rand.Rand) string { + return simtypes.RandStringOfLength(r, 10) +} + +// RandomDescription returns a random subspace description +func RandomDescription(r *rand.Rand) string { + return simtypes.RandStringOfLength(r, 30) +} + +// RandomDate returns a random post creation date +func RandomDate(r *rand.Rand) time.Time { + min := time.Date(1970, 1, 0, 0, 0, 0, 0, time.UTC).Unix() + max := time.Date(2010, 1, 0, 0, 0, 0, 0, time.UTC).Unix() + delta := max - min + + sec := r.Int63n(delta) + min + return time.Unix(sec, 0).Truncate(time.Millisecond) +} + +// RandomString returns a random string from the given slice +func RandomString(r *rand.Rand, strings []string) string { + return strings[r.Intn(len(strings))] +} + +// RandomGroup returns a random group selecting it from the list of groups given +func RandomGroup(r *rand.Rand, groups []types.UserGroup) types.UserGroup { + return groups[r.Intn(len(groups))] +} + +// RandomPermission returns a random permission from the given slice +func RandomPermission(r *rand.Rand, permissions []types.Permission) types.Permission { + return permissions[r.Intn(len(permissions))] +} + +// RandomAccount returns a random account from the slice given +func RandomAccount(r *rand.Rand, accounts []simtypes.Account) simtypes.Account { + return accounts[r.Intn(len(accounts))] +} + +// RandomAddress returns a random address from the slice given +func RandomAddress(r *rand.Rand, addresses []sdk.AccAddress) sdk.AccAddress { + return addresses[r.Intn(len(addresses))] +} + +// RandomAuthAccount returns a random account from the slice given +func RandomAuthAccount(r *rand.Rand, accounts []authtypes.AccountI) authtypes.AccountI { + return accounts[r.Intn(len(accounts))] +} + +// GetAccount gets the account having the given address from the accs list +func GetAccount(address sdk.Address, accs []simtypes.Account) *simtypes.Account { + for _, acc := range accs { + if acc.Address.Equals(address) { + return &acc + } + } + return nil +} diff --git a/x/subspaces/types/genesis.go b/x/subspaces/types/genesis.go index 74fe707071..9c673c12ee 100644 --- a/x/subspaces/types/genesis.go +++ b/x/subspaces/types/genesis.go @@ -56,11 +56,11 @@ func (group UserGroup) Validate() error { // ------------------------------------------------------------------------------------------------------------------- // NewGenesisState creates a new genesis state -func NewGenesisState(subspaces []Subspace, acl []ACLEntry, userGroups []UserGroup) *GenesisState { +func NewGenesisState(subspaces []Subspace, userGroups []UserGroup, acl []ACLEntry) *GenesisState { return &GenesisState{ Subspaces: subspaces, - ACL: acl, UserGroups: userGroups, + ACL: acl, } } diff --git a/x/subspaces/types/genesis_test.go b/x/subspaces/types/genesis_test.go index 079a4dc20a..aa951b370b 100644 --- a/x/subspaces/types/genesis_test.go +++ b/x/subspaces/types/genesis_test.go @@ -158,46 +158,46 @@ func TestValidateGenesis(t *testing.T) { { name: "invalid ACL entry returns error", genesis: types.NewGenesisState( + nil, nil, []types.ACLEntry{ types.NewACLEntry(0, "group", types.PermissionWrite), }, - nil, ), shouldErr: true, }, { name: "duplicated ACL entry returns error", genesis: types.NewGenesisState( + nil, nil, []types.ACLEntry{ types.NewACLEntry(1, "group", types.PermissionWrite), types.NewACLEntry(1, "group", types.PermissionSetPermissions), }, - nil, ), shouldErr: true, }, { name: "invalid group returns error", genesis: types.NewGenesisState( - nil, nil, []types.UserGroup{ types.NewUserGroup(0, "group", nil), }, + nil, ), shouldErr: true, }, { name: "duplicated group returns error", genesis: types.NewGenesisState( - nil, nil, []types.UserGroup{ types.NewUserGroup(1, "group", nil), types.NewUserGroup(1, "group", nil), }, + nil, ), shouldErr: true, }, @@ -229,10 +229,6 @@ func TestValidateGenesis(t *testing.T) { time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), ), }, - []types.ACLEntry{ - types.NewACLEntry(1, "group", types.PermissionWrite), - types.NewACLEntry(2, "another-group", types.PermissionManageGroups), - }, []types.UserGroup{ types.NewUserGroup(1, "group", []string{ "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", @@ -242,6 +238,10 @@ func TestValidateGenesis(t *testing.T) { "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", }), }, + []types.ACLEntry{ + types.NewACLEntry(1, "group", types.PermissionWrite), + types.NewACLEntry(2, "another-group", types.PermissionManageGroups), + }, ), shouldErr: false, }, diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go index 039a90ec0d..751f3ced92 100644 --- a/x/subspaces/types/permissions.go +++ b/x/subspaces/types/permissions.go @@ -36,19 +36,26 @@ const ( // ParsePermission parses the given permission string as a single Permissions instance func ParsePermission(permission string) (Permission, error) { - if strings.EqualFold(permission, "nothing") { + switch { + case strings.EqualFold(permission, "nothing"): return PermissionNothing, nil - } else if strings.EqualFold(permission, "Write") { + + case strings.EqualFold(permission, "Write"): return PermissionWrite, nil - } else if strings.EqualFold(permission, "ModerateContent") { + + case strings.EqualFold(permission, "ModerateContent"): return PermissionModerateContent, nil - } else if strings.EqualFold(permission, "ChangeInfo") { + + case strings.EqualFold(permission, "ChangeInfo"): return PermissionChangeInfo, nil - } else if strings.EqualFold(permission, "ManageGroups") { + + case strings.EqualFold(permission, "ManageGroups"): return PermissionManageGroups, nil - } else if strings.EqualFold(permission, "SetPermissions") { + + case strings.EqualFold(permission, "SetPermissions"): return PermissionSetPermissions, nil - } else if strings.EqualFold(permission, "Everything") { + + case strings.EqualFold(permission, "Everything"): return PermissionEverything, nil } diff --git a/x/subspaces/types/permissions_test.go b/x/subspaces/types/permissions_test.go index 86d7d6b354..77f29639d2 100644 --- a/x/subspaces/types/permissions_test.go +++ b/x/subspaces/types/permissions_test.go @@ -22,7 +22,7 @@ func TestMarshalPermission(t *testing.T) { { name: "non-zero permission", permission: types.PermissionManageGroups, - expected: []byte{0, 0, 0, 4}, + expected: []byte{0, 0, 0, 8}, }, { name: "high permission", @@ -63,7 +63,7 @@ func TestUnmarshalPermission(t *testing.T) { }, { name: "non-zero permission", - bz: []byte{0, 0, 0, 8}, + bz: []byte{0, 0, 0, 4}, expected: types.PermissionChangeInfo, }, } From 78a549904761af2673cbc963f5b4eef43cfcd2ac Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 24 Jan 2022 12:14:02 +0100 Subject: [PATCH 11/47] added changeset entry Signed-off-by: Riccardo Montagnin --- ...93894ef9a0bba10c1e28531dfd3420616246ebcdbe0c889326f.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/entries/7804abd9534fe93894ef9a0bba10c1e28531dfd3420616246ebcdbe0c889326f.yaml diff --git a/.changeset/entries/7804abd9534fe93894ef9a0bba10c1e28531dfd3420616246ebcdbe0c889326f.yaml b/.changeset/entries/7804abd9534fe93894ef9a0bba10c1e28531dfd3420616246ebcdbe0c889326f.yaml new file mode 100644 index 0000000000..fa9b8c157e --- /dev/null +++ b/.changeset/entries/7804abd9534fe93894ef9a0bba10c1e28531dfd3420616246ebcdbe0c889326f.yaml @@ -0,0 +1,6 @@ +type: feat +module: x/subspaces +pull_request: 728 +description: Added the new `x/subspaces` module +backward_compatible: false +date: 2022-01-24T11:13:39.102634771Z From 8233131936d631ee5f9f07ce976c18837ba92885 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 24 Jan 2022 14:13:46 +0100 Subject: [PATCH 12/47] updated x/profiles to use the correct type for subspaces ids Signed-off-by: Riccardo Montagnin --- app/app.go | 7 +- .../v1beta1/models_relationships.proto | 4 +- .../profiles/v1beta1/msgs_relationships.proto | 8 +- .../v1beta1/query_relationships.proto | 4 +- x/profiles/client/cli/cli_relationships.go | 44 +++- .../client/cli/cli_relationships_test.go | 8 +- x/profiles/client/cli/cli_test.go | 4 +- x/profiles/keeper/common_test.go | 11 +- x/profiles/keeper/expected_keeper.go | 16 ++ x/profiles/keeper/genesis_test.go | 40 ++-- x/profiles/keeper/grpc_query.go | 14 +- x/profiles/keeper/grpc_query_test.go | 28 +-- x/profiles/keeper/invariants.go | 4 +- x/profiles/keeper/invariants_test.go | 8 +- x/profiles/keeper/keeper.go | 3 + x/profiles/keeper/keeper_blocks.go | 12 +- x/profiles/keeper/keeper_blocks_test.go | 44 ++-- x/profiles/keeper/keeper_relationships.go | 9 +- .../keeper/keeper_relationships_test.go | 38 ++-- x/profiles/keeper/msg_server_blocks.go | 5 +- x/profiles/keeper/msg_server_blocks_test.go | 20 +- .../keeper/msg_server_dtag_transfers_test.go | 2 +- x/profiles/keeper/msg_server_relationships.go | 10 +- .../keeper/msg_server_relationships_test.go | 35 ++- x/profiles/module.go | 8 +- x/profiles/simulation/decoder.go | 4 +- x/profiles/simulation/decoder_test.go | 12 +- x/profiles/simulation/genesis.go | 23 +- x/profiles/simulation/operations.go | 4 +- .../simulation/operations_relationships.go | 22 +- .../simulation/operations_user_blocks.go | 4 +- x/profiles/types/genesis.go | 2 +- x/profiles/types/genesis_test.go | 30 +-- x/profiles/types/keys.go | 18 +- x/profiles/types/models_relationships.go | 20 +- x/profiles/types/models_relationships.pb.go | 128 ++++------- x/profiles/types/models_relationships_test.go | 37 +-- x/profiles/types/msgs_relationships.go | 24 +- x/profiles/types/msgs_relationships.pb.go | 214 ++++++------------ x/profiles/types/msgs_relationships_test.go | 71 ++---- x/profiles/types/query_relationships.pb.go | 126 ++++------- x/subspaces/client/cli/query.go | 13 +- x/subspaces/client/cli/tx.go | 25 +- x/subspaces/types/subspace.go | 14 ++ 44 files changed, 544 insertions(+), 633 deletions(-) create mode 100644 x/profiles/keeper/expected_keeper.go diff --git a/app/app.go b/app/app.go index cab05e543f..6cede0aeea 100644 --- a/app/app.go +++ b/app/app.go @@ -417,11 +417,12 @@ func NewDesmosApp( keys[profilestypes.StoreKey], app.GetSubspace(profilestypes.ModuleName), app.AccountKeeper, + app.SubspacesKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper, scopedProfilesKeeper, ) - profilesModule := profiles.NewAppModule(appCodec, legacyAmino, app.ProfileKeeper, app.AccountKeeper, app.BankKeeper) + profilesModule := profiles.NewAppModule(appCodec, legacyAmino, app.ProfileKeeper, app.SubspacesKeeper, app.AccountKeeper, app.BankKeeper) // Create subspaces keeper app.SubspacesKeeper = subspaceskeeper.NewKeeper(app.appCodec, keys[subspacestypes.StoreKey]) @@ -586,8 +587,8 @@ func NewDesmosApp( wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper), // Custom modules - profiles.NewAppModule(app.appCodec, legacyAmino, app.ProfileKeeper, app.AccountKeeper, app.BankKeeper), - // TODO: Add the subspaces module here + profiles.NewAppModule(app.appCodec, legacyAmino, app.ProfileKeeper, app.SubspacesKeeper, app.AccountKeeper, app.BankKeeper), + subspaces.NewAppModule(app.appCodec, app.SubspacesKeeper, app.AccountKeeper, app.BankKeeper), ) app.sm.RegisterStoreDecoders() diff --git a/proto/desmos/profiles/v1beta1/models_relationships.proto b/proto/desmos/profiles/v1beta1/models_relationships.proto index ac37d4be29..2e882a0509 100644 --- a/proto/desmos/profiles/v1beta1/models_relationships.proto +++ b/proto/desmos/profiles/v1beta1/models_relationships.proto @@ -17,7 +17,7 @@ message Relationship { string creator = 1 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; string recipient = 2 [ (gogoproto.moretags) = "yaml:\"recipient\"" ]; - string subspace = 3 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; + uint64 subspace = 3 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; } // UserBlock represents the fact that the Blocker has blocked the given Blocked @@ -37,5 +37,5 @@ message UserBlock { // Subspace contains the ID of the subspace inside which the user should be // blocked - string subspace = 4 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; + uint64 subspace = 4 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; } diff --git a/proto/desmos/profiles/v1beta1/msgs_relationships.proto b/proto/desmos/profiles/v1beta1/msgs_relationships.proto index 4c32b756f9..3f51f03255 100644 --- a/proto/desmos/profiles/v1beta1/msgs_relationships.proto +++ b/proto/desmos/profiles/v1beta1/msgs_relationships.proto @@ -18,7 +18,7 @@ message MsgCreateRelationship { string sender = 1 [ (gogoproto.moretags) = "yaml:\"sender\"" ]; string receiver = 2 [ (gogoproto.moretags) = "yaml:\"receiver\"" ]; - string subspace = 3 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; + uint64 subspace = 3 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; } // MsgCreateRelationshipResponse defines the Msg/CreateRelationship response @@ -32,7 +32,7 @@ message MsgCreateRelationshipResponse {} message MsgDeleteRelationship { string user = 1 [ (gogoproto.moretags) = "yaml:\"user\"" ]; string counterparty = 2 [ (gogoproto.moretags) = "yaml:\"counterparty\"" ]; - string subspace = 3 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; + uint64 subspace = 3 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; } // MsgDeleteRelationshipResponse defines the Msg/DeleteRelationship response @@ -47,7 +47,7 @@ message MsgBlockUser { string blocker = 1 [ (gogoproto.moretags) = "yaml:\"blocker\"" ]; string blocked = 2 [ (gogoproto.moretags) = "yaml:\"blocked\"" ]; string reason = 3 [ (gogoproto.moretags) = "yaml:\"reason\"" ]; - string subspace = 4 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; + uint64 subspace = 4 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; } // MsgBlockUserResponse defines the Msg/BlockUser response type. @@ -59,7 +59,7 @@ message MsgBlockUserResponse {} message MsgUnblockUser { string blocker = 1 [ (gogoproto.moretags) = "yaml:\"blocker\"" ]; string blocked = 2 [ (gogoproto.moretags) = "yaml:\"blocked\"" ]; - string subspace = 4 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; + uint64 subspace = 4 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; } // MsgUnblockUserResponse defines the Msg/UnblockUser response type. diff --git a/proto/desmos/profiles/v1beta1/query_relationships.proto b/proto/desmos/profiles/v1beta1/query_relationships.proto index 5994d87e13..83554c4d31 100644 --- a/proto/desmos/profiles/v1beta1/query_relationships.proto +++ b/proto/desmos/profiles/v1beta1/query_relationships.proto @@ -20,7 +20,7 @@ message QueryRelationshipsRequest { string user = 1; // subspace to query the relationships for - string subspace_id = 2; + uint64 subspace_id = 2; // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageRequest pagination = 3; @@ -46,7 +46,7 @@ message QueryBlocksRequest { // address of the user to query the blocks for string user = 1; - string subspace_id = 2; + uint64 subspace_id = 2; cosmos.base.query.v1beta1.PageRequest pagination = 3; } diff --git a/x/profiles/client/cli/cli_relationships.go b/x/profiles/client/cli/cli_relationships.go index ec7d626f36..8fa7bb4ad8 100644 --- a/x/profiles/client/cli/cli_relationships.go +++ b/x/profiles/client/cli/cli_relationships.go @@ -4,6 +4,8 @@ import ( "context" "fmt" + subspacestypes "github.com/desmos-labs/desmos/v2/x/subspaces/types" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" "github.com/cosmos/cosmos-sdk/client/tx" @@ -24,7 +26,12 @@ func GetCmdCreateRelationship() *cobra.Command { return err } - msg := types.NewMsgCreateRelationship(clientCtx.FromAddress.String(), args[0], args[1]) + subspaceID, err := subspacestypes.ParseSubspaceID(args[1]) + if err != nil { + return err + } + + msg := types.NewMsgCreateRelationship(clientCtx.FromAddress.String(), args[0], subspaceID) if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } @@ -50,7 +57,12 @@ func GetCmdDeleteRelationship() *cobra.Command { return err } - msg := types.NewMsgDeleteRelationship(clientCtx.FromAddress.String(), args[0], args[1]) + subspaceID, err := subspacestypes.ParseSubspaceID(args[1]) + if err != nil { + return err + } + + msg := types.NewMsgDeleteRelationship(clientCtx.FromAddress.String(), args[0], subspaceID) if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } @@ -76,12 +88,17 @@ func GetCmdBlockUser() *cobra.Command { return err } + subspaceID, err := subspacestypes.ParseSubspaceID(args[1]) + if err != nil { + return err + } + reason := "" if len(args) == 3 { reason = args[2] } - msg := types.NewMsgBlockUser(clientCtx.FromAddress.String(), args[0], reason, args[1]) + msg := types.NewMsgBlockUser(clientCtx.FromAddress.String(), args[0], reason, subspaceID) if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } @@ -107,7 +124,12 @@ func GetCmdUnblockUser() *cobra.Command { return err } - msg := types.NewMsgUnblockUser(clientCtx.FromAddress.String(), args[0], args[1]) + subspaceID, err := subspacestypes.ParseSubspaceID(args[1]) + if err != nil { + return err + } + + msg := types.NewMsgUnblockUser(clientCtx.FromAddress.String(), args[0], subspaceID) if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } @@ -141,9 +163,12 @@ func GetCmdQueryRelationships() *cobra.Command { user = args[0] } - var subspace string + var subspace uint64 if len(args) == 2 { - subspace = args[1] + subspace, err = subspacestypes.ParseSubspaceID(args[1]) + if err != nil { + return err + } } pageReq, err := client.ReadPageRequest(cmd.Flags()) @@ -187,9 +212,12 @@ func GetCmdQueryBlocks() *cobra.Command { user = args[0] } - var subspace string + var subspace uint64 if len(args) == 2 { - subspace = args[1] + subspace, err = subspacestypes.ParseSubspaceID(args[1]) + if err != nil { + return err + } } pageReq, err := client.ReadPageRequest(cmd.Flags()) diff --git a/x/profiles/client/cli/cli_relationships_test.go b/x/profiles/client/cli/cli_relationships_test.go index 7ab1a1435a..c66d3c99fb 100644 --- a/x/profiles/client/cli/cli_relationships_test.go +++ b/x/profiles/client/cli/cli_relationships_test.go @@ -34,7 +34,7 @@ func (s *IntegrationTestSuite) TestCmdQueryRelationships() { types.NewRelationship( "cosmos1ftkjv8njvkekk00ehwdfl5sst8zgdpenjfm4hs", "cosmos1zs70glquczqgt83g03jnvcqppu4jjj8yjxwlvh", - "", + 0, ), }, Pagination: &query.PageResponse{ @@ -70,7 +70,7 @@ func (s *IntegrationTestSuite) TestCmdQueryRelationships() { types.NewRelationship( "cosmos1ftkjv8njvkekk00ehwdfl5sst8zgdpenjfm4hs", "cosmos1zs70glquczqgt83g03jnvcqppu4jjj8yjxwlvh", - "", + 0, ), }, Pagination: &query.PageResponse{ @@ -123,7 +123,7 @@ func (s *IntegrationTestSuite) TestCmdQueryBlocks() { "cosmos1ftkjv8njvkekk00ehwdfl5sst8zgdpenjfm4hs", "cosmos1zs70glquczqgt83g03jnvcqppu4jjj8yjxwlvh", "Test block", - "", + 0, ), }, Pagination: &query.PageResponse{ @@ -160,7 +160,7 @@ func (s *IntegrationTestSuite) TestCmdQueryBlocks() { "cosmos1ftkjv8njvkekk00ehwdfl5sst8zgdpenjfm4hs", "cosmos1zs70glquczqgt83g03jnvcqppu4jjj8yjxwlvh", "Test block", - "", + 0, ), }, Pagination: &query.PageResponse{ diff --git a/x/profiles/client/cli/cli_test.go b/x/profiles/client/cli/cli_test.go index 32ea23a935..9b81df087c 100644 --- a/x/profiles/client/cli/cli_test.go +++ b/x/profiles/client/cli/cli_test.go @@ -121,14 +121,14 @@ func (s *IntegrationTestSuite) SetupSuite() { addr.String(), "cosmos1zs70glquczqgt83g03jnvcqppu4jjj8yjxwlvh", "Test block", - "", + 0, ), } profilesData.Relationships = []types.Relationship{ types.NewRelationship( addr.String(), "cosmos1zs70glquczqgt83g03jnvcqppu4jjj8yjxwlvh", - "", + 0, ), } profilesData.ApplicationLinks = []types.ApplicationLink{ diff --git a/x/profiles/keeper/common_test.go b/x/profiles/keeper/common_test.go index 09788032e5..41d4116cd8 100644 --- a/x/profiles/keeper/common_test.go +++ b/x/profiles/keeper/common_test.go @@ -4,6 +4,9 @@ import ( "testing" "time" + subspaceskeeper "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + subspacestypes "github.com/desmos-labs/desmos/v2/x/subspaces/types" + upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper" cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" @@ -51,6 +54,7 @@ type KeeperTestSuite struct { storeKey sdk.StoreKey k keeper.Keeper ak authkeeper.AccountKeeper + sk subspaceskeeper.Keeper paramsKeeper paramskeeper.Keeper stakingKeeper stakingkeeper.Keeper upgradeKeeper upgradekeeper.Keeper @@ -87,7 +91,10 @@ type TestData struct { func (suite *KeeperTestSuite) SetupTest() { // Define the store keys - keys := sdk.NewKVStoreKeys(types.StoreKey, authtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, capabilitytypes.StoreKey) + keys := sdk.NewKVStoreKeys( + types.StoreKey, subspacestypes.StoreKey, + authtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, capabilitytypes.StoreKey, + ) tKeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -139,11 +146,13 @@ func (suite *KeeperTestSuite) SetupTest() { scopedIBCKeeper, ) + suite.sk = subspaceskeeper.NewKeeper(suite.cdc, keys[subspacestypes.StoreKey]) suite.k = keeper.NewKeeper( suite.cdc, suite.storeKey, suite.paramsKeeper.Subspace(types.DefaultParamsSpace), suite.ak, + suite.sk, suite.IBCKeeper.ChannelKeeper, &suite.IBCKeeper.PortKeeper, scopedProfilesKeeper, diff --git a/x/profiles/keeper/expected_keeper.go b/x/profiles/keeper/expected_keeper.go new file mode 100644 index 0000000000..0b0f59a425 --- /dev/null +++ b/x/profiles/keeper/expected_keeper.go @@ -0,0 +1,16 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + subspacestypes "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// SubspacesKeeper represents the expected keeper used to interact with subspaces +type SubspacesKeeper interface { + // HasSubspace tells if the subspace with the given id exists + HasSubspace(ctx sdk.Context, subspaceID uint64) bool + + // GetAllSubspaces returns all the subspaces stored + GetAllSubspaces(ctx sdk.Context) []subspacestypes.Subspace +} diff --git a/x/profiles/keeper/genesis_test.go b/x/profiles/keeper/genesis_test.go index 77f65297ef..83ead876b1 100644 --- a/x/profiles/keeper/genesis_test.go +++ b/x/profiles/keeper/genesis_test.go @@ -58,12 +58,12 @@ func (suite *KeeperTestSuite) Test_ExportGenesis() { types.NewRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), } for _, rel := range relationships { @@ -75,13 +75,13 @@ func (suite *KeeperTestSuite) Test_ExportGenesis() { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewUserBlock( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), } for _, block := range blocks { @@ -151,12 +151,12 @@ func (suite *KeeperTestSuite) Test_ExportGenesis() { types.NewRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), }, []types.UserBlock{ @@ -164,13 +164,13 @@ func (suite *KeeperTestSuite) Test_ExportGenesis() { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewUserBlock( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), }, types.NewParams( @@ -268,8 +268,8 @@ func (suite *KeeperTestSuite) Test_InitGenesis() { genesis: types.NewGenesisState( nil, []types.Relationship{ - types.NewRelationship("creator", "recipient", "subspace"), - types.NewRelationship("creator", "recipient", "subspace"), + types.NewRelationship("creator", "recipient", 0), + types.NewRelationship("creator", "recipient", 0), }, []types.UserBlock{}, types.DefaultParams(), @@ -285,8 +285,8 @@ func (suite *KeeperTestSuite) Test_InitGenesis() { nil, []types.Relationship{}, []types.UserBlock{ - types.NewUserBlock("blocker", "blocked", "reason", "subspace"), - types.NewUserBlock("blocker", "blocked", "reason", "subspace"), + types.NewUserBlock("blocker", "blocked", "reason", 0), + types.NewUserBlock("blocker", "blocked", "reason", 0), }, types.DefaultParams(), "profiles-port-id", @@ -351,12 +351,12 @@ func (suite *KeeperTestSuite) Test_InitGenesis() { types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), }, []types.UserBlock{ @@ -364,13 +364,13 @@ func (suite *KeeperTestSuite) Test_InitGenesis() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewUserBlock( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), }, types.NewParams( @@ -427,12 +427,12 @@ func (suite *KeeperTestSuite) Test_InitGenesis() { types.NewRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), } suite.Require().Equal(relationships, suite.k.GetAllRelationships(ctx)) @@ -442,13 +442,13 @@ func (suite *KeeperTestSuite) Test_InitGenesis() { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewUserBlock( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), } suite.Require().Equal(blocks, suite.k.GetAllUsersBlocks(ctx)) diff --git a/x/profiles/keeper/grpc_query.go b/x/profiles/keeper/grpc_query.go index 6a4d6753b4..a7ccb1007c 100644 --- a/x/profiles/keeper/grpc_query.go +++ b/x/profiles/keeper/grpc_query.go @@ -91,7 +91,12 @@ func (k Keeper) Relationships(ctx context.Context, request *types.QueryRelations // Get user relationships prefix store store := sdkCtx.KVStore(k.storeKey) - relsStore := prefix.NewStore(store, types.UserRelationshipsSubspacePrefix(request.User, request.SubspaceId)) + + storePrefix := types.UserRelationshipsPrefix(request.User) + if request.User != "" { + storePrefix = types.UserRelationshipsSubspacePrefix(request.User, request.SubspaceId) + } + relsStore := prefix.NewStore(store, storePrefix) // Get paginated user relationships pageRes, err := query.Paginate(relsStore, request.Pagination, func(key []byte, value []byte) error { @@ -118,7 +123,12 @@ func (k Keeper) Blocks(ctx context.Context, request *types.QueryBlocksRequest) ( // Get user blocks prefix store store := sdkCtx.KVStore(k.storeKey) - userBlocksStore := prefix.NewStore(store, types.BlockerSubspacePrefix(request.User, request.SubspaceId)) + + storePrefix := types.BlockerPrefix(request.User) + if request.User != "" { + storePrefix = types.BlockerSubspacePrefix(request.User, request.SubspaceId) + } + userBlocksStore := prefix.NewStore(store, storePrefix) // Get paginated user blocks pageRes, err := query.Paginate(userBlocksStore, request.Pagination, func(key []byte, value []byte) error { diff --git a/x/profiles/keeper/grpc_query_test.go b/x/profiles/keeper/grpc_query_test.go index 7803589e42..7441949f0b 100644 --- a/x/profiles/keeper/grpc_query_test.go +++ b/x/profiles/keeper/grpc_query_test.go @@ -442,7 +442,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Relationships() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.SaveRelationship(ctx, relationship)) @@ -450,7 +450,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Relationships() { relationship = types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19mj6dkd85m84gxvf8d929w572z5h9q0u8d8wpa", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.SaveRelationship(ctx, relationship)) @@ -461,12 +461,12 @@ func (suite *KeeperTestSuite) TestQueryServer_Relationships() { types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19mj6dkd85m84gxvf8d929w572z5h9q0u8d8wpa", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), }, }, @@ -476,7 +476,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Relationships() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.SaveRelationship(ctx, relationship)) @@ -484,7 +484,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Relationships() { relationship = types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19mj6dkd85m84gxvf8d929w572z5h9q0u8d8wpa", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.SaveRelationship(ctx, relationship)) @@ -498,7 +498,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Relationships() { types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19mj6dkd85m84gxvf8d929w572z5h9q0u8d8wpa", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), }, }, @@ -539,7 +539,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Blocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason1", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.SaveUserBlock(ctx, block)) @@ -548,7 +548,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Blocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19mj6dkd85m84gxvf8d929w572z5h9q0u8d8wpa", "reason2", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.SaveUserBlock(ctx, block)) @@ -560,13 +560,13 @@ func (suite *KeeperTestSuite) TestQueryServer_Blocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19mj6dkd85m84gxvf8d929w572z5h9q0u8d8wpa", "reason2", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), types.NewUserBlock( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason1", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), }, }, @@ -577,7 +577,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Blocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason1", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.SaveUserBlock(ctx, block)) @@ -586,7 +586,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Blocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19mj6dkd85m84gxvf8d929w572z5h9q0u8d8wpa", "reason2", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.SaveUserBlock(ctx, block)) @@ -601,7 +601,7 @@ func (suite *KeeperTestSuite) TestQueryServer_Blocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19mj6dkd85m84gxvf8d929w572z5h9q0u8d8wpa", "reason2", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), }, }, diff --git a/x/profiles/keeper/invariants.go b/x/profiles/keeper/invariants.go index 7cc7df60e5..660e1df5f0 100644 --- a/x/profiles/keeper/invariants.go +++ b/x/profiles/keeper/invariants.go @@ -108,7 +108,7 @@ func formatOutputBlocks(invalidBlocks []types.UserBlock) (outputBlocks string) { outputBlocks = "The following list contains invalid user blocks:\n" for _, block := range invalidBlocks { outputBlocks += fmt.Sprintf( - "[Blocker]: %s, [Blocked]: %s, [Subspace]: %s\n", + "[Blocker]: %s, [Blocked]: %s, [Subspace]: %d\n", block.Blocker, block.Blocked, block.Subspace, ) } @@ -140,7 +140,7 @@ func formatOutputRelationships(relationships []types.Relationship) (output strin output = "The following list contains invalid relationships:\n" for _, relationship := range relationships { output += fmt.Sprintf( - "[Creator]: %s, [Recipient]: %s, [Subspace]: %s\n", + "[Creator]: %s, [Recipient]: %s, [Subspace]: %d\n", relationship.Creator, relationship.Recipient, relationship.Subspace, ) } diff --git a/x/profiles/keeper/invariants_test.go b/x/profiles/keeper/invariants_test.go index 800c82387c..f39a18fabf 100644 --- a/x/profiles/keeper/invariants_test.go +++ b/x/profiles/keeper/invariants_test.go @@ -52,7 +52,7 @@ func (suite *KeeperTestSuite) TestInvariants() { store: func(ctx sdk.Context) { store := ctx.KVStore(suite.storeKey) - block := types.NewUserBlock("blocker", "blocked", "reason", "subspace") + block := types.NewUserBlock("blocker", "blocked", "reason", 0) store.Set( types.UserBlockStoreKey(block.Blocker, block.Subspace, block.Blocked), suite.cdc.MustMarshal(&block), @@ -62,7 +62,7 @@ func (suite *KeeperTestSuite) TestInvariants() { expResponse: sdk.FormatInvariant(types.ModuleName, "invalid user blocks", fmt.Sprintf("%s%s", "The following list contains invalid user blocks:\n", - "[Blocker]: blocker, [Blocked]: blocked, [Subspace]: subspace\n", + "[Blocker]: blocker, [Blocked]: blocked, [Subspace]: 0\n", ), ), }, @@ -71,7 +71,7 @@ func (suite *KeeperTestSuite) TestInvariants() { store: func(ctx sdk.Context) { store := ctx.KVStore(suite.storeKey) - relationship := types.NewRelationship("creator", "recipient", "subspace") + relationship := types.NewRelationship("creator", "recipient", 0) store.Set( types.RelationshipsStoreKey(relationship.Creator, relationship.Subspace, relationship.Recipient), suite.cdc.MustMarshal(&relationship), @@ -81,7 +81,7 @@ func (suite *KeeperTestSuite) TestInvariants() { expResponse: sdk.FormatInvariant(types.ModuleName, "invalid relationships", fmt.Sprintf("%s%s", "The following list contains invalid relationships:\n", - "[Creator]: creator, [Recipient]: recipient, [Subspace]: subspace\n", + "[Creator]: creator, [Recipient]: recipient, [Subspace]: 0\n", ), ), }, diff --git a/x/profiles/keeper/keeper.go b/x/profiles/keeper/keeper.go index e8a36f4af0..a94da9b138 100644 --- a/x/profiles/keeper/keeper.go +++ b/x/profiles/keeper/keeper.go @@ -24,6 +24,7 @@ type Keeper struct { paramSubspace paramstypes.Subspace ak authkeeper.AccountKeeper + sk SubspacesKeeper channelKeeper types.ChannelKeeper portKeeper types.PortKeeper @@ -41,6 +42,7 @@ func NewKeeper( storeKey sdk.StoreKey, paramSpace paramstypes.Subspace, ak authkeeper.AccountKeeper, + sk SubspacesKeeper, channelKeeper types.ChannelKeeper, portKeeper types.PortKeeper, scopedKeeper types.ScopedKeeper, @@ -54,6 +56,7 @@ func NewKeeper( cdc: cdc, paramSubspace: paramSpace, ak: ak, + sk: sk, channelKeeper: channelKeeper, portKeeper: portKeeper, scopedKeeper: scopedKeeper, diff --git a/x/profiles/keeper/keeper_blocks.go b/x/profiles/keeper/keeper_blocks.go index 1ea6b0d4c6..5df338430a 100644 --- a/x/profiles/keeper/keeper_blocks.go +++ b/x/profiles/keeper/keeper_blocks.go @@ -60,13 +60,13 @@ func (k Keeper) GetAllUsersBlocks(ctx sdk.Context) []types.UserBlock { // IsUserBlocked tells if the given blocker has blocked the given blocked user func (k Keeper) IsUserBlocked(ctx sdk.Context, blocker, blocked string) bool { - return k.HasUserBlocked(ctx, blocker, blocked, "") + return k.HasUserBlocked(ctx, blocker, blocked, 0) } // HasUserBlocked returns true if the provided blocker has blocked the given user for the given subspace. // If the provided subspace is empty, all subspaces will be checked -func (k Keeper) HasUserBlocked(ctx sdk.Context, blocker, blocked, subspace string) bool { - if subspace != "" { +func (k Keeper) HasUserBlocked(ctx sdk.Context, blocker, blocked string, subspace uint64) bool { + if subspace != 0 { store := ctx.KVStore(k.storeKey) key := types.UserBlockStoreKey(blocker, subspace, blocked) @@ -76,7 +76,7 @@ func (k Keeper) HasUserBlocked(ctx sdk.Context, blocker, blocked, subspace strin blocks := k.GetUserBlocks(ctx, blocker) for _, block := range blocks { if block.Blocked == blocked { - return subspace == "" || block.Subspace == subspace + return subspace == 0 || block.Subspace == subspace } } @@ -84,12 +84,12 @@ func (k Keeper) HasUserBlocked(ctx sdk.Context, blocker, blocked, subspace strin } // DeleteUserBlock allows to the specified blocker to unblock the given blocked user. -func (k Keeper) DeleteUserBlock(ctx sdk.Context, blocker, blocked string, subspace string) error { +func (k Keeper) DeleteUserBlock(ctx sdk.Context, blocker, blocked string, subspace uint64) error { store := ctx.KVStore(k.storeKey) key := types.UserBlockStoreKey(blocker, subspace, blocked) if !store.Has(key) { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, - "block from %s towards %s for subspace %s not found", blocker, blocked, subspace) + "block from %s towards %s for subspace %d not found", blocker, blocked, subspace) } store.Delete(key) return nil diff --git a/x/profiles/keeper/keeper_blocks_test.go b/x/profiles/keeper/keeper_blocks_test.go index 16421d2562..f4b280ecb4 100644 --- a/x/profiles/keeper/keeper_blocks_test.go +++ b/x/profiles/keeper/keeper_blocks_test.go @@ -22,7 +22,7 @@ func (suite *KeeperTestSuite) TestKeeper_IsUserBlocked() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "test", - "", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -69,7 +69,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveUserBlock() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", "reason", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -79,7 +79,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveUserBlock() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", "reason", - "subspace", + 0, ), shouldErr: true, }, @@ -93,7 +93,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveUserBlock() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "reason", - "subspace", + 0, ), shouldErr: false, check: func(ctx sdk.Context) { @@ -103,7 +103,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveUserBlock() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "reason", - "subspace", + 0, ), blocks[0]) }, }, @@ -137,7 +137,7 @@ func (suite *KeeperTestSuite) TestKeeper_DeleteUserBlock() { store func(ctx sdk.Context) blocker string blocked string - subspace string + subspace uint64 shouldErr bool check func(ctx sdk.Context) }{ @@ -148,7 +148,7 @@ func (suite *KeeperTestSuite) TestKeeper_DeleteUserBlock() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "reason", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -158,7 +158,7 @@ func (suite *KeeperTestSuite) TestKeeper_DeleteUserBlock() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", "reason", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -166,7 +166,7 @@ func (suite *KeeperTestSuite) TestKeeper_DeleteUserBlock() { }, blocker: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", blocked: "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", - subspace: "subspace", + subspace: 0, shouldErr: false, check: func(ctx sdk.Context) { blocks := suite.k.GetUserBlocks(ctx, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47") @@ -180,7 +180,7 @@ func (suite *KeeperTestSuite) TestKeeper_DeleteUserBlock() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "reason", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -188,14 +188,14 @@ func (suite *KeeperTestSuite) TestKeeper_DeleteUserBlock() { }, blocker: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", blocked: "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - subspace: "subspace", + subspace: 0, shouldErr: false, }, { name: "deleting a user block that does not exist returns an error", blocker: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", blocked: "blocked", - subspace: "subspace", + subspace: 0, shouldErr: true, }, } @@ -236,7 +236,7 @@ func (suite *KeeperTestSuite) TestKeeper_GetUserBlocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", "reason", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -248,7 +248,7 @@ func (suite *KeeperTestSuite) TestKeeper_GetUserBlocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos10nsdxxdvy9qka3zv0lzw8z9cnu6kanld8jh773", "reason", - "subspace", + 0, ), }, }, @@ -286,7 +286,7 @@ func (suite *KeeperTestSuite) TestKeeper_GetAllUsersBlocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "reason", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -296,7 +296,7 @@ func (suite *KeeperTestSuite) TestKeeper_GetAllUsersBlocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", "reason", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -307,13 +307,13 @@ func (suite *KeeperTestSuite) TestKeeper_GetAllUsersBlocks() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "reason", - "subspace", + 0, ), types.NewUserBlock( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", "reason", - "subspace", + 0, ), }, }, @@ -343,7 +343,7 @@ func (suite *KeeperTestSuite) TestKeeper_HasUserBlocked() { store func(ctx sdk.Context) blocker string blocked string - subspace string + subspace uint64 expBlocked bool }{ { @@ -353,7 +353,7 @@ func (suite *KeeperTestSuite) TestKeeper_HasUserBlocked() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "reason", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -361,14 +361,14 @@ func (suite *KeeperTestSuite) TestKeeper_HasUserBlocked() { }, blocker: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", blocked: "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - subspace: "subspace", + subspace: 0, expBlocked: true, }, { name: "blocked user not found returns false", blocker: "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", blocked: "blocked", - subspace: "subspace_2", + subspace: 1, expBlocked: false, }, } diff --git a/x/profiles/keeper/keeper_relationships.go b/x/profiles/keeper/keeper_relationships.go index 1ba9bc2e4d..f38c1fe3bb 100644 --- a/x/profiles/keeper/keeper_relationships.go +++ b/x/profiles/keeper/keeper_relationships.go @@ -7,6 +7,11 @@ import ( "github.com/desmos-labs/desmos/v2/x/profiles/types" ) +// HasSubspace tells if the subspace with the given id exists +func (k Keeper) HasSubspace(ctx sdk.Context, subspaceID uint64) bool { + return k.sk.HasSubspace(ctx, subspaceID) +} + // SaveRelationship allows to store the given relationship returning an error if he's already present. // It requires the creator to have a profile. func (k Keeper) SaveRelationship(ctx sdk.Context, relationship types.Relationship) error { @@ -32,7 +37,7 @@ func (k Keeper) SaveRelationship(ctx sdk.Context, relationship types.Relationshi } // GetRelationship returns the relationship existing between the provided creator and recipient inside the given subspace -func (k Keeper) GetRelationship(ctx sdk.Context, creator, subspace, recipient string) (types.Relationship, bool) { +func (k Keeper) GetRelationship(ctx sdk.Context, creator string, subspace uint64, recipient string) (types.Relationship, bool) { store := ctx.KVStore(k.storeKey) key := types.RelationshipsStoreKey(creator, subspace, recipient) @@ -69,7 +74,7 @@ func (k Keeper) RemoveRelationship(ctx sdk.Context, relationship types.Relations key := types.RelationshipsStoreKey(relationship.Creator, relationship.Subspace, relationship.Recipient) if !store.Has(key) { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, - "relationship between %s and %s for subspace %s not found", + "relationship between %s and %s for subspace %d not found", relationship.Creator, relationship.Recipient, relationship.Subspace) } store.Delete(key) diff --git a/x/profiles/keeper/keeper_relationships_test.go b/x/profiles/keeper/keeper_relationships_test.go index 59b664974e..0846b25db8 100644 --- a/x/profiles/keeper/keeper_relationships_test.go +++ b/x/profiles/keeper/keeper_relationships_test.go @@ -21,7 +21,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveRelationship() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Recipient))) @@ -30,7 +30,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveRelationship() { relationship: types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ), shouldErr: true, }, @@ -43,7 +43,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveRelationship() { relationship: types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ), shouldErr: false, check: func(ctx sdk.Context) { @@ -51,7 +51,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveRelationship() { types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ), } suite.Require().Equal(expected, suite.k.GetAllRelationships(ctx)) @@ -63,7 +63,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveRelationship() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Recipient))) @@ -72,7 +72,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveRelationship() { relationship: types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace_2", + 1, ), shouldErr: false, }, @@ -82,7 +82,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveRelationship() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Recipient))) @@ -91,7 +91,7 @@ func (suite *KeeperTestSuite) TestKeeper_SaveRelationship() { relationship: types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", - "subspace_2", + 1, ), shouldErr: false, }, @@ -128,7 +128,7 @@ func (suite *KeeperTestSuite) TestKeeper_GetAllRelationships() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Recipient))) @@ -137,7 +137,7 @@ func (suite *KeeperTestSuite) TestKeeper_GetAllRelationships() { relationship = types.NewRelationship( "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Recipient))) @@ -147,12 +147,12 @@ func (suite *KeeperTestSuite) TestKeeper_GetAllRelationships() { types.NewRelationship( "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", - "subspace", + 0, ), types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ), }, }, @@ -189,7 +189,7 @@ func (suite *KeeperTestSuite) TestKeeper_GetUserRelationships() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Recipient))) @@ -200,7 +200,7 @@ func (suite *KeeperTestSuite) TestKeeper_GetUserRelationships() { types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ), }, }, @@ -238,7 +238,7 @@ func (suite *KeeperTestSuite) TestKeeper_RemoveRelationship() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Recipient))) @@ -247,7 +247,7 @@ func (suite *KeeperTestSuite) TestKeeper_RemoveRelationship() { relationship = types.NewRelationship( "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", - "subspace", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Recipient))) @@ -256,7 +256,7 @@ func (suite *KeeperTestSuite) TestKeeper_RemoveRelationship() { relationshipToDelete: types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ), shouldErr: false, check: func(ctx sdk.Context) { @@ -264,7 +264,7 @@ func (suite *KeeperTestSuite) TestKeeper_RemoveRelationship() { types.NewRelationship( "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", "cosmos1xcy3els9ua75kdm783c3qu0rfa2eplesldfevn", - "subspace", + 0, ), } suite.Require().Equal(expected, suite.k.GetAllRelationships(ctx)) @@ -275,7 +275,7 @@ func (suite *KeeperTestSuite) TestKeeper_RemoveRelationship() { relationshipToDelete: types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 0, ), shouldErr: true, }, diff --git a/x/profiles/keeper/msg_server_blocks.go b/x/profiles/keeper/msg_server_blocks.go index 57e82cf4a2..1405432111 100644 --- a/x/profiles/keeper/msg_server_blocks.go +++ b/x/profiles/keeper/msg_server_blocks.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" @@ -21,7 +22,7 @@ func (k msgServer) BlockUser(goCtx context.Context, msg *types.MsgBlockUser) (*t types.EventTypeBlockUser, sdk.NewAttribute(types.AttributeKeyUserBlockBlocker, msg.Blocker), sdk.NewAttribute(types.AttributeKeyUserBlockBlocked, msg.Blocked), - sdk.NewAttribute(types.AttributeKeySubspace, msg.Subspace), + sdk.NewAttribute(types.AttributeKeySubspace, fmt.Sprintf("%d", msg.Subspace)), sdk.NewAttribute(types.AttributeKeyUserBlockReason, msg.Reason), )) @@ -40,7 +41,7 @@ func (k msgServer) UnblockUser(goCtx context.Context, msg *types.MsgUnblockUser) types.EventTypeUnblockUser, sdk.NewAttribute(types.AttributeKeyUserBlockBlocker, msg.Blocker), sdk.NewAttribute(types.AttributeKeyUserBlockBlocked, msg.Blocked), - sdk.NewAttribute(types.AttributeKeySubspace, msg.Subspace), + sdk.NewAttribute(types.AttributeKeySubspace, fmt.Sprintf("%d", msg.Subspace)), )) return &types.MsgUnblockUserResponse{}, nil diff --git a/x/profiles/keeper/msg_server_blocks_test.go b/x/profiles/keeper/msg_server_blocks_test.go index 3ece25a3b0..4422f4ab98 100644 --- a/x/profiles/keeper/msg_server_blocks_test.go +++ b/x/profiles/keeper/msg_server_blocks_test.go @@ -25,7 +25,7 @@ func (suite *KeeperTestSuite) TestMsgServer_BlockUser() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -35,7 +35,7 @@ func (suite *KeeperTestSuite) TestMsgServer_BlockUser() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, ), shouldErr: true, }, @@ -49,7 +49,7 @@ func (suite *KeeperTestSuite) TestMsgServer_BlockUser() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, ), shouldErr: false, expEvents: sdk.Events{ @@ -57,7 +57,7 @@ func (suite *KeeperTestSuite) TestMsgServer_BlockUser() { types.EventTypeBlockUser, sdk.NewAttribute(types.AttributeKeyUserBlockBlocker, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"), sdk.NewAttribute(types.AttributeKeyUserBlockBlocked, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"), - sdk.NewAttribute(types.AttributeKeySubspace, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types.AttributeKeySubspace, "1"), sdk.NewAttribute(types.AttributeKeyUserBlockReason, "reason"), ), }, @@ -67,7 +67,7 @@ func (suite *KeeperTestSuite) TestMsgServer_BlockUser() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, ), } suite.Require().Equal(expected, suite.k.GetAllUsersBlocks(ctx)) @@ -113,8 +113,8 @@ func (suite *KeeperTestSuite) TestMsgServer_UnblockUser() { name: "invalid block returns error", msg: types.NewMsgUnblockUser( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "subspace", + "cosmos1cjf97gpzwmaf30", + 0, ), shouldErr: true, }, @@ -125,7 +125,7 @@ func (suite *KeeperTestSuite) TestMsgServer_UnblockUser() { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -134,7 +134,7 @@ func (suite *KeeperTestSuite) TestMsgServer_UnblockUser() { msg: types.NewMsgUnblockUser( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, ), shouldErr: false, expEvents: sdk.Events{ @@ -142,7 +142,7 @@ func (suite *KeeperTestSuite) TestMsgServer_UnblockUser() { types.EventTypeUnblockUser, sdk.NewAttribute(types.AttributeKeyUserBlockBlocker, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"), sdk.NewAttribute(types.AttributeKeyUserBlockBlocked, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"), - sdk.NewAttribute(types.AttributeKeySubspace, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types.AttributeKeySubspace, "1"), ), }, check: func(ctx sdk.Context) { diff --git a/x/profiles/keeper/msg_server_dtag_transfers_test.go b/x/profiles/keeper/msg_server_dtag_transfers_test.go index 58c5838dd2..ed9a6d7120 100644 --- a/x/profiles/keeper/msg_server_dtag_transfers_test.go +++ b/x/profiles/keeper/msg_server_dtag_transfers_test.go @@ -27,7 +27,7 @@ func (suite *KeeperTestSuite) TestMsgServer_RequestDTagTransfer() { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "This user has been blocked", - "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", + 1, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) diff --git a/x/profiles/keeper/msg_server_relationships.go b/x/profiles/keeper/msg_server_relationships.go index 9b71bfe4ce..89b3057e9c 100644 --- a/x/profiles/keeper/msg_server_relationships.go +++ b/x/profiles/keeper/msg_server_relationships.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -12,6 +13,11 @@ import ( func (k msgServer) CreateRelationship(goCtx context.Context, msg *types.MsgCreateRelationship) (*types.MsgCreateRelationshipResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) + // Check if the subspace exists + if !k.HasSubspace(ctx, msg.Subspace) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.Subspace) + } + // Check if the receiver has blocked the sender before if k.HasUserBlocked(ctx, msg.Receiver, msg.Sender, msg.Subspace) { return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "The user with address %s has blocked you", msg.Receiver) @@ -27,7 +33,7 @@ func (k msgServer) CreateRelationship(goCtx context.Context, msg *types.MsgCreat types.EventTypeRelationshipCreated, sdk.NewAttribute(types.AttributeRelationshipSender, msg.Sender), sdk.NewAttribute(types.AttributeRelationshipReceiver, msg.Receiver), - sdk.NewAttribute(types.AttributeRelationshipSubspace, msg.Subspace), + sdk.NewAttribute(types.AttributeRelationshipSubspace, fmt.Sprintf("%d", msg.Subspace)), )) return &types.MsgCreateRelationshipResponse{}, nil @@ -45,7 +51,7 @@ func (k msgServer) DeleteRelationship(goCtx context.Context, msg *types.MsgDelet types.EventTypeRelationshipsDeleted, sdk.NewAttribute(types.AttributeRelationshipSender, msg.User), sdk.NewAttribute(types.AttributeRelationshipReceiver, msg.Counterparty), - sdk.NewAttribute(types.AttributeRelationshipSubspace, msg.Subspace), + sdk.NewAttribute(types.AttributeRelationshipSubspace, fmt.Sprintf("%d", msg.Subspace)), )) return &types.MsgDeleteRelationshipResponse{}, nil diff --git a/x/profiles/keeper/msg_server_relationships_test.go b/x/profiles/keeper/msg_server_relationships_test.go index 0f46b48277..bac3c134f8 100644 --- a/x/profiles/keeper/msg_server_relationships_test.go +++ b/x/profiles/keeper/msg_server_relationships_test.go @@ -1,8 +1,12 @@ package keeper_test import ( + "time" + sdk "github.com/cosmos/cosmos-sdk/types" + subspacestypes "github.com/desmos-labs/desmos/v2/x/subspaces/types" + "github.com/desmos-labs/desmos/v2/testutil" "github.com/desmos-labs/desmos/v2/x/profiles/keeper" @@ -25,7 +29,7 @@ func (suite *KeeperTestSuite) TestMsgServer_CreateRelationship() { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "tc", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocker))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(block.Blocked))) @@ -34,7 +38,7 @@ func (suite *KeeperTestSuite) TestMsgServer_CreateRelationship() { msg: types.NewMsgCreateRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), shouldErr: true, }, @@ -44,7 +48,7 @@ func (suite *KeeperTestSuite) TestMsgServer_CreateRelationship() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Creator))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr(relationship.Recipient))) @@ -53,20 +57,29 @@ func (suite *KeeperTestSuite) TestMsgServer_CreateRelationship() { msg: types.NewMsgCreateRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), shouldErr: true, }, { name: "new relationship is stored correctly", store: func(ctx sdk.Context) { + suite.sk.SaveSubspace(ctx, subspacestypes.NewSubspace( + 0, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr("cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"))) suite.Require().NoError(suite.k.StoreProfile(ctx, testutil.ProfileFromAddr("cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"))) }, msg: types.NewMsgCreateRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), shouldErr: false, expEvents: sdk.Events{ @@ -74,7 +87,7 @@ func (suite *KeeperTestSuite) TestMsgServer_CreateRelationship() { types.EventTypeRelationshipCreated, sdk.NewAttribute(types.AttributeRelationshipSender, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"), sdk.NewAttribute(types.AttributeRelationshipReceiver, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns"), - sdk.NewAttribute(types.AttributeRelationshipSubspace, "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e"), + sdk.NewAttribute(types.AttributeRelationshipSubspace, "0"), ), }, check: func(ctx sdk.Context) { @@ -82,7 +95,7 @@ func (suite *KeeperTestSuite) TestMsgServer_CreateRelationship() { types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ), } suite.Require().Equal(expected, suite.k.GetAllRelationships(ctx)) @@ -129,7 +142,7 @@ func (suite *KeeperTestSuite) TestMsgServer_DeleteRelationship() { msg: types.NewMsgDeleteRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "other_subspace", + 2, ), shouldErr: true, }, @@ -140,7 +153,7 @@ func (suite *KeeperTestSuite) TestMsgServer_DeleteRelationship() { relationship := types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 1, ) store.Set( types.RelationshipsStoreKey(relationship.Creator, relationship.Subspace, relationship.Recipient), @@ -150,7 +163,7 @@ func (suite *KeeperTestSuite) TestMsgServer_DeleteRelationship() { msg: types.NewMsgDeleteRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x", - "subspace", + 1, ), shouldErr: false, expEvents: sdk.Events{ @@ -158,7 +171,7 @@ func (suite *KeeperTestSuite) TestMsgServer_DeleteRelationship() { types.EventTypeRelationshipsDeleted, sdk.NewAttribute(types.AttributeRelationshipSender, "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47"), sdk.NewAttribute(types.AttributeRelationshipReceiver, "cosmos19xz3mrvzvp9ymgmudhpukucg6668l5haakh04x"), - sdk.NewAttribute(types.AttributeRelationshipSubspace, "subspace"), + sdk.NewAttribute(types.AttributeRelationshipSubspace, "1"), ), }, check: func(ctx sdk.Context) { diff --git a/x/profiles/module.go b/x/profiles/module.go index 6a0697178e..7d22751646 100644 --- a/x/profiles/module.go +++ b/x/profiles/module.go @@ -98,6 +98,7 @@ func (AppModuleBasic) RegisterInterfaces(registry codectypes.InterfaceRegistry) type AppModule struct { AppModuleBasic keeper keeper.Keeper + sk keeper.SubspacesKeeper ak authkeeper.AccountKeeper bk bankkeeper.Keeper } @@ -124,12 +125,15 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { // NewAppModule creates a new AppModule Object func NewAppModule( - cdc codec.Codec, legacyAmino *codec.LegacyAmino, k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, + cdc codec.Codec, legacyAmino *codec.LegacyAmino, + k keeper.Keeper, sk keeper.SubspacesKeeper, + ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, ) AppModule { return AppModule{ AppModuleBasic: AppModuleBasic{cdc: cdc, legacyAmino: legacyAmino}, keeper: k, ak: ak, + sk: sk, bk: bk, } } @@ -222,5 +226,5 @@ func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) { // WeightedOperations returns the all the profiles module operations with their respective weights. func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation { - return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keeper, am.ak, am.bk) + return simulation.WeightedOperations(simState.AppParams, simState.Cdc, am.keeper, am.sk, am.ak, am.bk) } diff --git a/x/profiles/simulation/decoder.go b/x/profiles/simulation/decoder.go index 5aa1685bf2..2ffc1c5cb2 100644 --- a/x/profiles/simulation/decoder.go +++ b/x/profiles/simulation/decoder.go @@ -32,14 +32,14 @@ func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string { cdc.MustUnmarshal(kvA.Value, &relationshipA) cdc.MustUnmarshal(kvB.Value, &relationshipB) return fmt.Sprintf("Relationships A: %s\nRelationships B: %s\n", - relationshipA, relationshipB) + &relationshipA, &relationshipB) case bytes.HasPrefix(kvA.Key, types.UsersBlocksStorePrefix): var userBlockA, userBlockB types.UserBlock cdc.MustUnmarshal(kvA.Value, &userBlockA) cdc.MustUnmarshal(kvB.Value, &userBlockB) return fmt.Sprintf("User block A: %s\nUser block B: %s\n", - userBlockA, userBlockB) + &userBlockA, &userBlockB) case bytes.HasPrefix(kvA.Key, types.ChainLinksPrefix): var chainLinkA, chainLinkB types.ChainLink diff --git a/x/profiles/simulation/decoder_test.go b/x/profiles/simulation/decoder_test.go index 5418918a19..36bb4be519 100644 --- a/x/profiles/simulation/decoder_test.go +++ b/x/profiles/simulation/decoder_test.go @@ -32,14 +32,14 @@ func TestDecodeStore(t *testing.T) { relationship := types.NewRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, ) userBlock := types.NewUserBlock( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, ) kvPairs := kv.Pairs{Pairs: []kv.Pair{ @@ -57,7 +57,7 @@ func TestDecodeStore(t *testing.T) { { Key: types.RelationshipsStoreKey( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", ), Value: cdc.MustMarshal(&relationship), @@ -65,7 +65,7 @@ func TestDecodeStore(t *testing.T) { { Key: types.UserBlockStoreKey( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 1, "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", ), Value: cdc.MustMarshal(&userBlock), @@ -78,8 +78,8 @@ func TestDecodeStore(t *testing.T) { }{ {"DTags", fmt.Sprintf("DTagAddressA: %s\nDTagAddressB: %s\n", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns")}, {"DTag transfer request", fmt.Sprintf("RequestA: %s\nRequestB: %s\n", request, request)}, - {"Relationship", fmt.Sprintf("Relationships A: %s\nRelationships B: %s\n", relationship, relationship)}, - {"User block", fmt.Sprintf("User block A: %s\nUser block B: %s\n", userBlock, userBlock)}, + {"Relationship", fmt.Sprintf("Relationships A: %s\nRelationships B: %s\n", &relationship, &relationship)}, + {"User block", fmt.Sprintf("User block A: %s\nUser block B: %s\n", &userBlock, &userBlock)}, {"other", ""}, } diff --git a/x/profiles/simulation/genesis.go b/x/profiles/simulation/genesis.go index 50b451bc0f..4a2020c087 100644 --- a/x/profiles/simulation/genesis.go +++ b/x/profiles/simulation/genesis.go @@ -5,6 +5,9 @@ package simulation import ( "fmt" + subspacessim "github.com/desmos-labs/desmos/v2/x/subspaces/simulation" + subspacestypes "github.com/desmos-labs/desmos/v2/x/subspaces/types" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" @@ -38,10 +41,16 @@ func RandomizedGenState(simsState *module.SimulationState) { simsState.GenState[authtypes.ModuleName] = bz // Create and set profiles state + var subspacesState subspacestypes.GenesisState + err = simsState.Cdc.UnmarshalJSON(simsState.GenState[subspacestypes.ModuleName], &subspacesState) + if err != nil { + panic(err) + } + profileGenesis := types.NewGenesisState( randomDTagTransferRequests(profiles, simsState, simsState.Rand.Intn(profilesNumber)), - randomRelationships(profiles, simsState, simsState.Rand.Intn(profilesNumber)), - randomUsersBlocks(profiles, simsState, simsState.Rand.Intn(profilesNumber)), + randomRelationships(profiles, subspacesState.Subspaces, simsState, simsState.Rand.Intn(profilesNumber)), + randomUsersBlocks(profiles, subspacesState.Subspaces, simsState, simsState.Rand.Intn(profilesNumber)), types.NewParams( RandomNicknameParams(simsState.Rand), RandomDTagParams(simsState.Rand), @@ -136,7 +145,7 @@ func containsDTagTransferRequest(slice []types.DTagTransferRequest, request type // randomRelationships returns randomly generated genesis relationships and their associated users - IDs map func randomRelationships( - profiles []*types.Profile, simState *module.SimulationState, number int, + profiles []*types.Profile, subspaces []subspacestypes.Subspace, simState *module.SimulationState, number int, ) []types.Relationship { relationships := make([]types.Relationship, number) for index := 0; index < number; { @@ -148,10 +157,11 @@ func randomRelationships( continue } + subspace, _ := subspacessim.RandomSubspace(simState.Rand, subspaces) relationship := types.NewRelationship( profile1.GetAddress().String(), profile2.GetAddress().String(), - RandomSubspace(simState.Rand), + subspace.ID, ) if !containsRelationship(relationships, relationship) { @@ -178,7 +188,7 @@ func containsRelationship(slice []types.Relationship, relationship types.Relatio // randomUsersBlocks func randomUsersBlocks( - profiles []*types.Profile, simState *module.SimulationState, number int, + profiles []*types.Profile, subspaces []subspacestypes.Subspace, simState *module.SimulationState, number int, ) []types.UserBlock { usersBlocks := make([]types.UserBlock, number) for index := 0; index < number; { @@ -190,11 +200,12 @@ func randomUsersBlocks( continue } + subspace, _ := subspacessim.RandomSubspace(simState.Rand, subspaces) block := types.NewUserBlock( profile1.GetAddress().String(), profile2.GetAddress().String(), "reason", - RandomSubspace(simState.Rand), + subspace.ID, ) if !containsUserBlock(usersBlocks, block) { diff --git a/x/profiles/simulation/operations.go b/x/profiles/simulation/operations.go index 42ee9353f5..f1bef34629 100644 --- a/x/profiles/simulation/operations.go +++ b/x/profiles/simulation/operations.go @@ -35,7 +35,7 @@ const ( // WeightedOperations returns all the operations from the module with their respective weights func WeightedOperations( appParams simtypes.AppParams, cdc codec.JSONCodec, - k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, + k keeper.Keeper, sk keeper.SubspacesKeeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, ) sim.WeightedOperations { var weightMsgSaveProfile int appParams.GetOrGenerate(cdc, OpWeightMsgSaveProfile, &weightMsgSaveProfile, nil, @@ -134,7 +134,7 @@ func WeightedOperations( ), sim.NewWeightedOperation( weightMsgCreateRelationship, - SimulateMsgCreateRelationship(k, ak, bk), + SimulateMsgCreateRelationship(k, sk, ak, bk), ), sim.NewWeightedOperation( weightMsgDeleteRelationship, diff --git a/x/profiles/simulation/operations_relationships.go b/x/profiles/simulation/operations_relationships.go index 8afbebbcf4..5fec43a213 100644 --- a/x/profiles/simulation/operations_relationships.go +++ b/x/profiles/simulation/operations_relationships.go @@ -5,6 +5,8 @@ package simulation import ( "math/rand" + subspacessim "github.com/desmos-labs/desmos/v2/x/subspaces/simulation" + "github.com/desmos-labs/desmos/v2/testutil/simtesting" "github.com/desmos-labs/desmos/v2/x/profiles/keeper" @@ -21,14 +23,14 @@ import ( // SimulateMsgCreateRelationship tests and runs a single msg create relationships func SimulateMsgCreateRelationship( - k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, + k keeper.Keeper, sk keeper.SubspacesKeeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, ) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, ) (OperationMsg simtypes.OperationMsg, futureOps []simtypes.FutureOperation, err error) { - acc, relationship, skip := randomRelationshipFields(r, ctx, accs, k) + acc, relationship, skip := randomRelationshipFields(r, ctx, accs, k, sk) if skip { return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgCreateRelationship"), nil, nil } @@ -45,7 +47,7 @@ func SimulateMsgCreateRelationship( // randomRelationshipFields returns random relationships fields func randomRelationshipFields( - r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, sk keeper.SubspacesKeeper, ) (simtypes.Account, types.Relationship, bool) { if len(accs) == 0 { return simtypes.Account{}, types.Relationship{}, true @@ -54,7 +56,9 @@ func randomRelationshipFields( // Get random accounts sender, _ := simtypes.RandomAcc(r, accs) receiver, _ := simtypes.RandomAcc(r, accs) - subspace := RandomSubspace(r) + + subspaces := sk.GetAllSubspaces(ctx) + subspace, _ := subspacessim.RandomSubspace(r, subspaces) // Skip if the send and receiver are equals if sender.Equals(receiver) { @@ -72,11 +76,11 @@ func randomRelationshipFields( } // Skip if the receiver has block the sender - if k.HasUserBlocked(ctx, receiver.Address.String(), sender.Address.String(), subspace) { + if k.HasUserBlocked(ctx, receiver.Address.String(), sender.Address.String(), subspace.ID) { return simtypes.Account{}, types.Relationship{}, true } - rel := types.NewRelationship(sender.Address.String(), receiver.Address.String(), subspace) + rel := types.NewRelationship(sender.Address.String(), receiver.Address.String(), subspace.ID) // Skip if relationships already exists relationships := k.GetUserRelationships(ctx, sender.Address.String()) @@ -117,9 +121,9 @@ func SimulateMsgDeleteRelationship( // randomDeleteRelationshipFields returns random delete relationships fields func randomDeleteRelationshipFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, -) (user simtypes.Account, counterparty string, subspace string, skip bool) { +) (user simtypes.Account, counterparty string, subspace uint64, skip bool) { if len(accs) == 0 { - return simtypes.Account{}, "", "", true + return simtypes.Account{}, "", 0, true } // Get a random account @@ -138,7 +142,7 @@ func randomDeleteRelationshipFields( // Skip the test if the user has no relationships if len(outgoingRelationships) == 0 { - return simtypes.Account{}, "", "", true + return simtypes.Account{}, "", 0, true } // Get a random relationship diff --git a/x/profiles/simulation/operations_user_blocks.go b/x/profiles/simulation/operations_user_blocks.go index 23c322739b..2e2321551b 100644 --- a/x/profiles/simulation/operations_user_blocks.go +++ b/x/profiles/simulation/operations_user_blocks.go @@ -36,7 +36,7 @@ func SimulateMsgBlockUser( acc.Address.String(), blocked.String(), "reason", - "", + 0, ) err = simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{acc.PrivKey}) if err != nil { @@ -98,7 +98,7 @@ func SimulateMsgUnblockUser( msg := types.NewMsgUnblockUser( acc.Address.String(), userBlock.Blocked, - "4e188d9c17150037d5199bbdb91ae1eb2a78a15aca04cb35530cccb81494b36e", + 0, ) err = simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{acc.PrivKey}) if err != nil { diff --git a/x/profiles/types/genesis.go b/x/profiles/types/genesis.go index 3a9124f2b7..68bf988772 100644 --- a/x/profiles/types/genesis.go +++ b/x/profiles/types/genesis.go @@ -44,7 +44,7 @@ func ValidateGenesis(data *GenesisState) error { for _, rel := range data.Relationships { if containDuplicates(data.Relationships, rel) { - return fmt.Errorf("duplicated relationship: %s", rel) + return fmt.Errorf("duplicated relationship: %s", &rel) } err = rel.Validate() diff --git a/x/profiles/types/genesis_test.go b/x/profiles/types/genesis_test.go index 09b99bf36e..1ddb163b10 100644 --- a/x/profiles/types/genesis_test.go +++ b/x/profiles/types/genesis_test.go @@ -68,12 +68,12 @@ func TestValidateGenesis(t *testing.T) { types.NewRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "", - "", + 0, ), types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "subspace", + "cosmos1y54exmx84cqtasv", + 1, ), }, []types.UserBlock{ @@ -81,13 +81,13 @@ func TestValidateGenesis(t *testing.T) { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "", + 0, ), types.NewUserBlock( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "reason", - "", + 0, ), }, types.DefaultParams(), @@ -105,12 +105,12 @@ func TestValidateGenesis(t *testing.T) { types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "", + 0, ), types.NewRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "", + 0, ), }, []types.UserBlock{ @@ -118,7 +118,7 @@ func TestValidateGenesis(t *testing.T) { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "", "reason", - "", + 0, ), }, types.DefaultParams(), @@ -136,12 +136,12 @@ func TestValidateGenesis(t *testing.T) { types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "", + 0, ), types.NewRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "", + 0, ), }, []types.UserBlock{ @@ -149,7 +149,7 @@ func TestValidateGenesis(t *testing.T) { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "reason", - "", + 0, ), }, types.DefaultParams(), @@ -228,12 +228,12 @@ func TestValidateGenesis(t *testing.T) { types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "", + 0, ), types.NewRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "", + 0, ), }, []types.UserBlock{ @@ -241,13 +241,13 @@ func TestValidateGenesis(t *testing.T) { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "reason", - "", + 0, ), types.NewUserBlock( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "reason", - "", + 0, ), }, types.DefaultParams(), diff --git a/x/profiles/types/keys.go b/x/profiles/types/keys.go index b9c6365135..e09cffc2fb 100644 --- a/x/profiles/types/keys.go +++ b/x/profiles/types/keys.go @@ -1,6 +1,10 @@ package types -import "strings" +import ( + "strings" + + subspacestypes "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) // DONTCOVER @@ -71,12 +75,12 @@ func UserRelationshipsPrefix(user string) []byte { // UserRelationshipsSubspacePrefix returns the prefix used to store all the relationships created by the user // with the given address for the subspace having the given id -func UserRelationshipsSubspacePrefix(user, subspace string) []byte { - return append(UserRelationshipsPrefix(user), []byte(subspace)...) +func UserRelationshipsSubspacePrefix(user string, subspace uint64) []byte { + return append(UserRelationshipsPrefix(user), subspacestypes.GetSubspaceIDBytes(subspace)...) } // RelationshipsStoreKey returns the store key used to store the relationships containing the given data -func RelationshipsStoreKey(user, subspace, recipient string) []byte { +func RelationshipsStoreKey(user string, subspace uint64, recipient string) []byte { return append(UserRelationshipsSubspacePrefix(user, subspace), []byte(recipient)...) } @@ -87,13 +91,13 @@ func BlockerPrefix(blocker string) []byte { // BlockerSubspacePrefix returns the store prefix used to store the blocks that the given blocker // has created inside the specified subspace -func BlockerSubspacePrefix(blocker string, subspace string) []byte { - return append(BlockerPrefix(blocker), []byte(subspace)...) +func BlockerSubspacePrefix(blocker string, subspace uint64) []byte { + return append(BlockerPrefix(blocker), subspacestypes.GetSubspaceIDBytes(subspace)...) } // UserBlockStoreKey returns the store key used to save the block made by the given blocker, // inside the specified subspace and towards the given blocked user -func UserBlockStoreKey(blocker string, subspace string, blockedUser string) []byte { +func UserBlockStoreKey(blocker string, subspace uint64, blockedUser string) []byte { return append(BlockerSubspacePrefix(blocker, subspace), []byte(blockedUser)...) } diff --git a/x/profiles/types/models_relationships.go b/x/profiles/types/models_relationships.go index d51b335d4c..283b4dd023 100644 --- a/x/profiles/types/models_relationships.go +++ b/x/profiles/types/models_relationships.go @@ -8,16 +8,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// IsValidSubspace tell whether the given subspace ID is valid or not. -// NOTE: Currently we only support the empty subspace which identifies the generic Desmos subspace that can be used -// to block users on every subspace -func IsValidSubspace(subspace string) bool { - // TODO: Change with uint64 - return subspace == "" -} - // NewRelationship returns a new relationships with the given recipient and subspace -func NewRelationship(creator string, recipient string, subspace string) Relationship { +func NewRelationship(creator string, recipient string, subspace uint64) Relationship { return Relationship{ Creator: creator, Recipient: recipient, @@ -41,10 +33,6 @@ func (r Relationship) Validate() error { return fmt.Errorf("creator and recipient cannot be the same user") } - if !IsValidSubspace(r.Subspace) { - return fmt.Errorf("invalid subspace") - } - return nil } @@ -65,7 +53,7 @@ func MustUnmarshalRelationship(cdc codec.BinaryCodec, bz []byte) Relationship { // NewUserBlock returns a new object representing the fact that one user has blocked another one // for a specific reason on the given subspace. -func NewUserBlock(blocker, blocked string, reason, subspace string) UserBlock { +func NewUserBlock(blocker, blocked string, reason string, subspace uint64) UserBlock { return UserBlock{ Blocker: blocker, Blocked: blocked, @@ -88,10 +76,6 @@ func (ub UserBlock) Validate() error { return fmt.Errorf("blocker and blocked addresses cannot be equals") } - if !IsValidSubspace(ub.Subspace) { - return fmt.Errorf("invalid subspace") - } - return nil } diff --git a/x/profiles/types/models_relationships.pb.go b/x/profiles/types/models_relationships.pb.go index ec69626c94..e57a210789 100644 --- a/x/profiles/types/models_relationships.pb.go +++ b/x/profiles/types/models_relationships.pb.go @@ -31,7 +31,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type Relationship struct { Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` Recipient string `protobuf:"bytes,2,opt,name=recipient,proto3" json:"recipient,omitempty" yaml:"recipient"` - Subspace string `protobuf:"bytes,3,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` + Subspace uint64 `protobuf:"varint,3,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` } func (m *Relationship) Reset() { *m = Relationship{} } @@ -81,11 +81,11 @@ func (m *Relationship) GetRecipient() string { return "" } -func (m *Relationship) GetSubspace() string { +func (m *Relationship) GetSubspace() uint64 { if m != nil { return m.Subspace } - return "" + return 0 } // UserBlock represents the fact that the Blocker has blocked the given Blocked @@ -99,7 +99,7 @@ type UserBlock struct { Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty" yaml:"reason"` // Subspace contains the ID of the subspace inside which the user should be // blocked - Subspace string `protobuf:"bytes,4,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` + Subspace uint64 `protobuf:"varint,4,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` } func (m *UserBlock) Reset() { *m = UserBlock{} } @@ -156,11 +156,11 @@ func (m *UserBlock) GetReason() string { return "" } -func (m *UserBlock) GetSubspace() string { +func (m *UserBlock) GetSubspace() uint64 { if m != nil { return m.Subspace } - return "" + return 0 } func init() { @@ -173,32 +173,32 @@ func init() { } var fileDescriptor_47c7d48489f1a7d0 = []byte{ - // 395 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0xbf, 0x4e, 0xeb, 0x30, - 0x18, 0xc5, 0xeb, 0x7b, 0xaf, 0x7a, 0xdb, 0xe8, 0xfe, 0x81, 0x50, 0x89, 0xd2, 0x21, 0x41, 0x9e, - 0x40, 0x82, 0x98, 0x96, 0xad, 0x63, 0x57, 0xb6, 0x48, 0x2c, 0x2c, 0x95, 0x93, 0xb8, 0xa9, 0x55, - 0x27, 0x8e, 0x6c, 0xb7, 0xa2, 0x6f, 0xc1, 0xc8, 0xd8, 0x9d, 0x17, 0x61, 0x41, 0xea, 0xc8, 0x14, - 0xa1, 0x76, 0x61, 0xce, 0x13, 0xa0, 0x24, 0x4e, 0xcb, 0x3f, 0x09, 0xb1, 0x7d, 0x5f, 0xce, 0xef, - 0xc4, 0xe7, 0xe8, 0x33, 0x7a, 0x01, 0x91, 0x11, 0x97, 0x28, 0x11, 0x7c, 0x44, 0x19, 0x91, 0x68, - 0xd6, 0xf5, 0x88, 0xc2, 0x5d, 0x14, 0xf1, 0x80, 0x30, 0x39, 0x14, 0x84, 0x61, 0x45, 0x79, 0x2c, - 0xc7, 0x34, 0x91, 0x4e, 0x22, 0xb8, 0xe2, 0xe6, 0x7e, 0xe9, 0x71, 0x2a, 0x8f, 0xa3, 0x3d, 0x9d, - 0x56, 0xc8, 0x43, 0x5e, 0x30, 0x28, 0x9f, 0x4a, 0xbc, 0x73, 0x10, 0x72, 0x1e, 0x32, 0x82, 0x8a, - 0xcd, 0x9b, 0x8e, 0x10, 0x8e, 0xe7, 0x5a, 0xb2, 0xdf, 0x4b, 0x8a, 0x46, 0x44, 0x2a, 0x1c, 0x25, - 0x95, 0xd7, 0xe7, 0xf9, 0x53, 0xc3, 0xf2, 0xa7, 0xe5, 0xa2, 0xa5, 0xb3, 0x2f, 0x92, 0xfb, 0x63, - 0x4c, 0xe3, 0x21, 0xa3, 0xf1, 0x44, 0x3b, 0xe0, 0x1d, 0x30, 0xfe, 0xb8, 0xaf, 0xfa, 0x98, 0x27, - 0xc6, 0x6f, 0x5f, 0x10, 0xac, 0xb8, 0x68, 0x83, 0x43, 0x70, 0xd4, 0x1c, 0x98, 0x59, 0x6a, 0xff, - 0x9b, 0xe3, 0x88, 0xf5, 0xa1, 0x16, 0xa0, 0x5b, 0x21, 0x66, 0xcf, 0x68, 0x0a, 0xe2, 0xd3, 0x84, - 0x92, 0x58, 0xb5, 0x7f, 0x14, 0x7c, 0x2b, 0x4b, 0xed, 0x9d, 0x92, 0xdf, 0x48, 0xd0, 0xdd, 0x62, - 0x26, 0x32, 0x1a, 0x72, 0xea, 0xc9, 0x04, 0xfb, 0xa4, 0xfd, 0xb3, 0xb0, 0xec, 0x65, 0xa9, 0xfd, - 0xbf, 0xb4, 0x54, 0x0a, 0x74, 0x37, 0x50, 0xbf, 0x71, 0xbb, 0xb0, 0xc1, 0xf3, 0xc2, 0x06, 0xf0, - 0x01, 0x18, 0xcd, 0x4b, 0x49, 0xc4, 0x80, 0x71, 0x7f, 0x92, 0x47, 0xf5, 0xf2, 0x81, 0x7c, 0x12, - 0x55, 0x0b, 0xd0, 0xad, 0x90, 0x2d, 0x1d, 0xe8, 0xa0, 0x1f, 0xe8, 0x60, 0x43, 0x07, 0xe6, 0xb1, - 0x51, 0x17, 0x04, 0x4b, 0x1e, 0xeb, 0x88, 0xbb, 0x59, 0x6a, 0xff, 0xad, 0x5a, 0xe5, 0xdf, 0xa1, - 0xab, 0x81, 0x37, 0x7d, 0x7e, 0x7d, 0xab, 0xcf, 0xe0, 0xe2, 0x7e, 0x65, 0x81, 0xe5, 0xca, 0x02, - 0x4f, 0x2b, 0x0b, 0xdc, 0xac, 0xad, 0xda, 0x72, 0x6d, 0xd5, 0x1e, 0xd7, 0x56, 0xed, 0xaa, 0x1b, - 0x52, 0x35, 0x9e, 0x7a, 0x8e, 0xcf, 0x23, 0x54, 0x1e, 0xf5, 0x94, 0x61, 0x4f, 0xea, 0x19, 0xcd, - 0x7a, 0xe8, 0x7a, 0x7b, 0x65, 0x35, 0x4f, 0x88, 0xf4, 0xea, 0xc5, 0x45, 0xcf, 0x5f, 0x02, 0x00, - 0x00, 0xff, 0xff, 0xd9, 0xf3, 0xfa, 0x2e, 0xbf, 0x02, 0x00, 0x00, + // 400 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x91, 0x3f, 0x8f, 0xda, 0x30, + 0x18, 0xc6, 0x71, 0x8b, 0x28, 0x89, 0xfa, 0x37, 0x45, 0x2a, 0x65, 0x48, 0x90, 0x27, 0x2a, 0xb5, + 0x71, 0xa1, 0x1b, 0x63, 0xd6, 0x6e, 0x91, 0xba, 0x74, 0x41, 0x4e, 0x62, 0x82, 0x85, 0x13, 0x47, + 0xb6, 0x41, 0xe5, 0x5b, 0x74, 0xbc, 0x91, 0xfd, 0xbe, 0xc8, 0x2d, 0x27, 0x31, 0xde, 0x14, 0x9d, + 0x60, 0xb9, 0x39, 0x9f, 0xe0, 0x94, 0xc4, 0x81, 0xfb, 0x27, 0x9d, 0x6e, 0x7b, 0xdf, 0x3c, 0xbf, + 0x27, 0x7e, 0x1e, 0xbd, 0xe6, 0x24, 0x22, 0x32, 0xe1, 0x12, 0x65, 0x82, 0xcf, 0x29, 0x23, 0x12, + 0xad, 0xc7, 0x01, 0x51, 0x78, 0x8c, 0x12, 0x1e, 0x11, 0x26, 0x67, 0x82, 0x30, 0xac, 0x28, 0x4f, + 0xe5, 0x82, 0x66, 0xd2, 0xcd, 0x04, 0x57, 0xdc, 0xfa, 0x52, 0x7b, 0xdc, 0xc6, 0xe3, 0x6a, 0xcf, + 0xa0, 0x17, 0xf3, 0x98, 0x57, 0x0c, 0x2a, 0xa7, 0x1a, 0x1f, 0x7c, 0x8d, 0x39, 0x8f, 0x19, 0x41, + 0xd5, 0x16, 0xac, 0xe6, 0x08, 0xa7, 0x1b, 0x2d, 0x39, 0x0f, 0x25, 0x45, 0x13, 0x22, 0x15, 0x4e, + 0xb2, 0xc6, 0x1b, 0xf2, 0xf2, 0xa9, 0x59, 0xfd, 0xd3, 0x7a, 0xd1, 0xd2, 0xcf, 0x67, 0x92, 0x87, + 0x0b, 0x4c, 0xd3, 0x19, 0xa3, 0xe9, 0x52, 0x3b, 0xe0, 0x39, 0x30, 0xdf, 0xfa, 0x77, 0xfa, 0x58, + 0xdf, 0xcd, 0x37, 0xa1, 0x20, 0x58, 0x71, 0xd1, 0x07, 0x43, 0x30, 0x32, 0x3c, 0xab, 0xc8, 0x9d, + 0xf7, 0x1b, 0x9c, 0xb0, 0x29, 0xd4, 0x02, 0xf4, 0x1b, 0xc4, 0x9a, 0x98, 0x86, 0x20, 0x21, 0xcd, + 0x28, 0x49, 0x55, 0xff, 0x55, 0xc5, 0xf7, 0x8a, 0xdc, 0xf9, 0x58, 0xf3, 0x47, 0x09, 0xfa, 0x27, + 0xcc, 0x42, 0x66, 0x57, 0xae, 0x02, 0x99, 0xe1, 0x90, 0xf4, 0x5f, 0x0f, 0xc1, 0xa8, 0xed, 0x7d, + 0x2e, 0x72, 0xe7, 0x43, 0x6d, 0x69, 0x14, 0xe8, 0x1f, 0xa1, 0x69, 0xf7, 0x6c, 0xeb, 0x80, 0x9b, + 0xad, 0x03, 0xe0, 0x25, 0x30, 0x8d, 0x3f, 0x92, 0x08, 0x8f, 0xf1, 0x70, 0x59, 0x46, 0x0d, 0xca, + 0x81, 0x3c, 0x11, 0x55, 0x0b, 0xd0, 0x6f, 0x90, 0x13, 0x1d, 0xe9, 0xa0, 0x8f, 0xe8, 0xe8, 0x48, + 0x47, 0xd6, 0x37, 0xb3, 0x23, 0x08, 0x96, 0x3c, 0xad, 0x22, 0x1a, 0xde, 0xa7, 0x22, 0x77, 0xde, + 0x35, 0xad, 0xca, 0xef, 0xd0, 0xd7, 0xc0, 0xbd, 0x3e, 0xed, 0x17, 0xf5, 0xf1, 0x7e, 0x5f, 0xec, + 0x6d, 0xb0, 0xdb, 0xdb, 0xe0, 0x7a, 0x6f, 0x83, 0xff, 0x07, 0xbb, 0xb5, 0x3b, 0xd8, 0xad, 0xab, + 0x83, 0xdd, 0xfa, 0x3b, 0x8e, 0xa9, 0x5a, 0xac, 0x02, 0x37, 0xe4, 0x09, 0xaa, 0x8f, 0xfa, 0x83, + 0xe1, 0x40, 0xea, 0x19, 0xad, 0x27, 0xe8, 0xdf, 0xe9, 0xca, 0x6a, 0x93, 0x11, 0x19, 0x74, 0xaa, + 0x8b, 0xfe, 0xba, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x28, 0x6f, 0x12, 0x0c, 0xbf, 0x02, 0x00, 0x00, } func (this *Relationship) Equal(that interface{}) bool { @@ -284,12 +284,10 @@ func (m *Relationship) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Subspace) > 0 { - i -= len(m.Subspace) - copy(dAtA[i:], m.Subspace) - i = encodeVarintModelsRelationships(dAtA, i, uint64(len(m.Subspace))) + if m.Subspace != 0 { + i = encodeVarintModelsRelationships(dAtA, i, uint64(m.Subspace)) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x18 } if len(m.Recipient) > 0 { i -= len(m.Recipient) @@ -328,12 +326,10 @@ func (m *UserBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Subspace) > 0 { - i -= len(m.Subspace) - copy(dAtA[i:], m.Subspace) - i = encodeVarintModelsRelationships(dAtA, i, uint64(len(m.Subspace))) + if m.Subspace != 0 { + i = encodeVarintModelsRelationships(dAtA, i, uint64(m.Subspace)) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x20 } if len(m.Reason) > 0 { i -= len(m.Reason) @@ -384,9 +380,8 @@ func (m *Relationship) Size() (n int) { if l > 0 { n += 1 + l + sovModelsRelationships(uint64(l)) } - l = len(m.Subspace) - if l > 0 { - n += 1 + l + sovModelsRelationships(uint64(l)) + if m.Subspace != 0 { + n += 1 + sovModelsRelationships(uint64(m.Subspace)) } return n } @@ -409,9 +404,8 @@ func (m *UserBlock) Size() (n int) { if l > 0 { n += 1 + l + sovModelsRelationships(uint64(l)) } - l = len(m.Subspace) - if l > 0 { - n += 1 + l + sovModelsRelationships(uint64(l)) + if m.Subspace != 0 { + n += 1 + sovModelsRelationships(uint64(m.Subspace)) } return n } @@ -516,10 +510,10 @@ func (m *Relationship) Unmarshal(dAtA []byte) error { m.Recipient = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) } - var stringLen uint64 + m.Subspace = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModelsRelationships @@ -529,24 +523,11 @@ func (m *Relationship) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Subspace |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthModelsRelationships - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthModelsRelationships - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subspace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipModelsRelationships(dAtA[iNdEx:]) @@ -694,10 +675,10 @@ func (m *UserBlock) Unmarshal(dAtA []byte) error { m.Reason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) } - var stringLen uint64 + m.Subspace = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModelsRelationships @@ -707,24 +688,11 @@ func (m *UserBlock) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Subspace |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthModelsRelationships - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthModelsRelationships - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subspace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipModelsRelationships(dAtA[iNdEx:]) diff --git a/x/profiles/types/models_relationships_test.go b/x/profiles/types/models_relationships_test.go index 47e5b71190..fc67e9a066 100644 --- a/x/profiles/types/models_relationships_test.go +++ b/x/profiles/types/models_relationships_test.go @@ -21,7 +21,7 @@ func TestRelationship_Validate(t *testing.T) { relationship: types.NewRelationship( "", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "", + 0, ), shouldErr: true, }, @@ -30,16 +30,7 @@ func TestRelationship_Validate(t *testing.T) { relationship: types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "", - "", - ), - shouldErr: true, - }, - { - name: "invalid subspace returns error", - relationship: types.NewRelationship( - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "subspace", + 0, ), shouldErr: true, }, @@ -48,7 +39,7 @@ func TestRelationship_Validate(t *testing.T) { relationship: types.NewRelationship( "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "", + 0, ), shouldErr: true, }, @@ -57,7 +48,7 @@ func TestRelationship_Validate(t *testing.T) { relationship: types.NewRelationship( "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "", + 0, ), shouldErr: false, }, @@ -79,7 +70,7 @@ func TestRelationship_Validate(t *testing.T) { func TestRelationshipMarshaling(t *testing.T) { cdc, _ := app.MakeCodecs() - relationship := types.NewRelationship("creator", "recipient_1", "subspace") + relationship := types.NewRelationship("creator", "recipient_1", 1) marshalled := types.MustMarshalRelationship(cdc, relationship) unmarshalled := types.MustUnmarshalRelationship(cdc, marshalled) require.Equal(t, relationship, unmarshalled) @@ -99,7 +90,7 @@ func TestUserBlock_Validate(t *testing.T) { "", "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", "reason", - "", + 0, ), shouldErr: true, }, @@ -109,7 +100,7 @@ func TestUserBlock_Validate(t *testing.T) { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "", "reason", - "", + 0, ), shouldErr: true, }, @@ -119,17 +110,7 @@ func TestUserBlock_Validate(t *testing.T) { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "reason", - "", - ), - shouldErr: true, - }, - { - name: "invalid subspace returns error", - userBlock: types.NewUserBlock( - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", - "reason", - "yeah", + 0, ), shouldErr: true, }, @@ -139,7 +120,7 @@ func TestUserBlock_Validate(t *testing.T) { "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "cosmos1s3nh6tafl4amaxkke9kdejhp09lk93g9ev39r4", "reason", - "", + 0, ), shouldErr: false, }, diff --git a/x/profiles/types/msgs_relationships.go b/x/profiles/types/msgs_relationships.go index be0fbcf7b8..3ace35e34c 100644 --- a/x/profiles/types/msgs_relationships.go +++ b/x/profiles/types/msgs_relationships.go @@ -9,7 +9,7 @@ import ( // --- MsgSaveProfile // ---------------------- -func NewMsgCreateRelationship(creator, recipient, subspace string) *MsgCreateRelationship { +func NewMsgCreateRelationship(creator, recipient string, subspace uint64) *MsgCreateRelationship { return &MsgCreateRelationship{ Sender: creator, Receiver: recipient, @@ -41,10 +41,6 @@ func (msg MsgCreateRelationship) ValidateBasic() error { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "sender and receiver must be different") } - if !IsValidSubspace(msg.Subspace) { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid subspace") - } - return nil } @@ -61,7 +57,7 @@ func (msg MsgCreateRelationship) GetSigners() []sdk.AccAddress { // ___________________________________________________________________________________________________________________ -func NewMsgDeleteRelationship(user, counterparty, subspace string) *MsgDeleteRelationship { +func NewMsgDeleteRelationship(user, counterparty string, subspace uint64) *MsgDeleteRelationship { return &MsgDeleteRelationship{ User: user, Counterparty: counterparty, @@ -93,10 +89,6 @@ func (msg MsgDeleteRelationship) ValidateBasic() error { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "user and counterparty must be different") } - if !IsValidSubspace(msg.Subspace) { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid subspace") - } - return nil } @@ -113,7 +105,7 @@ func (msg MsgDeleteRelationship) GetSigners() []sdk.AccAddress { // ___________________________________________________________________________________________________________________ -func NewMsgBlockUser(blocker, blocked, reason, subspace string) *MsgBlockUser { +func NewMsgBlockUser(blocker, blocked, reason string, subspace uint64) *MsgBlockUser { return &MsgBlockUser{ Blocker: blocker, Blocked: blocked, @@ -146,10 +138,6 @@ func (msg MsgBlockUser) ValidateBasic() error { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "blocker and blocked must be different") } - if !IsValidSubspace(msg.Subspace) { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid subspace") - } - return nil } @@ -166,7 +154,7 @@ func (msg MsgBlockUser) GetSigners() []sdk.AccAddress { // ___________________________________________________________________________________________________________________ -func NewMsgUnblockUser(blocker, blocked, subspace string) *MsgUnblockUser { +func NewMsgUnblockUser(blocker, blocked string, subspace uint64) *MsgUnblockUser { return &MsgUnblockUser{ Blocker: blocker, Blocked: blocked, @@ -198,10 +186,6 @@ func (msg MsgUnblockUser) ValidateBasic() error { return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "blocker and blocked must be different") } - if !IsValidSubspace(msg.Subspace) { - return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "invalid subspace") - } - return nil } diff --git a/x/profiles/types/msgs_relationships.pb.go b/x/profiles/types/msgs_relationships.pb.go index a670fc29ff..cc0dbfa4db 100644 --- a/x/profiles/types/msgs_relationships.pb.go +++ b/x/profiles/types/msgs_relationships.pb.go @@ -30,7 +30,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type MsgCreateRelationship struct { Sender string `protobuf:"bytes,1,opt,name=sender,proto3" json:"sender,omitempty" yaml:"sender"` Receiver string `protobuf:"bytes,2,opt,name=receiver,proto3" json:"receiver,omitempty" yaml:"receiver"` - Subspace string `protobuf:"bytes,3,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` + Subspace uint64 `protobuf:"varint,3,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` } func (m *MsgCreateRelationship) Reset() { *m = MsgCreateRelationship{} } @@ -109,7 +109,7 @@ var xxx_messageInfo_MsgCreateRelationshipResponse proto.InternalMessageInfo type MsgDeleteRelationship struct { User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` Counterparty string `protobuf:"bytes,2,opt,name=counterparty,proto3" json:"counterparty,omitempty" yaml:"counterparty"` - Subspace string `protobuf:"bytes,3,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` + Subspace uint64 `protobuf:"varint,3,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` } func (m *MsgDeleteRelationship) Reset() { *m = MsgDeleteRelationship{} } @@ -159,11 +159,11 @@ func (m *MsgDeleteRelationship) GetCounterparty() string { return "" } -func (m *MsgDeleteRelationship) GetSubspace() string { +func (m *MsgDeleteRelationship) GetSubspace() uint64 { if m != nil { return m.Subspace } - return "" + return 0 } // MsgDeleteRelationshipResponse defines the Msg/DeleteRelationship response @@ -210,7 +210,7 @@ type MsgBlockUser struct { Blocker string `protobuf:"bytes,1,opt,name=blocker,proto3" json:"blocker,omitempty" yaml:"blocker"` Blocked string `protobuf:"bytes,2,opt,name=blocked,proto3" json:"blocked,omitempty" yaml:"blocked"` Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty" yaml:"reason"` - Subspace string `protobuf:"bytes,4,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` + Subspace uint64 `protobuf:"varint,4,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` } func (m *MsgBlockUser) Reset() { *m = MsgBlockUser{} } @@ -267,11 +267,11 @@ func (m *MsgBlockUser) GetReason() string { return "" } -func (m *MsgBlockUser) GetSubspace() string { +func (m *MsgBlockUser) GetSubspace() uint64 { if m != nil { return m.Subspace } - return "" + return 0 } // MsgBlockUserResponse defines the Msg/BlockUser response type. @@ -315,7 +315,7 @@ var xxx_messageInfo_MsgBlockUserResponse proto.InternalMessageInfo type MsgUnblockUser struct { Blocker string `protobuf:"bytes,1,opt,name=blocker,proto3" json:"blocker,omitempty" yaml:"blocker"` Blocked string `protobuf:"bytes,2,opt,name=blocked,proto3" json:"blocked,omitempty" yaml:"blocked"` - Subspace string `protobuf:"bytes,4,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` + Subspace uint64 `protobuf:"varint,4,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` } func (m *MsgUnblockUser) Reset() { *m = MsgUnblockUser{} } @@ -365,11 +365,11 @@ func (m *MsgUnblockUser) GetBlocked() string { return "" } -func (m *MsgUnblockUser) GetSubspace() string { +func (m *MsgUnblockUser) GetSubspace() uint64 { if m != nil { return m.Subspace } - return "" + return 0 } // MsgUnblockUserResponse defines the Msg/UnblockUser response type. @@ -425,39 +425,39 @@ func init() { } var fileDescriptor_2d797ddfd6bfe874 = []byte{ - // 507 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x93, 0x31, 0x6f, 0xd3, 0x4c, - 0x18, 0xc7, 0xe3, 0xf7, 0xad, 0x4a, 0x39, 0x4a, 0x2b, 0xd2, 0xd2, 0x86, 0x4a, 0xd8, 0xe8, 0x58, - 0x40, 0x2a, 0x39, 0x52, 0xb6, 0xb2, 0x05, 0x36, 0x94, 0xc5, 0x52, 0x17, 0x96, 0xe8, 0x6c, 0x3f, - 0xbd, 0x46, 0x38, 0x3e, 0x73, 0xcf, 0x39, 0x22, 0xdf, 0x80, 0x91, 0x2f, 0x80, 0xd4, 0x99, 0x81, - 0x8f, 0x81, 0x18, 0x3b, 0x32, 0x59, 0x28, 0x59, 0x98, 0xfd, 0x09, 0x90, 0x7d, 0x67, 0x37, 0x69, - 0x8b, 0x4a, 0x17, 0x36, 0xdf, 0xf3, 0xfc, 0xfe, 0xf6, 0xff, 0x27, 0xeb, 0xc8, 0xf3, 0x08, 0x70, - 0x2c, 0x91, 0xa5, 0x4a, 0x1e, 0x8f, 0x62, 0x40, 0x36, 0xe9, 0x05, 0xa0, 0x79, 0x8f, 0x8d, 0x51, - 0xe0, 0x50, 0x41, 0xcc, 0xf5, 0x48, 0x26, 0x78, 0x32, 0x4a, 0xb1, 0x9b, 0x2a, 0xa9, 0x65, 0x7b, - 0xd7, 0x24, 0xba, 0x75, 0xa2, 0x6b, 0x13, 0x7b, 0xdb, 0x42, 0x0a, 0x59, 0x31, 0xac, 0x7c, 0x32, - 0xf8, 0xde, 0x03, 0x21, 0xa5, 0x88, 0x81, 0x55, 0xa7, 0x20, 0x3b, 0x66, 0x3c, 0x99, 0xd6, 0xab, - 0x50, 0x96, 0x6f, 0x1a, 0x9a, 0x8c, 0x39, 0xd8, 0xd5, 0xfe, 0x1f, 0x6b, 0xc9, 0x08, 0xe2, 0x2a, - 0x52, 0xce, 0x2d, 0x7d, 0x70, 0x0d, 0x7d, 0x85, 0xc6, 0xb5, 0x99, 0x48, 0x73, 0x31, 0x54, 0xf0, - 0x3e, 0x03, 0xd4, 0x36, 0x43, 0xbf, 0x3a, 0xe4, 0xfe, 0x00, 0xc5, 0x2b, 0x05, 0x5c, 0x83, 0xbf, - 0xf0, 0xd2, 0xf6, 0x53, 0xb2, 0x8a, 0x90, 0x44, 0xa0, 0x3a, 0xce, 0x23, 0xe7, 0xc9, 0xed, 0xfe, - 0xbd, 0x22, 0xf7, 0xee, 0x4e, 0xf9, 0x38, 0x3e, 0xa4, 0x66, 0x4e, 0x7d, 0x0b, 0xb4, 0x19, 0x59, - 0x53, 0x10, 0xc2, 0x68, 0x02, 0xaa, 0xf3, 0x5f, 0x05, 0x6f, 0x15, 0xb9, 0xb7, 0x69, 0xe0, 0x7a, - 0x43, 0xfd, 0x06, 0x2a, 0x03, 0x98, 0x05, 0x98, 0xf2, 0x10, 0x3a, 0xff, 0x5f, 0x0c, 0xd4, 0x1b, - 0xea, 0x37, 0xd0, 0xe1, 0xda, 0xc7, 0x53, 0xaf, 0xf5, 0xeb, 0xd4, 0x6b, 0x51, 0x8f, 0x3c, 0xbc, - 0xb2, 0xaf, 0x0f, 0x98, 0xca, 0x04, 0x81, 0x7e, 0x31, 0x46, 0xaf, 0x21, 0x86, 0x0b, 0x46, 0x8f, - 0xc9, 0x4a, 0x86, 0x8d, 0xcf, 0x66, 0x91, 0x7b, 0x77, 0xcc, 0x17, 0xcb, 0x29, 0xf5, 0xab, 0x65, - 0xfb, 0x25, 0x59, 0x0f, 0x65, 0x96, 0x68, 0x50, 0x29, 0x57, 0x7a, 0x6a, 0x7d, 0x76, 0x8b, 0xdc, - 0xdb, 0x32, 0xf0, 0xe2, 0x96, 0xfa, 0x4b, 0xf0, 0x8d, 0xbd, 0xac, 0xcd, 0xe5, 0xae, 0x8d, 0xcd, - 0x37, 0x87, 0xac, 0x0f, 0x50, 0xf4, 0x63, 0x19, 0xbe, 0x3b, 0x2a, 0xfb, 0xed, 0x93, 0x5b, 0x41, - 0x79, 0x68, 0x3c, 0xda, 0x45, 0xee, 0x6d, 0x98, 0x2f, 0xd8, 0x05, 0xf5, 0x6b, 0xe4, 0x9c, 0x8e, - 0xac, 0xc8, 0x25, 0x3a, 0x6a, 0xe8, 0xa8, 0xfc, 0xe5, 0x0a, 0x38, 0xca, 0xc4, 0x96, 0x5f, 0xf8, - 0xe5, 0x66, 0x4e, 0x7d, 0x0b, 0x2c, 0x99, 0xae, 0xfc, 0x8d, 0xe9, 0x0e, 0xd9, 0x5e, 0xf4, 0x68, - 0x04, 0x3f, 0x3b, 0x64, 0x63, 0x80, 0xe2, 0x28, 0x09, 0xfe, 0x89, 0xe2, 0x8d, 0x7b, 0x77, 0xc8, - 0xce, 0x72, 0xbd, 0xba, 0x79, 0xff, 0xcd, 0xf7, 0x99, 0xeb, 0x9c, 0xcd, 0x5c, 0xe7, 0xe7, 0xcc, - 0x75, 0x3e, 0xcd, 0xdd, 0xd6, 0xd9, 0xdc, 0x6d, 0xfd, 0x98, 0xbb, 0xad, 0xb7, 0x3d, 0x31, 0xd2, - 0x27, 0x59, 0xd0, 0x0d, 0xe5, 0x98, 0x99, 0x3b, 0xf9, 0x2c, 0xe6, 0x01, 0xda, 0x67, 0x36, 0x39, - 0x60, 0x1f, 0xce, 0x2f, 0xa9, 0x9e, 0xa6, 0x80, 0xc1, 0x6a, 0x75, 0x1d, 0x5f, 0xfc, 0x0e, 0x00, - 0x00, 0xff, 0xff, 0xd0, 0x1c, 0x97, 0x0c, 0xbd, 0x04, 0x00, 0x00, + // 509 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x93, 0xb1, 0x6e, 0xd3, 0x40, + 0x18, 0xc7, 0x63, 0x88, 0x4a, 0x39, 0x4a, 0x2b, 0xd2, 0xd2, 0x86, 0x4a, 0xd8, 0xd5, 0xb1, 0x14, + 0xa9, 0xe4, 0x48, 0xd9, 0xca, 0x16, 0xd8, 0x50, 0x16, 0x4b, 0x5d, 0x58, 0xa2, 0xb3, 0xfd, 0xf5, + 0x1a, 0xe1, 0xf8, 0xcc, 0x7d, 0xe7, 0x88, 0xbc, 0x01, 0x23, 0x2f, 0x80, 0xd4, 0x99, 0x81, 0xc7, + 0x40, 0x8c, 0x1d, 0x99, 0x22, 0x94, 0x2c, 0xcc, 0x7e, 0x02, 0x64, 0xdf, 0xd9, 0x4d, 0x68, 0x51, + 0xe9, 0xc2, 0xe6, 0xfb, 0xbe, 0xdf, 0xdf, 0xfe, 0xff, 0x64, 0x1d, 0x79, 0x1e, 0x01, 0x8e, 0x24, + 0xb2, 0x54, 0xc9, 0x93, 0x61, 0x0c, 0xc8, 0xc6, 0xdd, 0x00, 0x34, 0xef, 0xb2, 0x11, 0x0a, 0x1c, + 0x28, 0x88, 0xb9, 0x1e, 0xca, 0x04, 0x4f, 0x87, 0x29, 0x76, 0x52, 0x25, 0xb5, 0x6c, 0xed, 0x98, + 0x44, 0xa7, 0x4a, 0x74, 0x6c, 0x62, 0x77, 0x4b, 0x48, 0x21, 0x4b, 0x86, 0x15, 0x4f, 0x06, 0xdf, + 0x7d, 0x24, 0xa4, 0x14, 0x31, 0xb0, 0xf2, 0x14, 0x64, 0x27, 0x8c, 0x27, 0x93, 0x6a, 0x15, 0xca, + 0xe2, 0x4d, 0x03, 0x93, 0x31, 0x07, 0xbb, 0x3a, 0xf8, 0x6b, 0x2d, 0x19, 0x41, 0x5c, 0x46, 0x8a, + 0xb9, 0xa5, 0x0f, 0xaf, 0xa1, 0xaf, 0xd0, 0xb8, 0x36, 0x13, 0x69, 0x2e, 0x06, 0x0a, 0xde, 0x67, + 0x80, 0xda, 0x66, 0xe8, 0x57, 0x87, 0x3c, 0xec, 0xa3, 0x78, 0xa5, 0x80, 0x6b, 0xf0, 0x17, 0x5e, + 0xda, 0x7a, 0x4a, 0x56, 0x10, 0x92, 0x08, 0x54, 0xdb, 0xd9, 0x73, 0xf6, 0xef, 0xf6, 0x1e, 0xe4, + 0x53, 0xef, 0xfe, 0x84, 0x8f, 0xe2, 0x23, 0x6a, 0xe6, 0xd4, 0xb7, 0x40, 0x8b, 0x91, 0x55, 0x05, + 0x21, 0x0c, 0xc7, 0xa0, 0xda, 0xb7, 0x4a, 0x78, 0x33, 0x9f, 0x7a, 0x1b, 0x06, 0xae, 0x36, 0xd4, + 0xaf, 0xa1, 0x22, 0x80, 0x59, 0x80, 0x29, 0x0f, 0xa1, 0x7d, 0x7b, 0xcf, 0xd9, 0x6f, 0x2e, 0x06, + 0xaa, 0x0d, 0xf5, 0x6b, 0xe8, 0x68, 0xf5, 0xe3, 0x99, 0xd7, 0xf8, 0x75, 0xe6, 0x35, 0xa8, 0x47, + 0x1e, 0x5f, 0xd9, 0xd7, 0x07, 0x4c, 0x65, 0x82, 0x40, 0xbf, 0x18, 0xa3, 0xd7, 0x10, 0xc3, 0x1f, + 0x46, 0x4f, 0x48, 0x33, 0xc3, 0xda, 0x67, 0x23, 0x9f, 0x7a, 0xf7, 0xcc, 0x17, 0x8b, 0x29, 0xf5, + 0xcb, 0x65, 0xeb, 0x25, 0x59, 0x0b, 0x65, 0x96, 0x68, 0x50, 0x29, 0x57, 0x7a, 0x62, 0x7d, 0x76, + 0xf2, 0xa9, 0xb7, 0x69, 0xe0, 0xc5, 0x2d, 0xf5, 0x97, 0xe0, 0x1b, 0x7b, 0x59, 0x9b, 0xcb, 0x5d, + 0x6b, 0x9b, 0x6f, 0x0e, 0x59, 0xeb, 0xa3, 0xe8, 0xc5, 0x32, 0x7c, 0x77, 0x5c, 0xf4, 0x3b, 0x20, + 0x77, 0x82, 0xe2, 0x50, 0x7b, 0xb4, 0xf2, 0xa9, 0xb7, 0x6e, 0xbe, 0x60, 0x17, 0xd4, 0xaf, 0x90, + 0x0b, 0x3a, 0xb2, 0x22, 0x97, 0xe8, 0xa8, 0xa6, 0xa3, 0xe2, 0x97, 0x2b, 0xe0, 0x28, 0x93, 0xb2, + 0xfc, 0xd2, 0x2f, 0x37, 0x73, 0xea, 0x5b, 0x60, 0xc9, 0xb4, 0xf9, 0x2f, 0xa6, 0xdb, 0x64, 0x6b, + 0xd1, 0xa3, 0x16, 0xfc, 0xec, 0x90, 0xf5, 0x3e, 0x8a, 0xe3, 0x24, 0xf8, 0x2f, 0x8a, 0x37, 0xee, + 0xdd, 0x26, 0xdb, 0xcb, 0xf5, 0xaa, 0xe6, 0xbd, 0x37, 0xdf, 0x67, 0xae, 0x73, 0x3e, 0x73, 0x9d, + 0x9f, 0x33, 0xd7, 0xf9, 0x34, 0x77, 0x1b, 0xe7, 0x73, 0xb7, 0xf1, 0x63, 0xee, 0x36, 0xde, 0x76, + 0xc5, 0x50, 0x9f, 0x66, 0x41, 0x27, 0x94, 0x23, 0x66, 0xee, 0xe4, 0xb3, 0x98, 0x07, 0x68, 0x9f, + 0xd9, 0xf8, 0x90, 0x7d, 0xb8, 0xb8, 0xa4, 0x7a, 0x92, 0x02, 0x06, 0x2b, 0xe5, 0x75, 0x7c, 0xf1, + 0x3b, 0x00, 0x00, 0xff, 0xff, 0x01, 0x5e, 0xbb, 0xac, 0xbd, 0x04, 0x00, 0x00, } func (m *MsgCreateRelationship) Marshal() (dAtA []byte, err error) { @@ -480,12 +480,10 @@ func (m *MsgCreateRelationship) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Subspace) > 0 { - i -= len(m.Subspace) - copy(dAtA[i:], m.Subspace) - i = encodeVarintMsgsRelationships(dAtA, i, uint64(len(m.Subspace))) + if m.Subspace != 0 { + i = encodeVarintMsgsRelationships(dAtA, i, uint64(m.Subspace)) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x18 } if len(m.Receiver) > 0 { i -= len(m.Receiver) @@ -547,12 +545,10 @@ func (m *MsgDeleteRelationship) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Subspace) > 0 { - i -= len(m.Subspace) - copy(dAtA[i:], m.Subspace) - i = encodeVarintMsgsRelationships(dAtA, i, uint64(len(m.Subspace))) + if m.Subspace != 0 { + i = encodeVarintMsgsRelationships(dAtA, i, uint64(m.Subspace)) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x18 } if len(m.Counterparty) > 0 { i -= len(m.Counterparty) @@ -614,12 +610,10 @@ func (m *MsgBlockUser) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Subspace) > 0 { - i -= len(m.Subspace) - copy(dAtA[i:], m.Subspace) - i = encodeVarintMsgsRelationships(dAtA, i, uint64(len(m.Subspace))) + if m.Subspace != 0 { + i = encodeVarintMsgsRelationships(dAtA, i, uint64(m.Subspace)) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x20 } if len(m.Reason) > 0 { i -= len(m.Reason) @@ -688,12 +682,10 @@ func (m *MsgUnblockUser) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.Subspace) > 0 { - i -= len(m.Subspace) - copy(dAtA[i:], m.Subspace) - i = encodeVarintMsgsRelationships(dAtA, i, uint64(len(m.Subspace))) + if m.Subspace != 0 { + i = encodeVarintMsgsRelationships(dAtA, i, uint64(m.Subspace)) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x20 } if len(m.Blocked) > 0 { i -= len(m.Blocked) @@ -760,9 +752,8 @@ func (m *MsgCreateRelationship) Size() (n int) { if l > 0 { n += 1 + l + sovMsgsRelationships(uint64(l)) } - l = len(m.Subspace) - if l > 0 { - n += 1 + l + sovMsgsRelationships(uint64(l)) + if m.Subspace != 0 { + n += 1 + sovMsgsRelationships(uint64(m.Subspace)) } return n } @@ -790,9 +781,8 @@ func (m *MsgDeleteRelationship) Size() (n int) { if l > 0 { n += 1 + l + sovMsgsRelationships(uint64(l)) } - l = len(m.Subspace) - if l > 0 { - n += 1 + l + sovMsgsRelationships(uint64(l)) + if m.Subspace != 0 { + n += 1 + sovMsgsRelationships(uint64(m.Subspace)) } return n } @@ -824,9 +814,8 @@ func (m *MsgBlockUser) Size() (n int) { if l > 0 { n += 1 + l + sovMsgsRelationships(uint64(l)) } - l = len(m.Subspace) - if l > 0 { - n += 1 + l + sovMsgsRelationships(uint64(l)) + if m.Subspace != 0 { + n += 1 + sovMsgsRelationships(uint64(m.Subspace)) } return n } @@ -854,9 +843,8 @@ func (m *MsgUnblockUser) Size() (n int) { if l > 0 { n += 1 + l + sovMsgsRelationships(uint64(l)) } - l = len(m.Subspace) - if l > 0 { - n += 1 + l + sovMsgsRelationships(uint64(l)) + if m.Subspace != 0 { + n += 1 + sovMsgsRelationships(uint64(m.Subspace)) } return n } @@ -970,10 +958,10 @@ func (m *MsgCreateRelationship) Unmarshal(dAtA []byte) error { m.Receiver = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) } - var stringLen uint64 + m.Subspace = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgsRelationships @@ -983,24 +971,11 @@ func (m *MsgCreateRelationship) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Subspace |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgsRelationships - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgsRelationships - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subspace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMsgsRelationships(dAtA[iNdEx:]) @@ -1166,10 +1141,10 @@ func (m *MsgDeleteRelationship) Unmarshal(dAtA []byte) error { m.Counterparty = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) } - var stringLen uint64 + m.Subspace = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgsRelationships @@ -1179,24 +1154,11 @@ func (m *MsgDeleteRelationship) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Subspace |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgsRelationships - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgsRelationships - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subspace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMsgsRelationships(dAtA[iNdEx:]) @@ -1394,10 +1356,10 @@ func (m *MsgBlockUser) Unmarshal(dAtA []byte) error { m.Reason = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) } - var stringLen uint64 + m.Subspace = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgsRelationships @@ -1407,24 +1369,11 @@ func (m *MsgBlockUser) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Subspace |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgsRelationships - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgsRelationships - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subspace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMsgsRelationships(dAtA[iNdEx:]) @@ -1590,10 +1539,10 @@ func (m *MsgUnblockUser) Unmarshal(dAtA []byte) error { m.Blocked = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) } - var stringLen uint64 + m.Subspace = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgsRelationships @@ -1603,24 +1552,11 @@ func (m *MsgUnblockUser) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Subspace |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgsRelationships - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgsRelationships - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Subspace = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipMsgsRelationships(dAtA[iNdEx:]) diff --git a/x/profiles/types/msgs_relationships_test.go b/x/profiles/types/msgs_relationships_test.go index eb1781bcec..8f85f54d21 100644 --- a/x/profiles/types/msgs_relationships_test.go +++ b/x/profiles/types/msgs_relationships_test.go @@ -13,7 +13,7 @@ import ( var msgCreateRelationship = types.NewMsgCreateRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "", + 0, ) func TestMsgCreateRelationship_Route(t *testing.T) { @@ -35,7 +35,7 @@ func TestMsgCreateRelationship_ValidateBasic(t *testing.T) { msg: types.NewMsgCreateRelationship( "", "", - "", + 0, ), shouldErr: true, }, @@ -44,7 +44,7 @@ func TestMsgCreateRelationship_ValidateBasic(t *testing.T) { msg: types.NewMsgCreateRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "", - "", + 0, ), shouldErr: true, }, @@ -53,16 +53,7 @@ func TestMsgCreateRelationship_ValidateBasic(t *testing.T) { msg: types.NewMsgCreateRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "", - ), - shouldErr: true, - }, - { - name: "invalid subspace returns error", - msg: types.NewMsgCreateRelationship( - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "1234", + 0, ), shouldErr: true, }, @@ -102,7 +93,7 @@ func TestMsgCreateRelationship_GetSigners(t *testing.T) { var msgDeleteRelationships = types.NewMsgDeleteRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "", + 0, ) func TestMsgDeleteRelationships_Route(t *testing.T) { @@ -124,7 +115,7 @@ func TestMsgDeleteRelationships_ValidateBasic(t *testing.T) { msg: types.NewMsgDeleteRelationship( "", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "", + 0, ), shouldErr: true, }, @@ -133,7 +124,7 @@ func TestMsgDeleteRelationships_ValidateBasic(t *testing.T) { msg: types.NewMsgDeleteRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "", - "", + 0, ), shouldErr: true, }, @@ -142,16 +133,7 @@ func TestMsgDeleteRelationships_ValidateBasic(t *testing.T) { msg: types.NewMsgDeleteRelationship( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "", - ), - shouldErr: true, - }, - { - name: "invalid subspace returns error", - msg: types.NewMsgDeleteRelationship( - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "1234", + 0, ), shouldErr: true, }, @@ -192,7 +174,7 @@ var msgBlockUser = types.NewMsgBlockUser( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", "reason", - "", + 0, ) func TestMsgBlockUser_Route(t *testing.T) { @@ -215,7 +197,7 @@ func TestMsgBlockUser_ValidateBasic(t *testing.T) { "", "", "", - "", + 0, ), shouldErr: true, }, @@ -225,7 +207,7 @@ func TestMsgBlockUser_ValidateBasic(t *testing.T) { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "", "", - "", + 0, ), shouldErr: true, }, @@ -235,17 +217,7 @@ func TestMsgBlockUser_ValidateBasic(t *testing.T) { "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "", - "", - ), - shouldErr: true, - }, - { - name: "invalid subspace returns error", - msg: types.NewMsgBlockUser( - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "", - "yeah", + 0, ), shouldErr: true, }, @@ -285,7 +257,7 @@ func TestMsgBlockUser_GetSigners(t *testing.T) { var msgUnblockUser = types.NewMsgUnblockUser( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "", + 0, ) func TestMsgUnblockUser_Route(t *testing.T) { @@ -307,7 +279,7 @@ func TestMsgUnblockUser_ValidateBasic(t *testing.T) { msg: types.NewMsgUnblockUser( "", "", - "", + 0, ), shouldErr: true, }, @@ -316,7 +288,7 @@ func TestMsgUnblockUser_ValidateBasic(t *testing.T) { msg: types.NewMsgUnblockUser( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "", - "", + 0, ), shouldErr: true, }, @@ -325,16 +297,7 @@ func TestMsgUnblockUser_ValidateBasic(t *testing.T) { msg: types.NewMsgUnblockUser( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "", - ), - shouldErr: true, - }, - { - name: "invalid subspace returns error", - msg: types.NewMsgUnblockUser( - "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", - "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "yeah", + 0, ), shouldErr: true, }, @@ -343,7 +306,7 @@ func TestMsgUnblockUser_ValidateBasic(t *testing.T) { msg: types.NewMsgUnblockUser( "cosmos1cjf97gpzwmaf30pzvaargfgr884mpp5ak8f7ns", "cosmos1y54exmx84cqtasvjnskf9f63djuuj68p7hqf47", - "", + 0, ), shouldErr: false, }, diff --git a/x/profiles/types/query_relationships.pb.go b/x/profiles/types/query_relationships.pb.go index ce3d6fea3a..f8b8b6aac2 100644 --- a/x/profiles/types/query_relationships.pb.go +++ b/x/profiles/types/query_relationships.pb.go @@ -33,7 +33,7 @@ type QueryRelationshipsRequest struct { // address of the user to query the relationships for User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` // subspace to query the relationships for - SubspaceId string `protobuf:"bytes,2,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` + SubspaceId uint64 `protobuf:"varint,2,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` // pagination defines an optional pagination for the request. Pagination *query.PageRequest `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -131,7 +131,7 @@ func (m *QueryRelationshipsResponse) GetPagination() *query.PageResponse { type QueryBlocksRequest struct { // address of the user to query the blocks for User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` - SubspaceId string `protobuf:"bytes,2,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` + SubspaceId uint64 `protobuf:"varint,2,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` Pagination *query.PageRequest `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -234,36 +234,36 @@ func init() { } var fileDescriptor_c0b8922e87a25523 = []byte{ - // 450 bytes of a gzipped FileDescriptorProto + // 452 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x93, 0xb1, 0x8e, 0xd3, 0x40, - 0x10, 0x86, 0xbd, 0x77, 0xa7, 0x13, 0x6c, 0x44, 0xb3, 0x20, 0x91, 0x44, 0xc8, 0x89, 0x22, 0x01, - 0x11, 0x12, 0xbb, 0x4a, 0xe8, 0xa8, 0x50, 0x0a, 0x10, 0xa2, 0xe1, 0x2c, 0xd1, 0xd0, 0x44, 0xbb, - 0xf1, 0x9c, 0xcf, 0xc2, 0xf1, 0xee, 0x79, 0xec, 0x13, 0x79, 0x03, 0x4a, 0x7a, 0x9a, 0x88, 0xa7, - 0xe0, 0x11, 0xae, 0xbc, 0x92, 0x0a, 0xa1, 0xa4, 0xe1, 0x31, 0x90, 0x77, 0x37, 0x9c, 0x2d, 0x5d, - 0x44, 0x43, 0x41, 0x37, 0xb3, 0x33, 0xff, 0xcc, 0x37, 0x7f, 0x62, 0x3a, 0x89, 0x01, 0x97, 0x1a, - 0x85, 0x29, 0xf4, 0x69, 0x9a, 0x01, 0x8a, 0x8b, 0x89, 0x82, 0x52, 0x4e, 0xc4, 0x79, 0x05, 0xc5, - 0x6a, 0x5e, 0x40, 0x26, 0xcb, 0x54, 0xe7, 0x78, 0x96, 0x1a, 0xe4, 0xa6, 0xd0, 0xa5, 0x66, 0xf7, - 0x9d, 0x84, 0xef, 0x24, 0xdc, 0x4b, 0xfa, 0xf7, 0x12, 0x9d, 0x68, 0xdb, 0x23, 0xea, 0xc8, 0xb5, - 0xf7, 0x1f, 0x24, 0x5a, 0x27, 0x19, 0x08, 0x69, 0x52, 0x21, 0xf3, 0x5c, 0x97, 0x6e, 0xa0, 0xaf, - 0xf6, 0x7c, 0xd5, 0x66, 0xaa, 0x3a, 0x15, 0x32, 0x5f, 0xf9, 0xd2, 0x74, 0x1f, 0xda, 0x52, 0xc7, - 0x90, 0xe1, 0x4d, 0x6c, 0xfd, 0xde, 0x42, 0xd7, 0x9a, 0xb9, 0xa3, 0x70, 0x89, 0x2f, 0x3d, 0x71, - 0x99, 0x50, 0x12, 0xc1, 0x5d, 0xf7, 0x67, 0xa0, 0x91, 0x49, 0x9a, 0xdb, 0x59, 0xae, 0x77, 0xf4, - 0x95, 0xd0, 0xde, 0x49, 0xdd, 0x12, 0x35, 0x77, 0x44, 0x70, 0x5e, 0x01, 0x96, 0x8c, 0xd1, 0xa3, - 0x0a, 0xa1, 0xe8, 0x92, 0x21, 0x19, 0xdf, 0x8e, 0x6c, 0xcc, 0x06, 0xb4, 0x83, 0x95, 0x42, 0x23, - 0x17, 0x30, 0x4f, 0xe3, 0xee, 0x81, 0x2d, 0xd1, 0xdd, 0xd3, 0xeb, 0x98, 0xbd, 0xa4, 0xf4, 0x7a, - 0x4d, 0xf7, 0x70, 0x48, 0xc6, 0x9d, 0xe9, 0x23, 0xee, 0x09, 0x6b, 0x26, 0x6e, 0x99, 0x76, 0x66, - 0xf2, 0xb7, 0x32, 0x01, 0xbf, 0x30, 0x6a, 0x28, 0x9f, 0xdf, 0xfa, 0xb4, 0x1e, 0x04, 0xbf, 0xd6, - 0x83, 0x60, 0xf4, 0x8d, 0xd0, 0xfe, 0x4d, 0x90, 0x68, 0x74, 0x8e, 0xc0, 0x4e, 0xe8, 0x9d, 0x96, - 0x43, 0x5d, 0x32, 0x3c, 0x1c, 0x77, 0xa6, 0x0f, 0xf9, 0x9e, 0x9f, 0x8f, 0x37, 0xc7, 0xcc, 0x8e, - 0x2e, 0x7f, 0x0c, 0x82, 0xa8, 0x3d, 0x81, 0xbd, 0x6a, 0xdd, 0x70, 0x60, 0x6f, 0x78, 0xfc, 0xd7, - 0x1b, 0x1c, 0x4f, 0xf3, 0x88, 0xd1, 0x17, 0x42, 0x99, 0x45, 0x9f, 0x65, 0x7a, 0xf1, 0xe1, 0x7f, - 0x33, 0x76, 0x4d, 0xe8, 0xdd, 0x16, 0x9d, 0x77, 0xf4, 0x05, 0x3d, 0x56, 0xf6, 0xc5, 0x5b, 0x39, - 0xda, 0x6b, 0xe5, 0x3b, 0x84, 0xc2, 0x8a, 0xbd, 0x8f, 0x5e, 0xf7, 0xcf, 0x0c, 0x9c, 0xbd, 0xb9, - 0xdc, 0x84, 0xe4, 0x6a, 0x13, 0x92, 0x9f, 0x9b, 0x90, 0x7c, 0xde, 0x86, 0xc1, 0xd5, 0x36, 0x0c, - 0xbe, 0x6f, 0xc3, 0xe0, 0xfd, 0x24, 0x49, 0xcb, 0xb3, 0x4a, 0xf1, 0x85, 0x5e, 0x0a, 0x87, 0xf7, - 0x34, 0x93, 0x0a, 0x7d, 0x2c, 0x2e, 0xa6, 0xe2, 0xe3, 0xf5, 0x17, 0x55, 0xae, 0x0c, 0xa0, 0x3a, - 0xb6, 0x7f, 0xfa, 0x67, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x72, 0x42, 0x3d, 0x1e, 0x0c, 0x04, - 0x00, 0x00, + 0x10, 0x86, 0xbd, 0x77, 0xd1, 0x09, 0x36, 0xa2, 0x59, 0x90, 0x48, 0x22, 0xe4, 0x44, 0x91, 0x80, + 0x08, 0x89, 0x5d, 0x25, 0x74, 0x54, 0x28, 0x05, 0x08, 0xd1, 0x70, 0x96, 0x68, 0x68, 0xa2, 0xdd, + 0x64, 0xce, 0x67, 0xe1, 0x78, 0xf7, 0x3c, 0xf6, 0x89, 0xbc, 0x01, 0x25, 0x3d, 0x4d, 0xc4, 0x53, + 0xf0, 0x08, 0x57, 0x5e, 0x49, 0x85, 0x50, 0xd2, 0xf0, 0x18, 0xc8, 0xbb, 0x1b, 0xce, 0x96, 0x12, + 0xd1, 0x50, 0xd0, 0xcd, 0xec, 0xcc, 0x3f, 0xf3, 0xcd, 0x9f, 0x98, 0x8e, 0x17, 0x80, 0x4b, 0x8d, + 0xc2, 0xe4, 0xfa, 0x2c, 0x49, 0x01, 0xc5, 0xe5, 0x58, 0x41, 0x21, 0xc7, 0xe2, 0xa2, 0x84, 0x7c, + 0x35, 0xcb, 0x21, 0x95, 0x45, 0xa2, 0x33, 0x3c, 0x4f, 0x0c, 0x72, 0x93, 0xeb, 0x42, 0xb3, 0xfb, + 0x4e, 0xc2, 0x77, 0x12, 0xee, 0x25, 0xbd, 0x7b, 0xb1, 0x8e, 0xb5, 0xed, 0x11, 0x55, 0xe4, 0xda, + 0x7b, 0x0f, 0x62, 0xad, 0xe3, 0x14, 0x84, 0x34, 0x89, 0x90, 0x59, 0xa6, 0x0b, 0x37, 0xd0, 0x57, + 0xbb, 0xbe, 0x6a, 0x33, 0x55, 0x9e, 0x09, 0x99, 0xad, 0x7c, 0x69, 0x72, 0x08, 0x6d, 0xa9, 0x17, + 0x90, 0xe2, 0x3e, 0xb6, 0x5e, 0x77, 0xae, 0x2b, 0xcd, 0xcc, 0x51, 0xb8, 0xc4, 0x97, 0x9e, 0xb8, + 0x4c, 0x28, 0x89, 0xe0, 0xae, 0xfb, 0x33, 0xd0, 0xc8, 0x38, 0xc9, 0xec, 0x2c, 0xd7, 0x3b, 0xfc, + 0x4a, 0x68, 0xf7, 0xb4, 0x6a, 0x89, 0xea, 0x3b, 0x22, 0xb8, 0x28, 0x01, 0x0b, 0xc6, 0x68, 0xab, + 0x44, 0xc8, 0x3b, 0x64, 0x40, 0x46, 0xb7, 0x23, 0x1b, 0xb3, 0x3e, 0x6d, 0x63, 0xa9, 0xd0, 0xc8, + 0x39, 0xcc, 0x92, 0x45, 0xe7, 0x68, 0x40, 0x46, 0xad, 0x88, 0xee, 0x9e, 0x5e, 0x2f, 0xd8, 0x4b, + 0x4a, 0x6f, 0xd6, 0x74, 0x8e, 0x07, 0x64, 0xd4, 0x9e, 0x3c, 0xe2, 0x9e, 0xb0, 0x62, 0xe2, 0x96, + 0x69, 0x67, 0x26, 0x7f, 0x2b, 0x63, 0xf0, 0x0b, 0xa3, 0x9a, 0xf2, 0xf9, 0xad, 0x4f, 0xeb, 0x7e, + 0xf0, 0x6b, 0xdd, 0x0f, 0x86, 0xdf, 0x08, 0xed, 0xed, 0x83, 0x44, 0xa3, 0x33, 0x04, 0x76, 0x4a, + 0xef, 0x34, 0x1c, 0xea, 0x90, 0xc1, 0xf1, 0xa8, 0x3d, 0x79, 0xc8, 0x0f, 0xfc, 0x7c, 0xbc, 0x3e, + 0x66, 0xda, 0xba, 0xfa, 0xd1, 0x0f, 0xa2, 0xe6, 0x04, 0xf6, 0xaa, 0x71, 0xc3, 0x91, 0xbd, 0xe1, + 0xf1, 0x5f, 0x6f, 0x70, 0x3c, 0xf5, 0x23, 0x86, 0x5f, 0x08, 0x65, 0x16, 0x7d, 0x9a, 0xea, 0xf9, + 0x87, 0xff, 0xcd, 0xd8, 0x35, 0xa1, 0x77, 0x1b, 0x74, 0xde, 0xd1, 0x17, 0xf4, 0x44, 0xd9, 0x17, + 0x6f, 0xe5, 0xf0, 0xa0, 0x95, 0xef, 0x10, 0x72, 0x2b, 0xf6, 0x3e, 0x7a, 0xdd, 0x3f, 0x33, 0x70, + 0xfa, 0xe6, 0x6a, 0x13, 0x92, 0xeb, 0x4d, 0x48, 0x7e, 0x6e, 0x42, 0xf2, 0x79, 0x1b, 0x06, 0xd7, + 0xdb, 0x30, 0xf8, 0xbe, 0x0d, 0x83, 0xf7, 0xe3, 0x38, 0x29, 0xce, 0x4b, 0xc5, 0xe7, 0x7a, 0x29, + 0x1c, 0xde, 0xd3, 0x54, 0x2a, 0xf4, 0xb1, 0xb8, 0x9c, 0x88, 0x8f, 0x37, 0x5f, 0x54, 0xb1, 0x32, + 0x80, 0xea, 0xc4, 0xfe, 0xe9, 0x9f, 0xfd, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x9b, 0x95, 0x8e, 0x67, + 0x0c, 0x04, 0x00, 0x00, } func (m *QueryRelationshipsRequest) Marshal() (dAtA []byte, err error) { @@ -298,12 +298,10 @@ func (m *QueryRelationshipsRequest) MarshalToSizedBuffer(dAtA []byte) (int, erro i-- dAtA[i] = 0x1a } - if len(m.SubspaceId) > 0 { - i -= len(m.SubspaceId) - copy(dAtA[i:], m.SubspaceId) - i = encodeVarintQueryRelationships(dAtA, i, uint64(len(m.SubspaceId))) + if m.SubspaceId != 0 { + i = encodeVarintQueryRelationships(dAtA, i, uint64(m.SubspaceId)) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x10 } if len(m.User) > 0 { i -= len(m.User) @@ -396,12 +394,10 @@ func (m *QueryBlocksRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - if len(m.SubspaceId) > 0 { - i -= len(m.SubspaceId) - copy(dAtA[i:], m.SubspaceId) - i = encodeVarintQueryRelationships(dAtA, i, uint64(len(m.SubspaceId))) + if m.SubspaceId != 0 { + i = encodeVarintQueryRelationships(dAtA, i, uint64(m.SubspaceId)) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x10 } if len(m.User) > 0 { i -= len(m.User) @@ -483,9 +479,8 @@ func (m *QueryRelationshipsRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQueryRelationships(uint64(l)) } - l = len(m.SubspaceId) - if l > 0 { - n += 1 + l + sovQueryRelationships(uint64(l)) + if m.SubspaceId != 0 { + n += 1 + sovQueryRelationships(uint64(m.SubspaceId)) } if m.Pagination != nil { l = m.Pagination.Size() @@ -523,9 +518,8 @@ func (m *QueryBlocksRequest) Size() (n int) { if l > 0 { n += 1 + l + sovQueryRelationships(uint64(l)) } - l = len(m.SubspaceId) - if l > 0 { - n += 1 + l + sovQueryRelationships(uint64(l)) + if m.SubspaceId != 0 { + n += 1 + sovQueryRelationships(uint64(m.SubspaceId)) } if m.Pagination != nil { l = m.Pagination.Size() @@ -621,10 +615,10 @@ func (m *QueryRelationshipsRequest) Unmarshal(dAtA []byte) error { m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SubspaceId", wireType) } - var stringLen uint64 + m.SubspaceId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQueryRelationships @@ -634,24 +628,11 @@ func (m *QueryRelationshipsRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.SubspaceId |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQueryRelationships - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQueryRelationships - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SubspaceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) @@ -891,10 +872,10 @@ func (m *QueryBlocksRequest) Unmarshal(dAtA []byte) error { m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 2 { + if wireType != 0 { return fmt.Errorf("proto: wrong wireType = %d for field SubspaceId", wireType) } - var stringLen uint64 + m.SubspaceId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQueryRelationships @@ -904,24 +885,11 @@ func (m *QueryBlocksRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.SubspaceId |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQueryRelationships - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQueryRelationships - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.SubspaceId = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) diff --git a/x/subspaces/client/cli/query.go b/x/subspaces/client/cli/query.go index 529f4fbc63..eed3f2f978 100644 --- a/x/subspaces/client/cli/query.go +++ b/x/subspaces/client/cli/query.go @@ -3,7 +3,6 @@ package cli import ( "context" "fmt" - "strconv" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" @@ -46,9 +45,9 @@ func GetCmdQuerySubspace() *cobra.Command { } queryClient := types.NewQueryClient(clientCtx) - subspaceID, err := strconv.ParseUint(args[0], 10, 64) + subspaceID, err := types.ParseSubspaceID(args[0]) if err != nil { - return fmt.Errorf("invalid subspace id: %s", err) + return err } res, err := queryClient.Subspace(context.Background(), types.NewQuerySubspaceRequest(subspaceID)) @@ -122,9 +121,9 @@ func GetCmdQueryUserGroups() *cobra.Command { return err } - subspaceID, err := strconv.ParseUint(args[0], 10, 64) + subspaceID, err := types.ParseSubspaceID(args[0]) if err != nil { - return fmt.Errorf("invalid subspace id: %s", err) + return err } res, err := queryClient.UserGroups( @@ -166,9 +165,9 @@ func GetCmdQueryUserGroupMembers() *cobra.Command { return err } - subspaceID, err := strconv.ParseUint(args[0], 10, 64) + subspaceID, err := types.ParseSubspaceID(args[0]) if err != nil { - return fmt.Errorf("invalid subspace id: %s", err) + return err } groupName := args[1] diff --git a/x/subspaces/client/cli/tx.go b/x/subspaces/client/cli/tx.go index efc91535a3..14cd03ff23 100644 --- a/x/subspaces/client/cli/tx.go +++ b/x/subspaces/client/cli/tx.go @@ -2,7 +2,6 @@ package cli import ( "fmt" - "strconv" "strings" "github.com/cosmos/cosmos-sdk/client" @@ -122,9 +121,9 @@ func GetCmdEditSubspace() *cobra.Command { return err } - subspaceID, err := strconv.ParseUint(args[0], 10, 64) + subspaceID, err := types.ParseSubspaceID(args[0]) if err != nil { - return fmt.Errorf("invalid subspace id: %s", err) + return err } name, err := cmd.Flags().GetString(FlagName) @@ -186,9 +185,9 @@ Multiple permissions must be specified separating them with a comma (,).`, return err } - subspaceID, err := strconv.ParseUint(args[0], 10, 64) + subspaceID, err := types.ParseSubspaceID(args[0]) if err != nil { - return fmt.Errorf("invalid subspace id: %s", err) + return err } name := args[1] @@ -233,9 +232,9 @@ func GetCmdDeleteUserGroup() *cobra.Command { return err } - subspaceID, err := strconv.ParseUint(args[0], 10, 64) + subspaceID, err := types.ParseSubspaceID(args[0]) if err != nil { - return fmt.Errorf("invalid subspace id: %s", err) + return err } name := args[1] @@ -270,9 +269,9 @@ func GetCmdAddUserToUserGroup() *cobra.Command { return err } - subspaceID, err := strconv.ParseUint(args[0], 10, 64) + subspaceID, err := types.ParseSubspaceID(args[0]) if err != nil { - return fmt.Errorf("invalid subspace id: %s", err) + return err } name := args[1] @@ -308,9 +307,9 @@ func GetCmdRemoveUserFromUserGroup() *cobra.Command { return err } - subspaceID, err := strconv.ParseUint(args[0], 10, 64) + subspaceID, err := types.ParseSubspaceID(args[0]) if err != nil { - return fmt.Errorf("invalid subspace id: %s", err) + return err } name := args[1] @@ -352,9 +351,9 @@ When specifying multiple permissions, they must be separated by a comma (,).`, return err } - subspaceID, err := strconv.ParseUint(args[0], 10, 64) + subspaceID, err := types.ParseSubspaceID(args[0]) if err != nil { - return fmt.Errorf("invalid subspace id: %s", err) + return err } target := args[1] diff --git a/x/subspaces/types/subspace.go b/x/subspaces/types/subspace.go index 423d62bea7..f8e70ddf74 100644 --- a/x/subspaces/types/subspace.go +++ b/x/subspaces/types/subspace.go @@ -2,12 +2,26 @@ package types import ( "fmt" + "strconv" "strings" "time" sdk "github.com/cosmos/cosmos-sdk/types" ) +// ParseSubspaceID parses the given value as a subspace id, returning an error if it's invalid +func ParseSubspaceID(value string) (uint64, error) { + if value == "" { + return 0, nil + } + + subspaceID, err := strconv.ParseUint(value, 10, 64) + if err != nil { + return 0, fmt.Errorf("invalid subspace id: %s", err) + } + return subspaceID, nil +} + // NewSubspace is a constructor for the Subspace type func NewSubspace(subspaceID uint64, name, description, treasury, owner, creator string, creationTime time.Time) Subspace { return Subspace{ From 10e2a710b8b99b60936129957d61b78e8d0a91f9 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 24 Jan 2022 15:11:07 +0100 Subject: [PATCH 13/47] added initial subspaces id to the subspaces genesis Signed-off-by: Riccardo Montagnin --- app/app.go | 16 +- .../legacy/v230/models_chain_links.proto | 6 +- proto/desmos/subspaces/v1/genesis.proto | 7 +- x/subspaces/client/cli/cli_test.go | 14 +- x/subspaces/keeper/genesis.go | 9 ++ x/subspaces/keeper/genesis_test.go | 18 +++ x/subspaces/simulation/genesis.go | 3 +- x/subspaces/types/genesis.go | 22 +-- x/subspaces/types/genesis.pb.go | 140 +++++++++++------- x/subspaces/types/genesis_test.go | 41 +++++ 10 files changed, 193 insertions(+), 83 deletions(-) diff --git a/app/app.go b/app/app.go index 6cede0aeea..e327c9d4a8 100644 --- a/app/app.go +++ b/app/app.go @@ -273,8 +273,8 @@ type DesmosApp struct { ScopedWasmKeeper capabilitykeeper.ScopedKeeper // Custom modules - ProfileKeeper profileskeeper.Keeper SubspacesKeeper subspaceskeeper.Keeper + ProfileKeeper profileskeeper.Keeper // Module Manager mm *module.Manager @@ -321,7 +321,7 @@ func NewDesmosApp( authzkeeper.StoreKey, wasm.StoreKey, // Custom modules - profilestypes.StoreKey, subspacestypes.StoreKey, + subspacestypes.StoreKey, profilestypes.StoreKey, ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey) memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey) @@ -411,6 +411,9 @@ func NewDesmosApp( ) transferModule := ibctransfer.NewAppModule(app.TransferKeeper) + // Create subspaces keeper + app.SubspacesKeeper = subspaceskeeper.NewKeeper(app.appCodec, keys[subspacestypes.StoreKey]) + // Create profiles keeper app.ProfileKeeper = profileskeeper.NewKeeper( app.appCodec, @@ -424,9 +427,6 @@ func NewDesmosApp( ) profilesModule := profiles.NewAppModule(appCodec, legacyAmino, app.ProfileKeeper, app.SubspacesKeeper, app.AccountKeeper, app.BankKeeper) - // Create subspaces keeper - app.SubspacesKeeper = subspaceskeeper.NewKeeper(app.appCodec, keys[subspacestypes.StoreKey]) - // Create static IBC router, add transfer route, then set and seal it ibcRouter := porttypes.NewRouter() ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferModule) @@ -523,8 +523,8 @@ func NewDesmosApp( wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper), // Custom modules - profilesModule, subspaces.NewAppModule(appCodec, app.SubspacesKeeper, app.AccountKeeper, app.BankKeeper), + profilesModule, ) // During begin block slashing happens after distr.BeginBlocker so that @@ -552,7 +552,7 @@ func NewDesmosApp( feegrant.ModuleName, wasm.ModuleName, // Custom modules - profilestypes.ModuleName, subspacestypes.ModuleName, + subspacestypes.ModuleName, profilestypes.ModuleName, crisistypes.ModuleName, ) @@ -587,8 +587,8 @@ func NewDesmosApp( wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper), // Custom modules - profiles.NewAppModule(app.appCodec, legacyAmino, app.ProfileKeeper, app.SubspacesKeeper, app.AccountKeeper, app.BankKeeper), subspaces.NewAppModule(app.appCodec, app.SubspacesKeeper, app.AccountKeeper, app.BankKeeper), + profiles.NewAppModule(app.appCodec, legacyAmino, app.ProfileKeeper, app.SubspacesKeeper, app.AccountKeeper, app.BankKeeper), ) app.sm.RegisterStoreDecoders() diff --git a/proto/desmos/profiles/legacy/v230/models_chain_links.proto b/proto/desmos/profiles/legacy/v230/models_chain_links.proto index 27c4a9f7c9..ada3b144e6 100644 --- a/proto/desmos/profiles/legacy/v230/models_chain_links.proto +++ b/proto/desmos/profiles/legacy/v230/models_chain_links.proto @@ -66,7 +66,8 @@ message Proof { // Signature represents the hex-encoded signature of the PlainText value string signature = 2 [ (gogoproto.moretags) = "yaml:\"signature\"" ]; - // PlainText represents the hex-encoded value signed in order to produce the Signature + // PlainText represents the hex-encoded value signed in order to produce the + // Signature string plain_text = 3 [ (gogoproto.moretags) = "yaml:\"plain_text\"" ]; } @@ -106,6 +107,7 @@ message HexAddress { // Value represents the hex address value string value = 1 [ (gogoproto.moretags) = "yaml:\"value\"" ]; - // Prefix represents the optional prefix used during address encoding (e.g. 0x) + // Prefix represents the optional prefix used during address encoding (e.g. + // 0x) string prefix = 2 [ (gogoproto.moretags) = "yaml:\"prefix\"" ]; } \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/genesis.proto b/proto/desmos/subspaces/v1/genesis.proto index 3a84b86e0e..eb71febe06 100644 --- a/proto/desmos/subspaces/v1/genesis.proto +++ b/proto/desmos/subspaces/v1/genesis.proto @@ -11,13 +11,16 @@ message GenesisState { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = true; - repeated desmos.subspaces.v1.Subspace subspaces = 1 + uint64 initial_subspace_id = 1 + [ (gogoproto.customname) = "InitialSubspaceID" ]; + + repeated desmos.subspaces.v1.Subspace subspaces = 2 [ (gogoproto.nullable) = false ]; repeated ACLEntry acl = 3 [ (gogoproto.customname) = "ACL", (gogoproto.nullable) = false ]; - repeated UserGroup user_groups = 2 [ (gogoproto.nullable) = false ]; + repeated UserGroup user_groups = 4 [ (gogoproto.nullable) = false ]; } // ACL represents a single Access Control List entry diff --git a/x/subspaces/client/cli/cli_test.go b/x/subspaces/client/cli/cli_test.go index 175e24e1f1..5174a67051 100644 --- a/x/subspaces/client/cli/cli_test.go +++ b/x/subspaces/client/cli/cli_test.go @@ -43,6 +43,7 @@ func (s *IntegrationTestSuite) SetupSuite() { var subspacesData types.GenesisState s.Require().NoError(cfg.Codec.UnmarshalJSON(genesisState[types.ModuleName], &subspacesData)) + subspacesData.InitialSubspaceID = 3 subspacesData.Subspaces = []types.Subspace{ types.NewSubspace( 1, @@ -167,6 +168,8 @@ func (s *IntegrationTestSuite) TestCmdQuerySubspaces() { { name: "subspaces are returned correctly", args: []string{ + fmt.Sprintf("--%s=%d", flags.FlagLimit, 1), + fmt.Sprintf("--%s=%d", flags.FlagPage, 1), fmt.Sprintf("--%s=json", tmcli.OutputFlag), }, shouldErr: false, @@ -181,15 +184,6 @@ func (s *IntegrationTestSuite) TestCmdQuerySubspaces() { "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), ), - types.NewSubspace( - 2, - "Another test subspace", - "This is another test subspace", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), - ), }, }, }, @@ -352,7 +346,7 @@ func (s *IntegrationTestSuite) TestCmdEditSubspace() { { name: "valid data returns no error", args: []string{ - "1", + "2", fmt.Sprintf("--%s=%s", cli.FlagName, "Edited name"), fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), diff --git a/x/subspaces/keeper/genesis.go b/x/subspaces/keeper/genesis.go index 3651baa7bf..44a5b7ff64 100644 --- a/x/subspaces/keeper/genesis.go +++ b/x/subspaces/keeper/genesis.go @@ -8,7 +8,13 @@ import ( // ExportGenesis returns the GenesisState associated with the given context func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { + subspaceID, err := k.GetSubspaceID(ctx) + if err != nil { + panic(err) + } + return types.NewGenesisState( + subspaceID, k.GetAllSubspaces(ctx), k.GetAllUserGroups(ctx), k.GetAllPermissions(ctx), @@ -54,6 +60,9 @@ func (k Keeper) GetAllUserGroups(ctx sdk.Context) []types.UserGroup { // InitGenesis initializes the chain state based on the given GenesisState func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { + // Set the initial subspace id + k.SetSubspaceID(ctx, data.InitialSubspaceID) + // Initialize the subspaces for _, subspace := range data.Subspaces { k.SaveSubspace(ctx, subspace) diff --git a/x/subspaces/keeper/genesis_test.go b/x/subspaces/keeper/genesis_test.go index f4dae5284d..5cb4d685dc 100644 --- a/x/subspaces/keeper/genesis_test.go +++ b/x/subspaces/keeper/genesis_test.go @@ -14,9 +14,17 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { store func(ctx sdk.Context) expGenesis *types.GenesisState }{ + { + name: "subspace id is exported properly", + store: func(ctx sdk.Context) { + suite.k.SetSubspaceID(ctx, 2) + }, + expGenesis: types.NewGenesisState(2, nil, nil, nil), + }, { name: "subspaces are exported correctly", store: func(ctx sdk.Context) { + suite.k.SetSubspaceID(ctx, 1) suite.k.SaveSubspace(ctx, types.NewSubspace( 1, "Test subspace", @@ -38,6 +46,7 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { )) }, expGenesis: types.NewGenesisState( + 1, []types.Subspace{ types.NewSubspace( 1, @@ -65,6 +74,7 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { { name: "permissions are exported correctly", store: func(ctx sdk.Context) { + suite.k.SetSubspaceID(ctx, 1) suite.k.SaveSubspace(ctx, types.NewSubspace( 1, "Test subspace", @@ -88,6 +98,7 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { suite.k.SetPermissions(ctx, 2, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", types.PermissionSetPermissions) }, expGenesis: types.NewGenesisState( + 1, []types.Subspace{ types.NewSubspace( 1, @@ -118,6 +129,7 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { { name: "user groups are exported properly", store: func(ctx sdk.Context) { + suite.k.SetSubspaceID(ctx, 1) suite.k.SaveSubspace(ctx, types.NewSubspace( 1, "Test subspace", @@ -154,6 +166,7 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { err = suite.k.AddUserToGroup(ctx, 2, "another-group", userAddr) }, expGenesis: types.NewGenesisState( + 1, []types.Subspace{ types.NewSubspace( 1, @@ -214,6 +227,7 @@ func (suite *KeeperTestsuite) TestKeeper_InitGenesis() { { name: "all data is imported properly", genesis: types.GenesisState{ + InitialSubspaceID: 2, Subspaces: []types.Subspace{ types.NewSubspace( 1, @@ -249,6 +263,10 @@ func (suite *KeeperTestsuite) TestKeeper_InitGenesis() { }, }, check: func(ctx sdk.Context) { + subspaceID, err := suite.k.GetSubspaceID(ctx) + suite.Require().NoError(err) + suite.Require().Equal(uint64(2), subspaceID) + subspaces := suite.k.GetAllSubspaces(ctx) suite.Require().Len(subspaces, 2) diff --git a/x/subspaces/simulation/genesis.go b/x/subspaces/simulation/genesis.go index 21b43fc2f4..85e1d6931f 100644 --- a/x/subspaces/simulation/genesis.go +++ b/x/subspaces/simulation/genesis.go @@ -20,7 +20,7 @@ func RandomizeGenState(simState *module.SimulationState) { acl := randomACL(simState.Rand, simState.Accounts, subspaces, groups) // Create the genesis and sanitize it - subspacesGenesis := types.NewGenesisState(subspaces, groups, acl) + subspacesGenesis := types.NewGenesisState(1, subspaces, groups, acl) subspacesGenesis = sanitizeGenesis(subspacesGenesis) simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(subspacesGenesis) @@ -92,6 +92,7 @@ func randomACL(r *rand.Rand, accounts []simtypes.Account, subspaces []types.Subs // groups or ACL entries that might be there func sanitizeGenesis(genesis *types.GenesisState) *types.GenesisState { return types.NewGenesisState( + genesis.InitialSubspaceID, sanitizeSubspaces(genesis.Subspaces), sanitizeUserGroups(genesis.UserGroups), sanitizeACLEntry(genesis.ACL), diff --git a/x/subspaces/types/genesis.go b/x/subspaces/types/genesis.go index 9c673c12ee..4a7f0fd75c 100644 --- a/x/subspaces/types/genesis.go +++ b/x/subspaces/types/genesis.go @@ -56,26 +56,24 @@ func (group UserGroup) Validate() error { // ------------------------------------------------------------------------------------------------------------------- // NewGenesisState creates a new genesis state -func NewGenesisState(subspaces []Subspace, userGroups []UserGroup, acl []ACLEntry) *GenesisState { +func NewGenesisState(initialSubspaceID uint64, subspaces []Subspace, userGroups []UserGroup, acl []ACLEntry) *GenesisState { return &GenesisState{ - Subspaces: subspaces, - UserGroups: userGroups, - ACL: acl, + InitialSubspaceID: initialSubspaceID, + Subspaces: subspaces, + UserGroups: userGroups, + ACL: acl, } } // DefaultGenesisState returns a default GenesisState func DefaultGenesisState() *GenesisState { - return NewGenesisState(nil, nil, nil) + return NewGenesisState(1, nil, nil, nil) } // ValidateGenesis validates the given genesis state and returns an error if something is invalid func ValidateGenesis(data *GenesisState) error { - for _, subspace := range data.Subspaces { - err := subspace.Validate() - if err != nil { - return err - } + if data.InitialSubspaceID == 0 { + return fmt.Errorf("initial subspace id must be greter than 0") } for _, subspace := range data.Subspaces { @@ -89,6 +87,10 @@ func ValidateGenesis(data *GenesisState) error { } } + if data.InitialSubspaceID < uint64(len(data.Subspaces)) { + return fmt.Errorf("initial subspace id must be equals or greter than subspaces count") + } + for _, entry := range data.ACL { err := entry.Validate() if err != nil { diff --git a/x/subspaces/types/genesis.pb.go b/x/subspaces/types/genesis.pb.go index e459f68dd4..8d646b0c3c 100644 --- a/x/subspaces/types/genesis.pb.go +++ b/x/subspaces/types/genesis.pb.go @@ -25,9 +25,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState contains the data of the genesis state for the subspaces module type GenesisState struct { - Subspaces []Subspace `protobuf:"bytes,1,rep,name=subspaces,proto3" json:"subspaces"` - ACL []ACLEntry `protobuf:"bytes,3,rep,name=acl,proto3" json:"acl"` - UserGroups []UserGroup `protobuf:"bytes,2,rep,name=user_groups,json=userGroups,proto3" json:"user_groups"` + InitialSubspaceID uint64 `protobuf:"varint,1,opt,name=initial_subspace_id,json=initialSubspaceId,proto3" json:"initial_subspace_id,omitempty"` + Subspaces []Subspace `protobuf:"bytes,2,rep,name=subspaces,proto3" json:"subspaces"` + ACL []ACLEntry `protobuf:"bytes,3,rep,name=acl,proto3" json:"acl"` + UserGroups []UserGroup `protobuf:"bytes,4,rep,name=user_groups,json=userGroups,proto3" json:"user_groups"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -63,6 +64,13 @@ func (m *GenesisState) XXX_DiscardUnknown() { var xxx_messageInfo_GenesisState proto.InternalMessageInfo +func (m *GenesisState) GetInitialSubspaceID() uint64 { + if m != nil { + return m.InitialSubspaceID + } + return 0 +} + func (m *GenesisState) GetSubspaces() []Subspace { if m != nil { return m.Subspaces @@ -217,32 +225,34 @@ func init() { func init() { proto.RegisterFile("desmos/subspaces/v1/genesis.proto", fileDescriptor_bce8af665337782b) } var fileDescriptor_bce8af665337782b = []byte{ - // 390 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x3f, 0xcf, 0xd2, 0x40, - 0x18, 0xef, 0xbd, 0x25, 0xaf, 0x6f, 0xaf, 0xea, 0x70, 0x1a, 0xd3, 0x90, 0xd8, 0x56, 0xa6, 0x2e, - 0xf6, 0x02, 0x6e, 0xc6, 0x85, 0x22, 0x21, 0x24, 0x4c, 0x25, 0x2e, 0x2e, 0xa4, 0x85, 0x4b, 0x6d, - 0x42, 0x7b, 0xcd, 0x3d, 0x57, 0x22, 0x93, 0x5f, 0xc1, 0xd1, 0x91, 0x8f, 0xc3, 0xc8, 0xe8, 0x44, - 0x48, 0x59, 0xfc, 0x18, 0xa6, 0xff, 0x80, 0x81, 0x98, 0xb8, 0x3d, 0xbf, 0xeb, 0xef, 0x5f, 0x9f, - 0x3c, 0xf8, 0xdd, 0x8a, 0x41, 0xc2, 0x81, 0x42, 0x1e, 0x42, 0x16, 0x2c, 0x19, 0xd0, 0x4d, 0x9f, - 0x46, 0x2c, 0x65, 0x10, 0x83, 0x9b, 0x09, 0x2e, 0x39, 0x79, 0x55, 0x53, 0xdc, 0x0b, 0xc5, 0xdd, - 0xf4, 0xbb, 0xaf, 0x23, 0x1e, 0xf1, 0xea, 0x3b, 0x2d, 0xa7, 0x9a, 0xda, 0xed, 0xdd, 0x73, 0x6b, - 0x41, 0xcd, 0xe9, 0x9d, 0x10, 0x7e, 0x3e, 0xa9, 0x03, 0xe6, 0x32, 0x90, 0x8c, 0x0c, 0xb1, 0x76, - 0xe1, 0x1b, 0xc8, 0x56, 0x1d, 0x7d, 0xf0, 0xd6, 0xbd, 0x93, 0xe9, 0xce, 0x1b, 0xe0, 0x75, 0xf6, - 0x47, 0x4b, 0xf1, 0xaf, 0x2a, 0xf2, 0x09, 0xab, 0xc1, 0x72, 0x6d, 0xa8, 0xff, 0x10, 0x0f, 0x47, - 0xb3, 0x71, 0x2a, 0xc5, 0xd6, 0xd3, 0x4b, 0x71, 0x71, 0xb4, 0xd4, 0xe1, 0x68, 0xe6, 0x97, 0x32, - 0x32, 0xc6, 0x7a, 0x0e, 0x4c, 0x2c, 0x22, 0xc1, 0xf3, 0x0c, 0x8c, 0x87, 0xca, 0xc5, 0xbc, 0xeb, - 0xf2, 0x05, 0x98, 0x98, 0x94, 0xb4, 0xa6, 0x03, 0xce, 0xdb, 0x07, 0xf8, 0xf8, 0xf4, 0x6b, 0x67, - 0xa1, 0x3f, 0x3b, 0x0b, 0xf5, 0x7e, 0xe0, 0xa7, 0x36, 0x8e, 0x50, 0xac, 0xb7, 0x0e, 0x8b, 0x78, - 0x65, 0x20, 0x1b, 0x39, 0x1d, 0xef, 0x65, 0x71, 0xb4, 0x70, 0xfb, 0x3b, 0xd3, 0xcf, 0x3e, 0x6e, - 0x29, 0xd3, 0x15, 0x79, 0x83, 0x1f, 0x65, 0x20, 0x22, 0x26, 0x8d, 0x07, 0x1b, 0x39, 0x9a, 0xdf, - 0x20, 0x62, 0x63, 0x3d, 0x63, 0x22, 0x89, 0x01, 0x62, 0x9e, 0x82, 0xa1, 0xda, 0xc8, 0x79, 0xe1, - 0xdf, 0x3e, 0xdd, 0x14, 0x90, 0x58, 0xbb, 0x34, 0xfd, 0xff, 0x06, 0x04, 0x77, 0xd2, 0x20, 0x61, - 0x4d, 0x7e, 0x35, 0x13, 0x03, 0x3f, 0x4b, 0x58, 0x12, 0x32, 0x01, 0xd5, 0x96, 0x35, 0xbf, 0x85, - 0xd7, 0x54, 0x6f, 0xb6, 0x2f, 0x4c, 0x74, 0x28, 0x4c, 0x74, 0x2a, 0x4c, 0xf4, 0xf3, 0x6c, 0x2a, - 0x87, 0xb3, 0xa9, 0xfc, 0x3e, 0x9b, 0xca, 0xd7, 0x41, 0x14, 0xcb, 0x6f, 0x79, 0xe8, 0x2e, 0x79, - 0x42, 0xeb, 0xb5, 0xbe, 0x5f, 0x07, 0x21, 0x34, 0x33, 0xdd, 0x0c, 0xe8, 0xf7, 0x9b, 0x9b, 0x91, - 0xdb, 0x8c, 0x41, 0xf8, 0x58, 0x9d, 0xcb, 0x87, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x22, 0xa6, - 0x52, 0xfa, 0xa2, 0x02, 0x00, 0x00, + // 420 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x4d, 0x8b, 0xd3, 0x50, + 0x14, 0xed, 0x6b, 0xca, 0x38, 0xbd, 0x51, 0x61, 0xde, 0xa8, 0x84, 0x01, 0x93, 0xd8, 0x55, 0x37, + 0xe6, 0x31, 0x75, 0x27, 0x6e, 0xda, 0xb1, 0x0c, 0x03, 0x5d, 0x65, 0x70, 0xe3, 0xa6, 0x24, 0xed, + 0x23, 0x3e, 0x68, 0xf2, 0xc2, 0xbb, 0x2f, 0xc5, 0x59, 0xf9, 0x17, 0x5c, 0xba, 0x9c, 0x9d, 0x7f, + 0x65, 0x96, 0x5d, 0xba, 0x2a, 0x92, 0x6e, 0xfc, 0x19, 0x92, 0xaf, 0x36, 0x68, 0x11, 0xdc, 0xdd, + 0x8f, 0x73, 0xee, 0x39, 0x1c, 0x2e, 0xbc, 0x5a, 0x72, 0x8c, 0x25, 0x32, 0xcc, 0x42, 0x4c, 0x83, + 0x05, 0x47, 0xb6, 0xbe, 0x64, 0x11, 0x4f, 0x38, 0x0a, 0xf4, 0x52, 0x25, 0xb5, 0xa4, 0xe7, 0x15, + 0xc4, 0xdb, 0x43, 0xbc, 0xf5, 0xe5, 0xc5, 0xb3, 0x48, 0x46, 0xb2, 0xdc, 0xb3, 0xa2, 0xaa, 0xa0, + 0x17, 0x83, 0x63, 0xd7, 0x9a, 0xa6, 0xc2, 0x0c, 0xbe, 0x77, 0xe1, 0xf1, 0x75, 0x25, 0x70, 0xab, + 0x03, 0xcd, 0xe9, 0x14, 0xce, 0x45, 0x22, 0xb4, 0x08, 0x56, 0xf3, 0x06, 0x3a, 0x17, 0x4b, 0x8b, + 0xb8, 0x64, 0xd8, 0x9b, 0x3c, 0xcf, 0xb7, 0xce, 0xd9, 0x4d, 0xb5, 0xbe, 0xad, 0xb7, 0x37, 0xef, + 0xfd, 0x33, 0xf1, 0xc7, 0x68, 0x49, 0xc7, 0xd0, 0xdf, 0xcb, 0x5a, 0x5d, 0xd7, 0x18, 0x9a, 0xa3, + 0x97, 0xde, 0x11, 0xeb, 0x5e, 0xc3, 0x99, 0xf4, 0x1e, 0xb6, 0x4e, 0xc7, 0x3f, 0xb0, 0xe8, 0x3b, + 0x30, 0x82, 0xc5, 0xca, 0x32, 0xfe, 0x41, 0x1e, 0x5f, 0xcd, 0xa6, 0x89, 0x56, 0x77, 0x13, 0xb3, + 0x20, 0xe7, 0x5b, 0xc7, 0x18, 0x5f, 0xcd, 0xfc, 0x82, 0x46, 0xa7, 0x60, 0x66, 0xc8, 0xd5, 0x3c, + 0x52, 0x32, 0x4b, 0xd1, 0xea, 0x95, 0x57, 0xec, 0xa3, 0x57, 0x3e, 0x20, 0x57, 0xd7, 0x05, 0xac, + 0xf6, 0x00, 0x59, 0x33, 0xc0, 0xb7, 0xa7, 0xdf, 0xee, 0x1d, 0xf2, 0xeb, 0xde, 0x21, 0x83, 0x2f, + 0x70, 0xda, 0xc8, 0x51, 0x06, 0xe6, 0xdf, 0xe1, 0x3c, 0xcd, 0xb7, 0x0e, 0xb4, 0x52, 0x01, 0x3c, + 0xc4, 0xf1, 0x02, 0x4e, 0x74, 0xa0, 0x22, 0xae, 0xad, 0xae, 0x4b, 0x86, 0x7d, 0xbf, 0xee, 0xa8, + 0x0b, 0x66, 0xca, 0x55, 0x2c, 0x10, 0x85, 0x4c, 0xd0, 0x32, 0x5c, 0x32, 0x7c, 0xe2, 0xb7, 0x47, + 0x2d, 0x03, 0x1a, 0xfa, 0x7b, 0xa7, 0xff, 0xef, 0x80, 0x42, 0x2f, 0x09, 0x62, 0x5e, 0xeb, 0x97, + 0x35, 0xb5, 0xe0, 0x51, 0xcc, 0xe3, 0x90, 0x2b, 0x2c, 0x53, 0xee, 0xfb, 0x4d, 0x7b, 0x50, 0x9d, + 0xcc, 0x1e, 0x72, 0x9b, 0x6c, 0x72, 0x9b, 0xfc, 0xcc, 0x6d, 0xf2, 0x75, 0x67, 0x77, 0x36, 0x3b, + 0xbb, 0xf3, 0x63, 0x67, 0x77, 0x3e, 0x8e, 0x22, 0xa1, 0x3f, 0x65, 0xa1, 0xb7, 0x90, 0x31, 0xab, + 0x62, 0x7d, 0xbd, 0x0a, 0x42, 0xac, 0x6b, 0xb6, 0x1e, 0xb1, 0xcf, 0xad, 0xd7, 0xd3, 0x77, 0x29, + 0xc7, 0xf0, 0xa4, 0xfc, 0xba, 0x37, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x14, 0x3f, 0x01, 0x14, + 0xe9, 0x02, 0x00, 0x00, } func (this *GenesisState) Equal(that interface{}) bool { @@ -264,6 +274,9 @@ func (this *GenesisState) Equal(that interface{}) bool { } else if this == nil { return false } + if this.InitialSubspaceID != that1.InitialSubspaceID { + return false + } if len(this.Subspaces) != len(that1.Subspaces) { return false } @@ -375,10 +388,10 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.ACL) > 0 { - for iNdEx := len(m.ACL) - 1; iNdEx >= 0; iNdEx-- { + if len(m.UserGroups) > 0 { + for iNdEx := len(m.UserGroups) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.ACL[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.UserGroups[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -386,13 +399,13 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x1a + dAtA[i] = 0x22 } } - if len(m.UserGroups) > 0 { - for iNdEx := len(m.UserGroups) - 1; iNdEx >= 0; iNdEx-- { + if len(m.ACL) > 0 { + for iNdEx := len(m.ACL) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.UserGroups[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.ACL[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -400,7 +413,7 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a } } if len(m.Subspaces) > 0 { @@ -414,9 +427,14 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintGenesis(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0xa + dAtA[i] = 0x12 } } + if m.InitialSubspaceID != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.InitialSubspaceID)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } @@ -521,20 +539,23 @@ func (m *GenesisState) Size() (n int) { } var l int _ = l + if m.InitialSubspaceID != 0 { + n += 1 + sovGenesis(uint64(m.InitialSubspaceID)) + } if len(m.Subspaces) > 0 { for _, e := range m.Subspaces { l = e.Size() n += 1 + l + sovGenesis(uint64(l)) } } - if len(m.UserGroups) > 0 { - for _, e := range m.UserGroups { + if len(m.ACL) > 0 { + for _, e := range m.ACL { l = e.Size() n += 1 + l + sovGenesis(uint64(l)) } } - if len(m.ACL) > 0 { - for _, e := range m.ACL { + if len(m.UserGroups) > 0 { + for _, e := range m.UserGroups { l = e.Size() n += 1 + l + sovGenesis(uint64(l)) } @@ -619,6 +640,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InitialSubspaceID", wireType) + } + m.InitialSubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.InitialSubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Subspaces", wireType) } @@ -652,9 +692,9 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex - case 2: + case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UserGroups", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ACL", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -681,14 +721,14 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.UserGroups = append(m.UserGroups, UserGroup{}) - if err := m.UserGroups[len(m.UserGroups)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.ACL = append(m.ACL, ACLEntry{}) + if err := m.ACL[len(m.ACL)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - case 3: + case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field ACL", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UserGroups", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -715,8 +755,8 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.ACL = append(m.ACL, ACLEntry{}) - if err := m.ACL[len(m.ACL)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.UserGroups = append(m.UserGroups, UserGroup{}) + if err := m.UserGroups[len(m.UserGroups)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/subspaces/types/genesis_test.go b/x/subspaces/types/genesis_test.go index aa951b370b..4e319f306f 100644 --- a/x/subspaces/types/genesis_test.go +++ b/x/subspaces/types/genesis_test.go @@ -108,9 +108,44 @@ func TestValidateGenesis(t *testing.T) { genesis *types.GenesisState shouldErr bool }{ + { + name: "invalid subspace id returns error (zero)", + genesis: types.NewGenesisState(0, nil, nil, nil), + shouldErr: true, + }, + { + name: "invalid subspace id returns error (too low)", + genesis: types.NewGenesisState( + 1, + []types.Subspace{ + types.NewSubspace( + 1, + "", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + types.NewSubspace( + 1, + "Another test subspace", + "This is another test subspace", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + nil, + nil, + ), + shouldErr: true, + }, { name: "invalid subspace returns error", genesis: types.NewGenesisState( + 1, []types.Subspace{ types.NewSubspace( 1, @@ -130,6 +165,7 @@ func TestValidateGenesis(t *testing.T) { { name: "duplicated subspace returns error", genesis: types.NewGenesisState( + 3, []types.Subspace{ types.NewSubspace( 1, @@ -158,6 +194,7 @@ func TestValidateGenesis(t *testing.T) { { name: "invalid ACL entry returns error", genesis: types.NewGenesisState( + 1, nil, nil, []types.ACLEntry{ @@ -169,6 +206,7 @@ func TestValidateGenesis(t *testing.T) { { name: "duplicated ACL entry returns error", genesis: types.NewGenesisState( + 1, nil, nil, []types.ACLEntry{ @@ -181,6 +219,7 @@ func TestValidateGenesis(t *testing.T) { { name: "invalid group returns error", genesis: types.NewGenesisState( + 1, nil, []types.UserGroup{ types.NewUserGroup(0, "group", nil), @@ -192,6 +231,7 @@ func TestValidateGenesis(t *testing.T) { { name: "duplicated group returns error", genesis: types.NewGenesisState( + 1, nil, []types.UserGroup{ types.NewUserGroup(1, "group", nil), @@ -209,6 +249,7 @@ func TestValidateGenesis(t *testing.T) { { name: "valid genesis state returns no error", genesis: types.NewGenesisState( + 3, []types.Subspace{ types.NewSubspace( 1, From c7006d34fb958178ca831bbfafc7482e2178b148 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 24 Jan 2022 15:57:51 +0100 Subject: [PATCH 14/47] fixed simulation tests Signed-off-by: Riccardo Montagnin --- app/sim_test.go | 6 +- x/subspaces/simulation/genesis.go | 4 +- x/subspaces/simulation/operations_groups.go | 67 +++++++++---------- .../simulation/operations_permissions.go | 7 +- .../simulation/operations_subspaces.go | 16 ++--- 5 files changed, 51 insertions(+), 49 deletions(-) diff --git a/app/sim_test.go b/app/sim_test.go index 016a53eb7c..4c3cd81158 100644 --- a/app/sim_test.go +++ b/app/sim_test.go @@ -8,6 +8,8 @@ import ( "path/filepath" "testing" + subspacestypes "github.com/desmos-labs/desmos/v2/x/subspaces/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types" @@ -217,10 +219,12 @@ func TestAppImportExport(t *testing.T) { {app.keys[govtypes.StoreKey], newApp.keys[govtypes.StoreKey], [][]byte{}}, {app.keys[evidencetypes.StoreKey], newApp.keys[evidencetypes.StoreKey], [][]byte{}}, - {app.keys[profilestypes.StoreKey], newApp.keys[profilestypes.StoreKey], [][]byte{}}, {app.keys[capabilitytypes.StoreKey], newApp.keys[capabilitytypes.StoreKey], [][]byte{}}, {app.keys[ibchost.StoreKey], newApp.keys[ibchost.StoreKey], [][]byte{}}, {app.keys[ibctransfertypes.StoreKey], newApp.keys[ibctransfertypes.StoreKey], [][]byte{}}, + + {app.keys[subspacestypes.StoreKey], newApp.keys[subspacestypes.StoreKey], [][]byte{}}, + {app.keys[profilestypes.StoreKey], newApp.keys[profilestypes.StoreKey], [][]byte{}}, } for _, skp := range storeKeysPrefixes { diff --git a/x/subspaces/simulation/genesis.go b/x/subspaces/simulation/genesis.go index 85e1d6931f..ee8ceae456 100644 --- a/x/subspaces/simulation/genesis.go +++ b/x/subspaces/simulation/genesis.go @@ -68,7 +68,9 @@ func randomACL(r *rand.Rand, accounts []simtypes.Account, subspaces []types.Subs // 50% of chance of selecting a group rather than an account if r.Intn(101) <= 50 { - target = RandomGroup(r, groups).Name + if len(groups) > 0 { + target = RandomGroup(r, groups).Name + } } // Get a random permission diff --git a/x/subspaces/simulation/operations_groups.go b/x/subspaces/simulation/operations_groups.go index 94a1b65516..26f46a218f 100644 --- a/x/subspaces/simulation/operations_groups.go +++ b/x/subspaces/simulation/operations_groups.go @@ -116,22 +116,19 @@ func SimulateMsgDeleteUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk func randomDeleteUserGroupFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, ) (subspaceID uint64, groupName string, account simtypes.Account, skip bool) { - // Get a subspace id - subspaces := k.GetAllSubspaces(ctx) - if len(subspaces) == 0 { - // Skip because there are no subspaces + // Get a group + groups := k.GetAllUserGroups(ctx) + if len(groups) == 0 { + // Skip if there are no groups skip = true return } - subspace, _ := RandomSubspace(r, subspaces) - subspaceID = subspace.ID - - // Get a group name - groups := k.GetSubspaceGroups(ctx, subspace.ID) - groupName = RandomString(r, groups) + group := RandomGroup(r, groups) + subspaceID = group.SubspaceID + groupName = group.Name // Get a signer - signers, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionManageGroups) + signers, _ := k.GetUsersWithPermission(ctx, subspaceID, types.PermissionManageGroups) acc := GetAccount(RandomAddress(r, signers), accs) if acc == nil { // Skip the operation without error as the account is not valid @@ -175,24 +172,21 @@ func SimulateMsgAddUserToUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, func randomAddUserToUserGroupFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, ak authkeeper.AccountKeeper, ) (subspaceID uint64, groupName string, user string, account simtypes.Account, skip bool) { - // Get a subspace id - subspaces := k.GetAllSubspaces(ctx) - if len(subspaces) == 0 { - // Skip because there are no subspaces + // Get a group + groups := k.GetAllUserGroups(ctx) + if len(groups) == 0 { + // Skip if there are no groups skip = true return } - subspace, _ := RandomSubspace(r, subspaces) - subspaceID = subspace.ID - - // Get a group - groups := k.GetSubspaceGroups(ctx, subspace.ID) - groupName = RandomString(r, groups) + group := RandomGroup(r, groups) + subspaceID = group.SubspaceID + groupName = group.Name // Get a user accounts := ak.GetAllAccounts(ctx) userAccount := RandomAuthAccount(r, accounts) - if k.IsMemberOfGroup(ctx, subspace.ID, groupName, userAccount.GetAddress()) { + if k.IsMemberOfGroup(ctx, subspaceID, groupName, userAccount.GetAddress()) { // Skip if the user is already part of group skip = true return @@ -200,7 +194,7 @@ func randomAddUserToUserGroupFields( user = userAccount.GetAddress().String() // Get a signer - signers, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionSetPermissions) + signers, _ := k.GetUsersWithPermission(ctx, subspaceID, types.PermissionSetPermissions) acc := GetAccount(RandomAddress(r, signers), accs) if acc == nil { // Skip the operation without error as the account is not valid @@ -244,26 +238,29 @@ func SimulateMsgRemoveUserFromUserGroup(k keeper.Keeper, ak authkeeper.AccountKe func randomRemoveUserFromUserGroupFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, ) (subspaceID uint64, groupName string, user string, account simtypes.Account, skip bool) { - // Get a subspace id - subspaces := k.GetAllSubspaces(ctx) - if len(subspaces) == 0 { - // Skip because there are no subspaces + // Get a group + groups := k.GetAllUserGroups(ctx) + if len(groups) == 0 { + // Skip if there are no groups skip = true return } - subspace, _ := RandomSubspace(r, subspaces) - subspaceID = subspace.ID - - // Get a group - groups := k.GetSubspaceGroups(ctx, subspace.ID) - groupName = RandomString(r, groups) + group := RandomGroup(r, groups) + subspaceID = group.SubspaceID + groupName = group.Name // Get a user - members := k.GetGroupMembers(ctx, subspace.ID, groupName) + members := k.GetGroupMembers(ctx, subspaceID, groupName) + if len(members) == 0 { + // Skip if there are no member groups to remove + skip = true + return + } + user = RandomAddress(r, members).String() // Get a signer - signers, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionSetPermissions) + signers, _ := k.GetUsersWithPermission(ctx, subspaceID, types.PermissionSetPermissions) acc := GetAccount(RandomAddress(r, signers), accs) if acc == nil { // Skip the operation without error as the account is not valid diff --git a/x/subspaces/simulation/operations_permissions.go b/x/subspaces/simulation/operations_permissions.go index 007c6222ec..2676f6c34c 100644 --- a/x/subspaces/simulation/operations_permissions.go +++ b/x/subspaces/simulation/operations_permissions.go @@ -57,10 +57,9 @@ func randomSetPermissionsFields( subspaceID = subspace.ID // Get a target - accounts := ak.GetAllAccounts(ctx) - var targets = make([]string, len(accounts)) - for i, account := range accounts { - targets[i] = account.String() + targets := make([]string, len(accs)) + for i, acc := range accs { + targets[i] = acc.Address.String() } targets = append(targets, k.GetSubspaceGroups(ctx, subspace.ID)...) target = RandomString(r, targets) diff --git a/x/subspaces/simulation/operations_subspaces.go b/x/subspaces/simulation/operations_subspaces.go index 996b5af772..bf0121e4b1 100644 --- a/x/subspaces/simulation/operations_subspaces.go +++ b/x/subspaces/simulation/operations_subspaces.go @@ -128,14 +128,6 @@ func randomEditSubspaceFields( subspace, _ := RandomSubspace(r, subspaces) subspaceID = subspace.ID - // Build the update data - update = types.NewSubspaceUpdate( - RandomName(r), - RandomDescription(r), - account.Address.String(), - account.Address.String(), - ) - // Get an editor editors, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionChangeInfo) acc := GetAccount(RandomAddress(r, editors), accs) @@ -146,5 +138,13 @@ func randomEditSubspaceFields( } account = *acc + // Build the update data + update = types.NewSubspaceUpdate( + RandomName(r), + RandomDescription(r), + account.Address.String(), + account.Address.String(), + ) + return subspaceID, update, account, false } From 2b04da8c3d5d85fe690006f79bc942b0a6fa0584 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 24 Jan 2022 16:01:06 +0100 Subject: [PATCH 15/47] added changeset entry for x/profiles Signed-off-by: Riccardo Montagnin --- ...13668455bb550707d515b63dd90fceb597e339f5e732b702bbb.yaml | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/entries/1fd815be9372a13668455bb550707d515b63dd90fceb597e339f5e732b702bbb.yaml diff --git a/.changeset/entries/1fd815be9372a13668455bb550707d515b63dd90fceb597e339f5e732b702bbb.yaml b/.changeset/entries/1fd815be9372a13668455bb550707d515b63dd90fceb597e339f5e732b702bbb.yaml new file mode 100644 index 0000000000..b90ab99635 --- /dev/null +++ b/.changeset/entries/1fd815be9372a13668455bb550707d515b63dd90fceb597e339f5e732b702bbb.yaml @@ -0,0 +1,6 @@ +type: refactor +module: x/profiles +pull_request: 728 +description: Changed the subspace id type from string to uint64 +backward_compatible: false +date: 2022-01-24T15:00:42.365992872Z From d28fef6d72a2e189c1f262d2610071175394532b Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 24 Jan 2022 16:05:58 +0100 Subject: [PATCH 16/47] fixed formatting Signed-off-by: Riccardo Montagnin --- x/subspaces/simulation/operations_permissions.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/subspaces/simulation/operations_permissions.go b/x/subspaces/simulation/operations_permissions.go index 2676f6c34c..f7440fc73c 100644 --- a/x/subspaces/simulation/operations_permissions.go +++ b/x/subspaces/simulation/operations_permissions.go @@ -24,7 +24,7 @@ func SimulateMsgSetPermissions(k keeper.Keeper, ak authkeeper.AccountKeeper, bk ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { // Get the data - subspaceID, target, permissions, creator, skip := randomSetPermissionsFields(r, ctx, accs, k, ak) + subspaceID, target, permissions, creator, skip := randomSetPermissionsFields(r, ctx, accs, k) if skip { return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgSetPermissions"), nil, nil } @@ -44,7 +44,7 @@ func SimulateMsgSetPermissions(k keeper.Keeper, ak authkeeper.AccountKeeper, bk // randomSetPermissionsFields returns the data used to build a random MsgSetPermissions func randomSetPermissionsFields( - r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, ak authkeeper.AccountKeeper, + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, ) (subspaceID uint64, target string, permissions types.Permission, account simtypes.Account, skip bool) { // Get a subspace id subspaces := k.GetAllSubspaces(ctx) From 5a557c3eaa02fd3c71064c54a86628785a5687f5 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Tue, 25 Jan 2022 14:46:58 +0100 Subject: [PATCH 17/47] added migration for both modules Signed-off-by: Riccardo Montagnin --- app/app.go | 12 +- client/docs/swagger-ui/swagger.yaml | 1419 ++++++++++++++--- .../legacy/v230/models_relationships.proto | 40 + x/profiles/keeper/migrations.go | 9 +- .../legacy/v230/models_chain_links.pb.go | 6 +- .../legacy/v230/models_relationships.pb.go | 832 ++++++++++ x/profiles/legacy/v300/store.go | 112 ++ x/profiles/module.go | 6 +- 8 files changed, 2244 insertions(+), 192 deletions(-) create mode 100644 proto/desmos/profiles/legacy/v230/models_relationships.proto create mode 100644 x/profiles/legacy/v230/models_relationships.pb.go create mode 100644 x/profiles/legacy/v300/store.go diff --git a/app/app.go b/app/app.go index e327c9d4a8..2f71834d04 100644 --- a/app/app.go +++ b/app/app.go @@ -780,7 +780,8 @@ func (app *DesmosApp) RegisterTendermintService(clientCtx client.Context) { } func (app *DesmosApp) registerUpgradeHandlers() { - app.UpgradeKeeper.SetUpgradeHandler("v2.3.1", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + app.UpgradeKeeper.SetUpgradeHandler("v3.0.0", func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) { + // Nothing to do here for the x/subspaces module since the InitGenesis will be called return app.mm.RunMigrations(ctx, app.configurator, fromVM) }) @@ -789,8 +790,13 @@ func (app *DesmosApp) registerUpgradeHandlers() { panic(err) } - if upgradeInfo.Name == "v2.3.1" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { - storeUpgrades := storetypes.StoreUpgrades{} + if upgradeInfo.Name == "v3.0.0" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + storeUpgrades := storetypes.StoreUpgrades{ + Added: []string{ + wasm.ModuleName, + subspacestypes.ModuleName, + }, + } // Configure store loader that checks if version == upgradeHeight and applies store upgrades app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index dadc3f30c3..4e3b120d2a 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -2,7 +2,7 @@ swagger: '2.0' info: title: Desmos - REST and gRPC Gateway docs description: A REST interface for state queries - version: 1.0.0 + version: 3.0.0 paths: '/desmos/profiles/v1beta1/app-links/clients/{client_id}': get: @@ -730,6 +730,9 @@ paths: description: >- reverse is set to true if results are to be returned in the descending order. + + + Since: cosmos-sdk 0.43 in: query required: false type: boolean @@ -1471,7 +1474,183 @@ paths: prove the ownership signature: - type: string + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the + type of the serialized + + protocol buffer message. This string must + contain at least + + one "/" character. The last segment of the URL's + path must represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name + should be in a canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the + binary all types that they + + expect it to use in the context of Any. However, + for URLs which use the + + scheme `http`, `https`, or no scheme, one can + optionally set up a type + + server that maps type URLs to message + definitions as follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup + results based on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently + available in the official + + protobuf release, and it is not used for type + URLs beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty + scheme) might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of + the above specified type. + description: >- + `Any` contains an arbitrary serialized protocol + buffer message along with a + + URL that describes the type of the serialized + message. + + + Protobuf library provides support to pack/unpack Any + values in the form + + of utility functions or additional generated methods + of the Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will + by default use + + 'type.googleapis.com/full.type.name' as the type URL + and the unpack + + methods only use the fully qualified type name after + the last '/' + + in the type URL, for example "foo.bar.com/x/y.z" + will yield type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the + regular + + representation of the deserialized, embedded + message, with an + + additional field `@type` which contains the type + URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a + custom JSON + + representation, that representation will be embedded + adding a field + + `value` which holds the custom JSON in addition to + the `@type` + + field. Example (for message + [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } title: >- Signature represents the hex-encoded signature of the PlainText value @@ -1479,7 +1658,9 @@ paths: type: string title: >- PlainText represents the hex-encoded value signed in - order to produce the Signature + order to produce the + + Signature chain_config: title: >- ChainConfig contains the configuration of the external @@ -1778,6 +1959,9 @@ paths: description: >- reverse is set to true if results are to be returned in the descending order. + + + Since: cosmos-sdk 0.43 in: query required: false type: boolean @@ -2171,70 +2355,247 @@ paths: prove the ownership signature: - type: string - title: >- - Signature represents the hex-encoded signature of the - PlainText value - plain_text: - type: string - title: >- - PlainText represents the hex-encoded value signed in - order to produce the Signature - chain_config: - title: >- - ChainConfig contains the configuration of the external - chain - type: object - properties: - name: - type: string - description: >- - ChainConfig contains the data of the chain with which the - link is made. - creation_time: - type: string - format: date-time - title: >- - CreationTime represents the time in which the link has - been created - title: >- - ChainLink contains the data representing either an inter- or - cross- chain + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the + type of the serialized - link - title: >- - QueryUserChainLinkResponse contains the data that is returned when - querying a + protocol buffer message. This string must contain + at least - specific chain link - default: - description: An unexpected error response - schema: - type: object - properties: - error: - type: string - code: - type: integer - format: int32 - message: - type: string - details: - type: array - items: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of - the serialized + one "/" character. The last segment of the URL's + path must represent - protocol buffer message. This string must contain at - least + the fully qualified name of the type (as in - one "/" character. The last segment of the URL's path - must represent + `path/google.protobuf.Duration`). The name should + be in a canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the + binary all types that they + + expect it to use in the context of Any. However, + for URLs which use the + + scheme `http`, `https`, or no scheme, one can + optionally set up a type + + server that maps type URLs to message definitions + as follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results + based on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently + available in the official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty + scheme) might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the + above specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer + message along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any + values in the form + + of utility functions or additional generated methods + of the Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by + default use + + 'type.googleapis.com/full.type.name' as the type URL + and the unpack + + methods only use the fully qualified type name after + the last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will + yield type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the + regular + + representation of the deserialized, embedded message, + with an + + additional field `@type` which contains the type URL. + Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a + custom JSON + + representation, that representation will be embedded + adding a field + + `value` which holds the custom JSON in addition to the + `@type` + + field. Example (for message + [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + title: >- + Signature represents the hex-encoded signature of the + PlainText value + plain_text: + type: string + title: >- + PlainText represents the hex-encoded value signed in + order to produce the + + Signature + chain_config: + title: >- + ChainConfig contains the configuration of the external + chain + type: object + properties: + name: + type: string + description: >- + ChainConfig contains the data of the chain with which the + link is made. + creation_time: + type: string + format: date-time + title: >- + CreationTime represents the time in which the link has + been created + title: >- + ChainLink contains the data representing either an inter- or + cross- chain + + link + title: >- + QueryUserChainLinkResponse contains the data that is returned when + querying a + + specific chain link + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at + least + + one "/" character. The last segment of the URL's path + must represent the fully qualified name of the type (as in @@ -2747,6 +3108,9 @@ paths: description: >- reverse is set to true if results are to be returned in the descending order. + + + Since: cosmos-sdk 0.43 in: query required: false type: boolean @@ -3481,6 +3845,7 @@ paths: blocked for. subspace: type: string + format: uint64 title: >- Subspace contains the ID of the subspace inside which the user should be @@ -3720,6 +4085,7 @@ paths: in: query required: false type: string + format: uint64 - name: pagination.key description: |- key is a value returned in PageResponse.next_key to begin @@ -3771,6 +4137,9 @@ paths: description: >- reverse is set to true if results are to be returned in the descending order. + + + Since: cosmos-sdk 0.43 in: query required: false type: boolean @@ -3800,6 +4169,7 @@ paths: type: string subspace: type: string + format: uint64 description: >- Relationship is the struct of a relationship. @@ -4035,6 +4405,7 @@ paths: in: query required: false type: string + format: uint64 - name: pagination.key description: |- key is a value returned in PageResponse.next_key to begin @@ -4086,6 +4457,9 @@ paths: description: >- reverse is set to true if results are to be returned in the descending order. + + + Since: cosmos-sdk 0.43 in: query required: false type: boolean @@ -4137,6 +4511,9 @@ definitions: description: >- reverse is set to true if results are to be returned in the descending order. + + + Since: cosmos-sdk 0.43 description: |- message SomeRequest { Foo some_parameter = 1; @@ -4651,32 +5028,197 @@ definitions: prove the ownership signature: - type: string - title: >- - Signature represents the hex-encoded signature of the PlainText - value - plain_text: - type: string - title: >- - PlainText represents the hex-encoded value signed in order to - produce the Signature - chain_config: - title: ChainConfig contains the configuration of the external chain - type: object - properties: - name: - type: string - description: >- - ChainConfig contains the data of the chain with which the link is - made. - creation_time: - type: string - format: date-time - title: CreationTime represents the time in which the link has been created - title: |- - ChainLink contains the data representing either an inter- or cross- chain - link - desmos.profiles.v1beta1.DTagParams: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of the + serialized + + protocol buffer message. This string must contain at least + + one "/" character. The last segment of the URL's path must + represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in a + canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary all + types that they + + expect it to use in the context of Any. However, for URLs + which use the + + scheme `http`, `https`, or no scheme, one can optionally set + up a type + + server that maps type URLs to message definitions as follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based on + the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in the + official + + protobuf release, and it is not used for type URLs beginning + with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) might + be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer message + along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values in the + form + + of utility functions or additional generated methods of the Any + type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by default use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with an + + additional field `@type` which contains the type URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom JSON + + representation, that representation will be embedded adding a + field + + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + title: >- + Signature represents the hex-encoded signature of the PlainText + value + plain_text: + type: string + title: >- + PlainText represents the hex-encoded value signed in order to + produce the + + Signature + chain_config: + title: ChainConfig contains the configuration of the external chain + type: object + properties: + name: + type: string + description: >- + ChainConfig contains the data of the chain with which the link is + made. + creation_time: + type: string + format: date-time + title: CreationTime represents the time in which the link has been created + title: |- + ChainLink contains the data representing either an inter- or cross- chain + link + desmos.profiles.v1beta1.DTagParams: type: object properties: reg_ex: @@ -4902,54 +5444,218 @@ definitions: MinCount represents the minimum count of oracles that should complete the - verification successfully - prepare_gas: - type: string - format: uint64 - title: >- - PrepareGas represents the amount of gas to be used during the - preparation + verification successfully + prepare_gas: + type: string + format: uint64 + title: >- + PrepareGas represents the amount of gas to be used during the + preparation + + stage of the oracle script + execute_gas: + type: string + format: uint64 + title: >- + ExecuteGas represents the amount of gas to be used during the + execution of + + the oracle script + fee_amount: + type: array + items: + type: object + properties: + denom: + type: string + amount: + type: string + description: >- + Coin defines a token with a denomination and an amount. + + + NOTE: The amount field is an Int which implements the custom + method + + signatures required by gogoproto. + title: >- + FeeAmount represents the amount of fees to be payed in order to + execute the + + oracle script + title: |- + OracleParams defines the parameters related to the oracle + that will be used to verify the ownership of a centralized + application account by a Desmos profile + title: Params contains the parameters for the profiles module + desmos.profiles.v1beta1.Proof: + type: object + properties: + pub_key: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of the + serialized + + protocol buffer message. This string must contain at least + + one "/" character. The last segment of the URL's path must + represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in a + canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary all types + that they + + expect it to use in the context of Any. However, for URLs which + use the + + scheme `http`, `https`, or no scheme, one can optionally set up a + type + + server that maps type URLs to message definitions as follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in the + official + + protobuf release, and it is not used for type URLs beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above specified + type. + description: >- + `Any` contains an arbitrary serialized protocol buffer message along + with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values in the + form + + of utility functions or additional generated methods of the Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by default use + + 'type.googleapis.com/full.type.name' as the type URL and the unpack + + methods only use the fully qualified type name after the last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with an - stage of the oracle script - execute_gas: - type: string - format: uint64 - title: >- - ExecuteGas represents the amount of gas to be used during the - execution of + additional field `@type` which contains the type URL. Example: - the oracle script - fee_amount: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } - NOTE: The amount field is an Int which implements the custom - method + If the embedded message type is well-known and has a custom JSON - signatures required by gogoproto. - title: >- - FeeAmount represents the amount of fees to be payed in order to - execute the + representation, that representation will be embedded adding a field - oracle script - title: |- - OracleParams defines the parameters related to the oracle - that will be used to verify the ownership of a centralized - application account by a Desmos profile - title: Params contains the parameters for the profiles module - desmos.profiles.v1beta1.Proof: - type: object - properties: - pub_key: + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + title: >- + PubKey represents the public key associated with the address for which + to + + prove the ownership + signature: type: object properties: type_url: @@ -5108,19 +5814,14 @@ definitions: "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } - title: >- - PubKey represents the public key associated with the address for which - to - - prove the ownership - signature: - type: string title: Signature represents the hex-encoded signature of the PlainText value plain_text: type: string title: >- PlainText represents the hex-encoded value signed in order to produce - the Signature + the + + Signature title: |- Proof contains all the data used to verify a signature when linking an account to a profile @@ -5389,6 +6090,7 @@ definitions: for. subspace: type: string + format: uint64 title: >- Subspace contains the ID of the subspace inside which the user should be @@ -5566,57 +6268,237 @@ definitions: methods only use the fully qualified type name after the last '/' - in the type URL, for example "foo.bar.com/x/y.z" will yield type + in the type URL, for example "foo.bar.com/x/y.z" will yield type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with an + + additional field `@type` which contains the type URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom JSON + + representation, that representation will be embedded adding a + field + + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + title: >- + Address contains the data of the external chain address to be + connected + + with the Desmos profile + proof: + title: Proof contains the ownership proof of the external chain address + type: object + properties: + pub_key: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at + least + + one "/" character. The last segment of the URL's path + must represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in + a canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary + all types that they + + expect it to use in the context of Any. However, for + URLs which use the + + scheme `http`, `https`, or no scheme, one can optionally + set up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based + on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in + the official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer + message along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values + in the form + + of utility functions or additional generated methods of the + Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by + default use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the + last '/' - name "y.z". + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + name "y.z". - JSON - ==== + JSON - The JSON representation of an `Any` value uses the regular + ==== - representation of the deserialized, embedded message, with an + The JSON representation of an `Any` value uses the regular - additional field `@type` which contains the type URL. Example: + representation of the deserialized, embedded message, with + an - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } + additional field `@type` which contains the type URL. + Example: - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } - If the embedded message type is well-known and has a custom JSON + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } - representation, that representation will be embedded adding a - field + If the embedded message type is well-known and has a custom + JSON - `value` which holds the custom JSON in addition to the `@type` + representation, that representation will be embedded adding + a field - field. Example (for message [google.protobuf.Duration][]): + `value` which holds the custom JSON in addition to the + `@type` - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - title: >- - Address contains the data of the external chain address to be - connected + field. Example (for message [google.protobuf.Duration][]): - with the Desmos profile - proof: - title: Proof contains the ownership proof of the external chain address - type: object - properties: - pub_key: + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + title: >- + PubKey represents the public key associated with the address + for which to + + prove the ownership + signature: type: object properties: type_url: @@ -5791,13 +6673,6 @@ definitions: "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } - title: >- - PubKey represents the public key associated with the address - for which to - - prove the ownership - signature: - type: string title: >- Signature represents the hex-encoded signature of the PlainText value @@ -5805,7 +6680,9 @@ definitions: type: string title: >- PlainText represents the hex-encoded value signed in order - to produce the Signature + to produce the + + Signature chain_config: title: ChainConfig contains the configuration of the external chain type: object @@ -6204,6 +7081,7 @@ definitions: type: string subspace: type: string + format: uint64 description: |- Relationship is the struct of a relationship. It represent the concept of "follow" of traditional social networks. @@ -6702,7 +7580,176 @@ definitions: prove the ownership signature: - type: string + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at least + + one "/" character. The last segment of the URL's path must + represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in a + canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary all + types that they + + expect it to use in the context of Any. However, for URLs + which use the + + scheme `http`, `https`, or no scheme, one can optionally + set up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based + on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in the + official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer message + along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values in + the form + + of utility functions or additional generated methods of the + Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by default + use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the last + '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with an + + additional field `@type` which contains the type URL. Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom + JSON + + representation, that representation will be embedded adding a + field + + `value` which holds the custom JSON in addition to the `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } title: >- Signature represents the hex-encoded signature of the PlainText value @@ -6710,7 +7757,9 @@ definitions: type: string title: >- PlainText represents the hex-encoded value signed in order to - produce the Signature + produce the + + Signature chain_config: title: ChainConfig contains the configuration of the external chain type: object @@ -6745,6 +7794,7 @@ definitions: type: string subspace: type: string + format: uint64 description: |- Relationship is the struct of a relationship. It represent the concept of "follow" of traditional social networks. @@ -6804,6 +7854,7 @@ definitions: description: Reason represents the optional reason the user has been blocked for. subspace: type: string + format: uint64 title: >- Subspace contains the ID of the subspace inside which the user should be diff --git a/proto/desmos/profiles/legacy/v230/models_relationships.proto b/proto/desmos/profiles/legacy/v230/models_relationships.proto new file mode 100644 index 0000000000..13a41d4d08 --- /dev/null +++ b/proto/desmos/profiles/legacy/v230/models_relationships.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; +package desmos.profiles.legacy.v230; + +import "gogoproto/gogo.proto"; +import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; +import "cosmos_proto/cosmos.proto"; + +option go_package = "github.com/desmos-labs/desmos/v2/x/profiles/legacy/v230"; + +// Relationship is the struct of a relationship. +// It represent the concept of "follow" of traditional social networks. +message Relationship { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + + string creator = 1 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; + string recipient = 2 [ (gogoproto.moretags) = "yaml:\"recipient\"" ]; + string subspace = 3 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; +} + +// UserBlock represents the fact that the Blocker has blocked the given Blocked +// user. +message UserBlock { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + + // Blocker represents the address of the user blocking another one + string blocker = 1 [ (gogoproto.moretags) = "yaml:\"blocker\"" ]; + + // Blocked represents the address of the blocked user + string blocked = 2 [ (gogoproto.moretags) = "yaml:\"blocked\"" ]; + + // Reason represents the optional reason the user has been blocked for. + string reason = 3 [ (gogoproto.moretags) = "yaml:\"reason\"" ]; + + // Subspace contains the ID of the subspace inside which the user should be + // blocked + string subspace = 4 [ (gogoproto.moretags) = "yaml:\"subspace\"" ]; +} \ No newline at end of file diff --git a/x/profiles/keeper/migrations.go b/x/profiles/keeper/migrations.go index 5da56adf7d..c0309168f1 100644 --- a/x/profiles/keeper/migrations.go +++ b/x/profiles/keeper/migrations.go @@ -11,9 +11,9 @@ import ( "github.com/desmos-labs/desmos/v2/x/profiles/types" - v210 "github.com/desmos-labs/desmos/v2/x/profiles/legacy/v210" - v200 "github.com/desmos-labs/desmos/v2/x/profiles/legacy/v200" + v210 "github.com/desmos-labs/desmos/v2/x/profiles/legacy/v210" + v300 "github.com/desmos-labs/desmos/v2/x/profiles/legacy/v300" ) // DONTCOVER @@ -107,3 +107,8 @@ func (m Migrator) migrateProfile(ctx sdk.Context, profile *types.Profile) error m.keeper.ak.SetAccount(ctx, profile) return nil } + +// Migrate4to5 migrates from version 4 to 5. +func (m Migrator) Migrate4to5(ctx sdk.Context) error { + return v300.MigrateStore(ctx, m.keeper.storeKey, m.keeper.cdc) +} diff --git a/x/profiles/legacy/v230/models_chain_links.pb.go b/x/profiles/legacy/v230/models_chain_links.pb.go index 252a1eedc3..e42624572b 100644 --- a/x/profiles/legacy/v230/models_chain_links.pb.go +++ b/x/profiles/legacy/v230/models_chain_links.pb.go @@ -124,7 +124,8 @@ type Proof struct { PubKey *types.Any `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty" yaml:"pub_key"` // Signature represents the hex-encoded signature of the PlainText value Signature string `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty" yaml:"signature"` - // PlainText represents the hex-encoded value signed in order to produce the Signature + // PlainText represents the hex-encoded value signed in order to produce the + // Signature PlainText string `protobuf:"bytes,3,opt,name=plain_text,json=plainText,proto3" json:"plain_text,omitempty" yaml:"plain_text"` } @@ -246,7 +247,8 @@ var xxx_messageInfo_Base58Address proto.InternalMessageInfo type HexAddress struct { // Value represents the hex address value Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` - // Prefix represents the optional prefix used during address encoding (e.g. 0x) + // Prefix represents the optional prefix used during address encoding (e.g. + // 0x) Prefix string `protobuf:"bytes,2,opt,name=prefix,proto3" json:"prefix,omitempty" yaml:"prefix"` } diff --git a/x/profiles/legacy/v230/models_relationships.pb.go b/x/profiles/legacy/v230/models_relationships.pb.go new file mode 100644 index 0000000000..e1aefb5f40 --- /dev/null +++ b/x/profiles/legacy/v230/models_relationships.pb.go @@ -0,0 +1,832 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: desmos/profiles/legacy/v230/models_relationships.proto + +package v230 + +import ( + fmt "fmt" + _ "github.com/cosmos/cosmos-sdk/codec/types" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + _ "github.com/regen-network/cosmos-proto" + _ "google.golang.org/protobuf/types/known/timestamppb" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Relationship is the struct of a relationship. +// It represent the concept of "follow" of traditional social networks. +type Relationship struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` + Recipient string `protobuf:"bytes,2,opt,name=recipient,proto3" json:"recipient,omitempty" yaml:"recipient"` + Subspace string `protobuf:"bytes,3,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` +} + +func (m *Relationship) Reset() { *m = Relationship{} } +func (m *Relationship) String() string { return proto.CompactTextString(m) } +func (*Relationship) ProtoMessage() {} +func (*Relationship) Descriptor() ([]byte, []int) { + return fileDescriptor_4929e4628d8fdc04, []int{0} +} +func (m *Relationship) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Relationship) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Relationship.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Relationship) XXX_Merge(src proto.Message) { + xxx_messageInfo_Relationship.Merge(m, src) +} +func (m *Relationship) XXX_Size() int { + return m.Size() +} +func (m *Relationship) XXX_DiscardUnknown() { + xxx_messageInfo_Relationship.DiscardUnknown(m) +} + +var xxx_messageInfo_Relationship proto.InternalMessageInfo + +func (m *Relationship) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *Relationship) GetRecipient() string { + if m != nil { + return m.Recipient + } + return "" +} + +func (m *Relationship) GetSubspace() string { + if m != nil { + return m.Subspace + } + return "" +} + +// UserBlock represents the fact that the Blocker has blocked the given Blocked +// user. +type UserBlock struct { + // Blocker represents the address of the user blocking another one + Blocker string `protobuf:"bytes,1,opt,name=blocker,proto3" json:"blocker,omitempty" yaml:"blocker"` + // Blocked represents the address of the blocked user + Blocked string `protobuf:"bytes,2,opt,name=blocked,proto3" json:"blocked,omitempty" yaml:"blocked"` + // Reason represents the optional reason the user has been blocked for. + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty" yaml:"reason"` + // Subspace contains the ID of the subspace inside which the user should be + // blocked + Subspace string `protobuf:"bytes,4,opt,name=subspace,proto3" json:"subspace,omitempty" yaml:"subspace"` +} + +func (m *UserBlock) Reset() { *m = UserBlock{} } +func (m *UserBlock) String() string { return proto.CompactTextString(m) } +func (*UserBlock) ProtoMessage() {} +func (*UserBlock) Descriptor() ([]byte, []int) { + return fileDescriptor_4929e4628d8fdc04, []int{1} +} +func (m *UserBlock) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UserBlock) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UserBlock.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UserBlock) XXX_Merge(src proto.Message) { + xxx_messageInfo_UserBlock.Merge(m, src) +} +func (m *UserBlock) XXX_Size() int { + return m.Size() +} +func (m *UserBlock) XXX_DiscardUnknown() { + xxx_messageInfo_UserBlock.DiscardUnknown(m) +} + +var xxx_messageInfo_UserBlock proto.InternalMessageInfo + +func (m *UserBlock) GetBlocker() string { + if m != nil { + return m.Blocker + } + return "" +} + +func (m *UserBlock) GetBlocked() string { + if m != nil { + return m.Blocked + } + return "" +} + +func (m *UserBlock) GetReason() string { + if m != nil { + return m.Reason + } + return "" +} + +func (m *UserBlock) GetSubspace() string { + if m != nil { + return m.Subspace + } + return "" +} + +func init() { + proto.RegisterType((*Relationship)(nil), "desmos.profiles.legacy.v230.Relationship") + proto.RegisterType((*UserBlock)(nil), "desmos.profiles.legacy.v230.UserBlock") +} + +func init() { + proto.RegisterFile("desmos/profiles/legacy/v230/models_relationships.proto", fileDescriptor_4929e4628d8fdc04) +} + +var fileDescriptor_4929e4628d8fdc04 = []byte{ + // 387 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x92, 0xbd, 0x4e, 0xeb, 0x30, + 0x18, 0x86, 0xeb, 0x73, 0x8e, 0x7a, 0xda, 0xe8, 0xfc, 0x40, 0xe8, 0x50, 0x8a, 0x94, 0x20, 0x4f, + 0x20, 0x41, 0x8c, 0x5a, 0x09, 0xa4, 0x8e, 0xbd, 0x03, 0x22, 0xb1, 0xb0, 0x54, 0x4e, 0xe2, 0xa6, + 0x11, 0x4e, 0xbe, 0xc8, 0x4e, 0x2b, 0x7a, 0x17, 0x8c, 0x8c, 0xdd, 0xb9, 0x11, 0x16, 0xa4, 0x8e, + 0x4c, 0x11, 0x6a, 0x17, 0xe6, 0x5c, 0x01, 0x4a, 0x9c, 0xb4, 0xfc, 0x74, 0x61, 0xfb, 0x9c, 0xf7, + 0x79, 0x92, 0xf7, 0x53, 0xac, 0x9d, 0x7b, 0x4c, 0x86, 0x20, 0x49, 0x2c, 0x60, 0x14, 0x70, 0x26, + 0x09, 0x67, 0x3e, 0x75, 0x67, 0x64, 0xda, 0xed, 0x9d, 0x91, 0x10, 0x3c, 0xc6, 0xe5, 0x50, 0x30, + 0x4e, 0x93, 0x00, 0x22, 0x39, 0x0e, 0x62, 0x69, 0xc5, 0x02, 0x12, 0xd0, 0x0f, 0x94, 0x67, 0x55, + 0x9e, 0xa5, 0x3c, 0x2b, 0xf7, 0x3a, 0x2d, 0x1f, 0x7c, 0x28, 0x38, 0x92, 0x4f, 0x4a, 0xe9, 0xec, + 0xfb, 0x00, 0x3e, 0x67, 0xa4, 0x38, 0x39, 0x93, 0x11, 0xa1, 0xd1, 0xac, 0x8c, 0xcc, 0xcf, 0x51, + 0x12, 0x84, 0x4c, 0x26, 0x34, 0x8c, 0x2b, 0xd7, 0x85, 0xfc, 0x73, 0x43, 0xf5, 0x52, 0x75, 0x50, + 0x11, 0x7e, 0x40, 0xda, 0x1f, 0xfb, 0x5d, 0x43, 0xfd, 0x44, 0xfb, 0xed, 0x0a, 0x46, 0x13, 0x10, + 0x6d, 0x74, 0x88, 0x8e, 0x9a, 0x03, 0x3d, 0x4b, 0xcd, 0x7f, 0x33, 0x1a, 0xf2, 0x3e, 0x2e, 0x03, + 0x6c, 0x57, 0x88, 0xde, 0xd5, 0x9a, 0x82, 0xb9, 0x41, 0x1c, 0xb0, 0x28, 0x69, 0xff, 0x28, 0xf8, + 0x56, 0x96, 0x9a, 0x3b, 0x8a, 0x5f, 0x47, 0xd8, 0xde, 0x60, 0x3a, 0xd1, 0x1a, 0x72, 0xe2, 0xc8, + 0x98, 0xba, 0xac, 0xfd, 0xb3, 0x50, 0xf6, 0xb2, 0xd4, 0xfc, 0xaf, 0x94, 0x2a, 0xc1, 0xf6, 0x1a, + 0xea, 0x37, 0xee, 0xe7, 0x26, 0x7a, 0x9d, 0x9b, 0x08, 0x3f, 0x21, 0xad, 0x79, 0x25, 0x99, 0x18, + 0x70, 0x70, 0x6f, 0xf2, 0xaa, 0x4e, 0x3e, 0xb0, 0x2d, 0x55, 0xcb, 0x00, 0xdb, 0x15, 0xb2, 0xa1, + 0xbd, 0xb2, 0xe8, 0x17, 0xda, 0x5b, 0xd3, 0x9e, 0x7e, 0xac, 0xd5, 0x05, 0xa3, 0x12, 0xa2, 0xb2, + 0xe2, 0x6e, 0x96, 0x9a, 0x7f, 0xab, 0xad, 0xf2, 0xe7, 0xd8, 0x2e, 0x81, 0x0f, 0xfb, 0xfc, 0xfa, + 0xd6, 0x3e, 0x83, 0xcb, 0xc7, 0xa5, 0x81, 0x16, 0x4b, 0x03, 0xbd, 0x2c, 0x0d, 0x74, 0xb7, 0x32, + 0x6a, 0x8b, 0x95, 0x51, 0x7b, 0x5e, 0x19, 0xb5, 0xeb, 0x0b, 0x3f, 0x48, 0xc6, 0x13, 0xc7, 0x72, + 0x21, 0x24, 0xea, 0xb2, 0x9c, 0x72, 0xea, 0xc8, 0x72, 0x26, 0xd3, 0x2e, 0xb9, 0xdd, 0x7a, 0xeb, + 0x9c, 0x7a, 0xf1, 0x5f, 0x7b, 0x6f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x95, 0x70, 0xc1, 0x81, 0x9b, + 0x02, 0x00, 0x00, +} + +func (this *Relationship) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Relationship) + if !ok { + that2, ok := that.(Relationship) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Creator != that1.Creator { + return false + } + if this.Recipient != that1.Recipient { + return false + } + if this.Subspace != that1.Subspace { + return false + } + return true +} +func (this *UserBlock) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*UserBlock) + if !ok { + that2, ok := that.(UserBlock) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.Blocker != that1.Blocker { + return false + } + if this.Blocked != that1.Blocked { + return false + } + if this.Reason != that1.Reason { + return false + } + if this.Subspace != that1.Subspace { + return false + } + return true +} +func (m *Relationship) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Relationship) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Relationship) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Subspace) > 0 { + i -= len(m.Subspace) + copy(dAtA[i:], m.Subspace) + i = encodeVarintModelsRelationships(dAtA, i, uint64(len(m.Subspace))) + i-- + dAtA[i] = 0x1a + } + if len(m.Recipient) > 0 { + i -= len(m.Recipient) + copy(dAtA[i:], m.Recipient) + i = encodeVarintModelsRelationships(dAtA, i, uint64(len(m.Recipient))) + i-- + dAtA[i] = 0x12 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintModelsRelationships(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *UserBlock) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UserBlock) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UserBlock) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Subspace) > 0 { + i -= len(m.Subspace) + copy(dAtA[i:], m.Subspace) + i = encodeVarintModelsRelationships(dAtA, i, uint64(len(m.Subspace))) + i-- + dAtA[i] = 0x22 + } + if len(m.Reason) > 0 { + i -= len(m.Reason) + copy(dAtA[i:], m.Reason) + i = encodeVarintModelsRelationships(dAtA, i, uint64(len(m.Reason))) + i-- + dAtA[i] = 0x1a + } + if len(m.Blocked) > 0 { + i -= len(m.Blocked) + copy(dAtA[i:], m.Blocked) + i = encodeVarintModelsRelationships(dAtA, i, uint64(len(m.Blocked))) + i-- + dAtA[i] = 0x12 + } + if len(m.Blocker) > 0 { + i -= len(m.Blocker) + copy(dAtA[i:], m.Blocker) + i = encodeVarintModelsRelationships(dAtA, i, uint64(len(m.Blocker))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintModelsRelationships(dAtA []byte, offset int, v uint64) int { + offset -= sovModelsRelationships(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Relationship) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovModelsRelationships(uint64(l)) + } + l = len(m.Recipient) + if l > 0 { + n += 1 + l + sovModelsRelationships(uint64(l)) + } + l = len(m.Subspace) + if l > 0 { + n += 1 + l + sovModelsRelationships(uint64(l)) + } + return n +} + +func (m *UserBlock) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Blocker) + if l > 0 { + n += 1 + l + sovModelsRelationships(uint64(l)) + } + l = len(m.Blocked) + if l > 0 { + n += 1 + l + sovModelsRelationships(uint64(l)) + } + l = len(m.Reason) + if l > 0 { + n += 1 + l + sovModelsRelationships(uint64(l)) + } + l = len(m.Subspace) + if l > 0 { + n += 1 + l + sovModelsRelationships(uint64(l)) + } + return n +} + +func sovModelsRelationships(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozModelsRelationships(x uint64) (n int) { + return sovModelsRelationships(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Relationship) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Relationship: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Relationship: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModelsRelationships + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModelsRelationships + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Recipient", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModelsRelationships + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModelsRelationships + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Recipient = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModelsRelationships + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModelsRelationships + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipModelsRelationships(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthModelsRelationships + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UserBlock) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UserBlock: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UserBlock: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Blocker", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModelsRelationships + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModelsRelationships + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Blocker = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Blocked", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModelsRelationships + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModelsRelationships + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Blocked = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModelsRelationships + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModelsRelationships + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModelsRelationships + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModelsRelationships + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subspace = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipModelsRelationships(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthModelsRelationships + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipModelsRelationships(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModelsRelationships + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthModelsRelationships + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupModelsRelationships + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthModelsRelationships + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthModelsRelationships = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowModelsRelationships = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupModelsRelationships = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/profiles/legacy/v300/store.go b/x/profiles/legacy/v300/store.go new file mode 100644 index 0000000000..124dff3011 --- /dev/null +++ b/x/profiles/legacy/v300/store.go @@ -0,0 +1,112 @@ +package v300 + +import ( + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + + v230 "github.com/desmos-labs/desmos/v2/x/profiles/legacy/v230" + "github.com/desmos-labs/desmos/v2/x/profiles/types" +) + +// MigrateStore performs in-place store migrations from v2.3 to v3.0. +// The migration includes: +// +// - replace all relationship subspace id from string to uint64 +// - replace all user blocks subspace id from string to uint64 +func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) error { + store := ctx.KVStore(storeKey) + + err := migrateUserBlocks(store, cdc) + if err != nil { + return err + } + + err = migrateRelationships(store, cdc) + if err != nil { + return err + } + + return nil +} + +// migrateUserBlocks migrates the user blocks stored to the new type, converting the subspace from string to uint64 +func migrateUserBlocks(store sdk.KVStore, cdc codec.BinaryCodec) error { + var keys [][]byte + var values []v230.UserBlock + + userBlocksStore := prefix.NewStore(store, types.UsersBlocksStorePrefix) + iterator := userBlocksStore.Iterator(nil, nil) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + // Get the keys + keys = append(keys, iterator.Key()) + + // Get the associated values + var block v230.UserBlock + err := cdc.Unmarshal(iterator.Value(), &block) + if err != nil { + return err + } + values = append(values, block) + } + + for i := 0; i < len(keys); i++ { + // Serialize the block as the new type + blockBz, err := cdc.Marshal(&types.UserBlock{ + Blocker: values[i].Blocker, + Blocked: values[i].Blocked, + Reason: values[i].Reason, + Subspace: 0, + }) + if err != nil { + return err + } + + // Set the key inside the store + store.Set(keys[i], blockBz) + } + + return nil +} + +// migrateRelationships migrates the relationships stored to the new type, converting the subspace from string to uint64 +func migrateRelationships(store sdk.KVStore, cdc codec.BinaryCodec) error { + var keys [][]byte + var values []v230.Relationship + + relationshipsStore := prefix.NewStore(store, types.RelationshipsStorePrefix) + iterator := relationshipsStore.Iterator(nil, nil) + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + // Get the keys + keys = append(keys, iterator.Key()) + + // Get the associated values + var block v230.Relationship + err := cdc.Unmarshal(iterator.Value(), &block) + if err != nil { + return err + } + values = append(values, block) + } + + for i := 0; i < len(keys); i++ { + // Serialize the relationship as the new type + blockBz, err := cdc.Marshal(&types.Relationship{ + Creator: values[i].Creator, + Recipient: values[i].Recipient, + Subspace: 0, + }) + if err != nil { + return err + } + + // Set the key inside the store + store.Set(keys[i], blockBz) + } + + return nil +} diff --git a/x/profiles/module.go b/x/profiles/module.go index 7d22751646..381589c80a 100644 --- a/x/profiles/module.go +++ b/x/profiles/module.go @@ -28,7 +28,7 @@ import ( ) const ( - consensusVersion = 4 + consensusVersion = 5 ) // type check to ensure the interface is properly implemented @@ -121,6 +121,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { if err != nil { panic(err) } + err = cfg.RegisterMigration(types.ModuleName, 4, m.Migrate4to5) + if err != nil { + panic(err) + } } // NewAppModule creates a new AppModule Object From 7d91aed1fd56cf17b23d3b074ab137a84a68e9a0 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Wed, 26 Jan 2022 10:09:32 +0100 Subject: [PATCH 18/47] fixed lint Signed-off-by: Riccardo Montagnin --- x/profiles/types/genesis.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/profiles/types/genesis.go b/x/profiles/types/genesis.go index 68bf988772..93708478da 100644 --- a/x/profiles/types/genesis.go +++ b/x/profiles/types/genesis.go @@ -42,9 +42,9 @@ func ValidateGenesis(data *GenesisState) error { } } - for _, rel := range data.Relationships { + for i, rel := range data.Relationships { if containDuplicates(data.Relationships, rel) { - return fmt.Errorf("duplicated relationship: %s", &rel) + return fmt.Errorf("duplicated relationship: %s", &data.Relationships[i]) } err = rel.Validate() From ff6c40944bd1cf2edf72c0485e24bf8f321c94e9 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 27 Jan 2022 09:43:06 +0100 Subject: [PATCH 19/47] fixed suggested typos Signed-off-by: Riccardo Montagnin --- proto/desmos/subspaces/v1/genesis.proto | 7 ++++--- proto/desmos/subspaces/v1/msgs.proto | 2 +- proto/desmos/subspaces/v1/subspace.proto | 2 +- x/subspaces/client/cli/tx.go | 2 +- x/subspaces/types/genesis.pb.go | 7 +++---- x/subspaces/types/msgs.pb.go | 4 ++-- x/subspaces/types/subspace.pb.go | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/proto/desmos/subspaces/v1/genesis.proto b/proto/desmos/subspaces/v1/genesis.proto index eb71febe06..1b613febee 100644 --- a/proto/desmos/subspaces/v1/genesis.proto +++ b/proto/desmos/subspaces/v1/genesis.proto @@ -28,14 +28,15 @@ message ACLEntry { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = true; - // Either group name or user address uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID" ]; + + // Either a group name or user address string target = 2; + uint32 permissions = 3; } -// UsersEntry contains the data of a slice of users associated to a subspace -// with a specific id +// UserGroup contains the data of a single user group present inside a subspace message UserGroup { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = true; diff --git a/proto/desmos/subspaces/v1/msgs.proto b/proto/desmos/subspaces/v1/msgs.proto index 3a24fe0390..ed7c430785 100644 --- a/proto/desmos/subspaces/v1/msgs.proto +++ b/proto/desmos/subspaces/v1/msgs.proto @@ -30,7 +30,7 @@ service Msg { rpc RemoveUserFromUserGroup(MsgRemoveUserFromUserGroup) returns (MsgRemoveUserFromUserGroupResponse); - // SetUserPermissions allows to set another user's permissions + // SetPermissions allows to set another user's permissions rpc SetPermissions(MsgSetPermissions) returns (MsgSetPermissionsResponse); } diff --git a/proto/desmos/subspaces/v1/subspace.proto b/proto/desmos/subspaces/v1/subspace.proto index 024c45c0a8..bb54788b69 100644 --- a/proto/desmos/subspaces/v1/subspace.proto +++ b/proto/desmos/subspaces/v1/subspace.proto @@ -11,7 +11,7 @@ message Subspace { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = true; - // Unique SHA-256 string that identifies the subspace + // Unique id that identifies the subspace uint64 id = 1 [ (gogoproto.customname) = "ID", (gogoproto.moretags) = "yaml:\"id\"" ]; diff --git a/x/subspaces/client/cli/tx.go b/x/subspaces/client/cli/tx.go index 14cd03ff23..a1629b70ca 100644 --- a/x/subspaces/client/cli/tx.go +++ b/x/subspaces/client/cli/tx.go @@ -172,7 +172,7 @@ func GetCmdCreateUserGroup() *cobra.Command { Args: cobra.MinimumNArgs(2), Short: "Create a new user group within a subspace", Long: `Create a new user group within the subspace having the provided id. -The permissions this group can be set using the third (optional) parameter. +The permissions of this group can be set using the third (optional) parameter. If no permissions are set, the default PermissionNothing will be used instead. Multiple permissions must be specified separating them with a comma (,).`, Example: fmt.Sprintf(` diff --git a/x/subspaces/types/genesis.pb.go b/x/subspaces/types/genesis.pb.go index 8d646b0c3c..19c794bd84 100644 --- a/x/subspaces/types/genesis.pb.go +++ b/x/subspaces/types/genesis.pb.go @@ -94,8 +94,8 @@ func (m *GenesisState) GetUserGroups() []UserGroup { // ACL represents a single Access Control List entry type ACLEntry struct { - // Either group name or user address - SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` + // Either a group name or user address Target string `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty"` Permissions uint32 `protobuf:"varint,3,opt,name=permissions,proto3" json:"permissions,omitempty"` } @@ -154,8 +154,7 @@ func (m *ACLEntry) GetPermissions() uint32 { return 0 } -// UsersEntry contains the data of a slice of users associated to a subspace -// with a specific id +// UserGroup contains the data of a single user group present inside a subspace type UserGroup struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` diff --git a/x/subspaces/types/msgs.pb.go b/x/subspaces/types/msgs.pb.go index 95328f2cc5..790acd6d4e 100644 --- a/x/subspaces/types/msgs.pb.go +++ b/x/subspaces/types/msgs.pb.go @@ -821,7 +821,7 @@ type MsgClient interface { // RemoveUserFromUserGroup allows to remove a specific user from a specific // user group RemoveUserFromUserGroup(ctx context.Context, in *MsgRemoveUserFromUserGroup, opts ...grpc.CallOption) (*MsgRemoveUserFromUserGroupResponse, error) - // SetUserPermissions allows to set another user's permissions + // SetPermissions allows to set another user's permissions SetPermissions(ctx context.Context, in *MsgSetPermissions, opts ...grpc.CallOption) (*MsgSetPermissionsResponse, error) } @@ -911,7 +911,7 @@ type MsgServer interface { // RemoveUserFromUserGroup allows to remove a specific user from a specific // user group RemoveUserFromUserGroup(context.Context, *MsgRemoveUserFromUserGroup) (*MsgRemoveUserFromUserGroupResponse, error) - // SetUserPermissions allows to set another user's permissions + // SetPermissions allows to set another user's permissions SetPermissions(context.Context, *MsgSetPermissions) (*MsgSetPermissionsResponse, error) } diff --git a/x/subspaces/types/subspace.pb.go b/x/subspaces/types/subspace.pb.go index ddb8b23622..398c5b9164 100644 --- a/x/subspaces/types/subspace.pb.go +++ b/x/subspaces/types/subspace.pb.go @@ -29,7 +29,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Subspace contains all the data of a Desmos subspace type Subspace struct { - // Unique SHA-256 string that identifies the subspace + // Unique id that identifies the subspace ID uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // Human-readable name of the subspace Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` From 3620cce289961274e8cb959706f866864f51c9ec Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 27 Jan 2022 09:43:16 +0100 Subject: [PATCH 20/47] fixed group name checking inside genesis Signed-off-by: Riccardo Montagnin --- x/subspaces/types/genesis.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/subspaces/types/genesis.go b/x/subspaces/types/genesis.go index 4a7f0fd75c..cfa2e1314d 100644 --- a/x/subspaces/types/genesis.go +++ b/x/subspaces/types/genesis.go @@ -2,6 +2,7 @@ package types import ( "fmt" + "strings" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -39,7 +40,7 @@ func (group UserGroup) Validate() error { return fmt.Errorf("invalid subspace id: %d", group.SubspaceID) } - if group.Name == "" { + if strings.TrimSpace(group.Name) == "" { return fmt.Errorf("invalid group name: %s", group.Name) } From 96f4e093363607833784cdca754ad197bd0a0e82 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 27 Jan 2022 09:43:55 +0100 Subject: [PATCH 21/47] generated updated Swagger file Signed-off-by: Riccardo Montagnin --- client/docs/swagger-ui/swagger.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 4e3b120d2a..38bef3acda 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -2,7 +2,7 @@ swagger: '2.0' info: title: Desmos - REST and gRPC Gateway docs description: A REST interface for state queries - version: 3.0.0 + version: 1.0.0 paths: '/desmos/profiles/v1beta1/app-links/clients/{client_id}': get: From 0e4b722880404a6ef6b5b95d28aeb9b609b67e5b Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 27 Jan 2022 09:45:22 +0100 Subject: [PATCH 22/47] fixed the blocks and relationships migration Signed-off-by: Riccardo Montagnin --- x/profiles/legacy/v300/store.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/x/profiles/legacy/v300/store.go b/x/profiles/legacy/v300/store.go index 124dff3011..fdcd78da9f 100644 --- a/x/profiles/legacy/v300/store.go +++ b/x/profiles/legacy/v300/store.go @@ -37,7 +37,6 @@ func migrateUserBlocks(store sdk.KVStore, cdc codec.BinaryCodec) error { userBlocksStore := prefix.NewStore(store, types.UsersBlocksStorePrefix) iterator := userBlocksStore.Iterator(nil, nil) - defer iterator.Close() for ; iterator.Valid(); iterator.Next() { // Get the keys @@ -52,6 +51,12 @@ func migrateUserBlocks(store sdk.KVStore, cdc codec.BinaryCodec) error { values = append(values, block) } + // Close the iterator + err := iterator.Close() + if err != nil { + return err + } + for i := 0; i < len(keys); i++ { // Serialize the block as the new type blockBz, err := cdc.Marshal(&types.UserBlock{ @@ -78,7 +83,6 @@ func migrateRelationships(store sdk.KVStore, cdc codec.BinaryCodec) error { relationshipsStore := prefix.NewStore(store, types.RelationshipsStorePrefix) iterator := relationshipsStore.Iterator(nil, nil) - defer iterator.Close() for ; iterator.Valid(); iterator.Next() { // Get the keys @@ -93,6 +97,12 @@ func migrateRelationships(store sdk.KVStore, cdc codec.BinaryCodec) error { values = append(values, block) } + // Close the iterator + err := iterator.Close() + if err != nil { + return err + } + for i := 0; i < len(keys); i++ { // Serialize the relationship as the new type blockBz, err := cdc.Marshal(&types.Relationship{ From 32a545e9ad91b197080919376e7f629ec5b55f46 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 27 Jan 2022 10:57:12 +0100 Subject: [PATCH 23/47] added the ability to delete a subspace added hooks to the subspaces keeper Signed-off-by: Riccardo Montagnin --- app/params/weights.go | 1 + proto/desmos/subspaces/v1/msgs.proto | 20 + x/subspaces/client/cli/cli_test.go | 53 ++ x/subspaces/client/cli/tx.go | 32 ++ x/subspaces/keeper/groups.go | 23 +- x/subspaces/keeper/hooks.go | 66 +++ x/subspaces/keeper/keeper.go | 11 + x/subspaces/keeper/msg_server.go | 32 ++ x/subspaces/keeper/msg_server_test.go | 107 ++++ x/subspaces/keeper/permissions.go | 6 +- x/subspaces/keeper/subspaces.go | 10 + x/subspaces/simulation/operations.go | 12 + .../simulation/operations_subspaces.go | 59 ++- x/subspaces/types/events.go | 1 + x/subspaces/types/hooks.go | 90 ++++ x/subspaces/types/keys.go | 1 + x/subspaces/types/msgs.go | 41 ++ x/subspaces/types/msgs.pb.go | 474 +++++++++++++++--- x/subspaces/types/msgs_test.go | 60 +++ x/subspaces/types/permissions.go | 3 + 20 files changed, 1033 insertions(+), 69 deletions(-) create mode 100644 x/subspaces/keeper/hooks.go create mode 100644 x/subspaces/types/hooks.go diff --git a/app/params/weights.go b/app/params/weights.go index ba458e51e1..33dfaf43ab 100644 --- a/app/params/weights.go +++ b/app/params/weights.go @@ -16,6 +16,7 @@ const ( DefaultWeightMsgCreateSubspace int = 80 DefaultWeightMsgEditSubspace int = 30 + DefaultWeightMsgDeleteSubspace int = 5 DefaultWeightMsgCreateUserGroup int = 10 DefaultWeightMsgDeleteUserGroup int = 5 DefaultWeightMsgAddUserToUserGroup int = 7 diff --git a/proto/desmos/subspaces/v1/msgs.proto b/proto/desmos/subspaces/v1/msgs.proto index ed7c430785..ecc6baf3e5 100644 --- a/proto/desmos/subspaces/v1/msgs.proto +++ b/proto/desmos/subspaces/v1/msgs.proto @@ -15,6 +15,9 @@ service Msg { // EditSubspace allows to edit a subspace rpc EditSubspace(MsgEditSubspace) returns (MsgEditSubspaceResponse); + // DeleteSubspace allows to delete a subspace + rpc DeleteSubspace(MsgDeleteSubspace) returns (MsgDeleteSubspaceResponse); + // CreateUserGroup allows to create a user group rpc CreateUserGroup(MsgCreateUserGroup) returns (MsgCreateUserGroupResponse); @@ -80,6 +83,23 @@ message MsgEditSubspaceResponse {} // -------------------------------------------------------------------------------------------------------------------- +// MsgDeleteSubspace represents the message used to delete a subspace +message MsgDeleteSubspace { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + string signer = 2 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; +} + +// MsgDeleteSubspaceResponse defines the Msg/DeleteSubspace response type +message MsgDeleteSubspaceResponse {} + +// -------------------------------------------------------------------------------------------------------------------- + // MsgCreateUserGroup represents the message used to create a user group message MsgCreateUserGroup { uint64 subspace_id = 1 [ diff --git a/x/subspaces/client/cli/cli_test.go b/x/subspaces/client/cli/cli_test.go index 5174a67051..e964f7e0b0 100644 --- a/x/subspaces/client/cli/cli_test.go +++ b/x/subspaces/client/cli/cli_test.go @@ -63,6 +63,15 @@ func (s *IntegrationTestSuite) SetupSuite() { "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), ), + types.NewSubspace( + 3, + "Subspace to delete", + "This is a test subspace that will be deleted", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), } subspacesData.ACL = []types.ACLEntry{ types.NewACLEntry(1, "group", types.PermissionWrite), @@ -375,6 +384,50 @@ func (s *IntegrationTestSuite) TestCmdEditSubspace() { } } +func (s *IntegrationTestSuite) TestCmdDeleteSubspace() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + respType proto.Message + }{ + { + name: "invalid subspace id returns error", + args: []string{"subspace"}, + shouldErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "3", + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + shouldErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdDeleteSubspace() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} + func (s *IntegrationTestSuite) TestCmdCreateUserGroup() { val := s.network.Validators[0] testCases := []struct { diff --git a/x/subspaces/client/cli/tx.go b/x/subspaces/client/cli/tx.go index a1629b70ca..08549d850b 100644 --- a/x/subspaces/client/cli/tx.go +++ b/x/subspaces/client/cli/tx.go @@ -165,6 +165,38 @@ func GetCmdEditSubspace() *cobra.Command { return cmd } +// GetCmdDeleteSubspace returns the command to delete a subspace +func GetCmdDeleteSubspace() *cobra.Command { + cmd := &cobra.Command{ + Use: "delete [subspace-id]", + Args: cobra.ExactArgs(1), + Short: "Deletes the subspace with the given id", + Example: fmt.Sprintf(`%s tx subspaces delete 1 --from alice`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + subspaceID, err := types.ParseSubspaceID(args[0]) + if err != nil { + return err + } + + msg := types.NewMsgDeleteSubspace(subspaceID, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + // GetCmdCreateUserGroup returns the command to create a user group func GetCmdCreateUserGroup() *cobra.Command { cmd := &cobra.Command{ diff --git a/x/subspaces/keeper/groups.go b/x/subspaces/keeper/groups.go index bf34f1bac1..ca014d2718 100644 --- a/x/subspaces/keeper/groups.go +++ b/x/subspaces/keeper/groups.go @@ -17,20 +17,20 @@ func (k Keeper) HasUserGroup(ctx sdk.Context, subspaceID uint64, groupName strin func (k Keeper) SaveUserGroup(ctx sdk.Context, subspaceID uint64, groupName string, permissions types.Permission) { store := ctx.KVStore(k.storeKey) - k.Logger(ctx).Info("group saved", "subspace_id", subspaceID, "group_name", groupName) - + // Save the group store.Set(types.GroupStoreKey(subspaceID, groupName), []byte{0x01}) + + // Save the permissions k.SetPermissions(ctx, subspaceID, groupName, permissions) + + k.Logger(ctx).Info("group saved", "subspace_id", subspaceID, "group_name", groupName) + k.AfterSubspaceGroupSaved(ctx, subspaceID, groupName) } // DeleteUserGroup deletes the group with the given name from the subspace with the provided id func (k Keeper) DeleteUserGroup(ctx sdk.Context, subspaceID uint64, groupName string) { store := ctx.KVStore(k.storeKey) - k.Logger(ctx).Info("group deleted", "subspace_id", subspaceID, "group_name", groupName) - - store.Delete(types.GroupStoreKey(subspaceID, groupName)) - // Remove all the members from this group var members []sdk.AccAddress k.IterateGroupMembers(ctx, subspaceID, groupName, func(index int64, member sdk.AccAddress) (stop bool) { @@ -44,6 +44,12 @@ func (k Keeper) DeleteUserGroup(ctx sdk.Context, subspaceID uint64, groupName st // Remove the group permissions k.RemovePermissions(ctx, subspaceID, groupName) + + // Delete the group + store.Delete(types.GroupStoreKey(subspaceID, groupName)) + + k.Logger(ctx).Info("group deleted", "subspace_id", subspaceID, "group_name", groupName) + k.AfterSubspaceGroupDeleted(ctx, subspaceID, groupName) } // IsMemberOfGroup returns whether the given user is part of the group with @@ -62,6 +68,9 @@ func (k Keeper) AddUserToGroup(ctx sdk.Context, subspaceID uint64, groupName str store := ctx.KVStore(k.storeKey) store.Set(types.GroupMemberStoreKey(subspaceID, groupName, user), []byte{0x01}) + + k.AfterSubspaceGroupMemberAdded(ctx, subspaceID, groupName, user) + return nil } @@ -70,4 +79,6 @@ func (k Keeper) AddUserToGroup(ctx sdk.Context, subspaceID uint64, groupName str func (k Keeper) RemoveUserFromGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { store := ctx.KVStore(k.storeKey) store.Delete(types.GroupMemberStoreKey(subspaceID, groupName, user)) + + k.AfterSubspaceGroupMemberRemoved(ctx, subspaceID, groupName, user) } diff --git a/x/subspaces/keeper/hooks.go b/x/subspaces/keeper/hooks.go new file mode 100644 index 0000000000..4c06067aa3 --- /dev/null +++ b/x/subspaces/keeper/hooks.go @@ -0,0 +1,66 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +// Implements StakingHooks interface +var _ types.SubspacesHooks = Keeper{} + +// AfterSubspaceSaved - call if hook is registered +func (k Keeper) AfterSubspaceSaved(ctx sdk.Context, subspaceID uint64) { + if k.hooks != nil { + k.hooks.AfterSubspaceSaved(ctx, subspaceID) + } +} + +// AfterSubspaceDeleted - call if hook is registered +func (k Keeper) AfterSubspaceDeleted(ctx sdk.Context, subspaceID uint64) { + if k.hooks != nil { + k.hooks.AfterSubspaceDeleted(ctx, subspaceID) + } +} + +// AfterSubspaceGroupSaved - call if hook is registered +func (k Keeper) AfterSubspaceGroupSaved(ctx sdk.Context, subspaceID uint64, groupName string) { + if k.hooks != nil { + k.hooks.AfterSubspaceGroupSaved(ctx, subspaceID, groupName) + } +} + +// AfterSubspaceGroupMemberAdded - call if hook is registered +func (k Keeper) AfterSubspaceGroupMemberAdded(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { + if k.hooks != nil { + k.hooks.AfterSubspaceGroupMemberAdded(ctx, subspaceID, groupName, user) + } +} + +// AfterSubspaceGroupMemberRemoved - call if hook is registered +func (k Keeper) AfterSubspaceGroupMemberRemoved(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { + if k.hooks != nil { + k.hooks.AfterSubspaceGroupMemberRemoved(ctx, subspaceID, groupName, user) + } +} + +// AfterSubspaceGroupDeleted - call if hook is registered +func (k Keeper) AfterSubspaceGroupDeleted(ctx sdk.Context, subspaceID uint64, groupName string) { + if k.hooks != nil { + k.hooks.AfterSubspaceGroupDeleted(ctx, subspaceID, groupName) + } +} + +// AfterPermissionSet - call if hook is registered +func (k Keeper) AfterPermissionSet(ctx sdk.Context, subspaceID uint64, target string, permissions types.Permission) { + if k.hooks != nil { + k.hooks.AfterPermissionSet(ctx, subspaceID, target, permissions) + } +} + +// AfterPermissionRemoved - call if hook is registered +func (k Keeper) AfterPermissionRemoved(ctx sdk.Context, subspaceID uint64, target string) { + if k.hooks != nil { + k.hooks.AfterPermissionRemoved(ctx, subspaceID, target) + } +} diff --git a/x/subspaces/keeper/keeper.go b/x/subspaces/keeper/keeper.go index 0f5c1b369f..cc6c045c86 100644 --- a/x/subspaces/keeper/keeper.go +++ b/x/subspaces/keeper/keeper.go @@ -11,6 +11,7 @@ import ( type Keeper struct { storeKey sdk.StoreKey cdc codec.BinaryCodec + hooks types.SubspacesHooks } // NewKeeper creates new instances of the subspaces keeper @@ -25,3 +26,13 @@ func NewKeeper(cdc codec.BinaryCodec, storeKey sdk.StoreKey) Keeper { func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/"+types.ModuleName) } + +// SetHooks allows to set the subspaces hooks +func (k Keeper) SetHooks(sh types.SubspacesHooks) Keeper { + if k.hooks != nil { + panic("cannot set subspaces hooks twice") + } + + k.hooks = sh + return k +} diff --git a/x/subspaces/keeper/msg_server.go b/x/subspaces/keeper/msg_server.go index f31cd32e99..e47ed73ba7 100644 --- a/x/subspaces/keeper/msg_server.go +++ b/x/subspaces/keeper/msg_server.go @@ -105,6 +105,38 @@ func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspac return &types.MsgEditSubspaceResponse{}, nil } +// DeleteSubspace defines a rpc method for MsgDeleteSubspace +func (k msgServer) DeleteSubspace(goCtx context.Context, msg *types.MsgDeleteSubspace) (*types.MsgDeleteSubspaceResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // Check the if the subspace exists + if !k.HasSubspace(ctx, msg.SubspaceID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) + } + + // Check the permission to edit + if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionDeleteSubspace) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot edit this subspace") + } + + // Delete the subspace + k.Keeper.DeleteSubspace(ctx, msg.SubspaceID) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), + ), + sdk.NewEvent( + types.EventTypeDeleteSubspace, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), + ), + }) + + return &types.MsgDeleteSubspaceResponse{}, nil +} + // CreateUserGroup defines a rpc method for MsgCreateUserGroup func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUserGroup) (*types.MsgCreateUserGroupResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) diff --git a/x/subspaces/keeper/msg_server_test.go b/x/subspaces/keeper/msg_server_test.go index 48c9c9f03c..0e79571307 100644 --- a/x/subspaces/keeper/msg_server_test.go +++ b/x/subspaces/keeper/msg_server_test.go @@ -365,6 +365,113 @@ func (suite *KeeperTestsuite) TestMsgServer_EditSubspace() { } } +func (suite *KeeperTestsuite) TestMsgServer_DeleteSubspace() { + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgDeleteSubspace + shouldErr bool + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "subspace not found returns error", + msg: types.NewMsgDeleteSubspace(1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"), + shouldErr: true, + check: func(ctx sdk.Context) { + _, found := suite.k.GetSubspace(ctx, 1) + suite.Require().False(found) + }, + }, + { + name: "missing permission returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + msg: types.NewMsgDeleteSubspace(1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"), + shouldErr: true, + check: func(ctx sdk.Context) { + subspace, found := suite.k.GetSubspace(ctx, 1) + suite.Require().True(found) + suite.Require().Equal(types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), subspace) + }, + }, + { + name: "existing subspace is deleted correctly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SetPermissions(ctx, 1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", types.PermissionDeleteSubspace) + }, + msg: types.NewMsgDeleteSubspace(1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"), + shouldErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"), + ), + sdk.NewEvent( + types.EventTypeDeleteSubspace, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + ), + }, + check: func(ctx sdk.Context) { + exists := suite.k.HasSubspace(ctx, 1) + suite.Require().False(exists) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + _, err := service.DeleteSubspace(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() { testCases := []struct { name string diff --git a/x/subspaces/keeper/permissions.go b/x/subspaces/keeper/permissions.go index 6db33bf626..eefde55f70 100644 --- a/x/subspaces/keeper/permissions.go +++ b/x/subspaces/keeper/permissions.go @@ -86,13 +86,17 @@ func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, target string, } // SetPermissions sets the given permission for the specific target inside a single subspace -func (k Keeper) SetPermissions(ctx sdk.Context, subspaceID uint64, target string, permissions uint32) { +func (k Keeper) SetPermissions(ctx sdk.Context, subspaceID uint64, target string, permissions types.Permission) { store := ctx.KVStore(k.storeKey) store.Set(types.PermissionStoreKey(subspaceID, target), types.MarshalPermission(permissions)) + + k.AfterPermissionSet(ctx, subspaceID, target, permissions) } // RemovePermissions removes the permission for the given target inside the provided subspace func (k Keeper) RemovePermissions(ctx sdk.Context, subspaceID uint64, target string) { store := ctx.KVStore(k.storeKey) store.Delete(types.PermissionStoreKey(subspaceID, target)) + + k.AfterPermissionRemoved(ctx, subspaceID, target) } diff --git a/x/subspaces/keeper/subspaces.go b/x/subspaces/keeper/subspaces.go index b37762c7c8..582c763492 100644 --- a/x/subspaces/keeper/subspaces.go +++ b/x/subspaces/keeper/subspaces.go @@ -31,6 +31,7 @@ func (k Keeper) SaveSubspace(ctx sdk.Context, subspace types.Subspace) { store.Set(types.SubspaceKey(subspace.ID), k.cdc.MustMarshal(&subspace)) k.Logger(ctx).Info("subspace saved", "id", subspace.ID) + k.AfterSubspaceSaved(ctx, subspace.ID) } // HasSubspace tells whether the given subspace exists or not @@ -52,3 +53,12 @@ func (k Keeper) GetSubspace(ctx sdk.Context, subspaceID uint64) (subspace types. k.cdc.MustUnmarshal(store.Get(key), &subspace) return subspace, true } + +// DeleteSubspace allows to delete the subspace with the given id +func (k Keeper) DeleteSubspace(ctx sdk.Context, subspaceID uint64) { + store := ctx.KVStore(k.storeKey) + store.Delete(types.SubspaceKey(subspaceID)) + + k.Logger(ctx).Info("subspace deleted", "id", subspaceID) + k.AfterSubspaceDeleted(ctx, subspaceID) +} diff --git a/x/subspaces/simulation/operations.go b/x/subspaces/simulation/operations.go index ae30f055bf..2b6538b7f0 100644 --- a/x/subspaces/simulation/operations.go +++ b/x/subspaces/simulation/operations.go @@ -20,6 +20,7 @@ import ( const ( OpWeightMsgCreateSubspace = "op_weight_msg_create_subspace" OpWeightMsgEditSubspace = "op_weight_msg_edit_subspace" + OpWeightMsgDeleteSubspace = "op_weight_msg_delete_subspace" OpWeightMsgCreateUserGroup = "op_weight_msg_create_user_group" OpWeightMsgDeleteUserGroup = "op_weight_msg_delete_user_group" OpWeightMsgAddUserToUserGroup = "op_weight_msg_add_user_to_user_group" @@ -49,6 +50,13 @@ func WeightedOperations( }, ) + var weightMsgDeleteSubspace int + appParams.GetOrGenerate(cdc, OpWeightMsgDeleteSubspace, &weightMsgDeleteSubspace, nil, + func(_ *rand.Rand) { + weightMsgDeleteSubspace = params.DefaultWeightMsgDeleteSubspace + }, + ) + var weightMsgCreateUserGroup int appParams.GetOrGenerate(cdc, OpWeightMsgCreateUserGroup, &weightMsgCreateUserGroup, nil, func(_ *rand.Rand) { @@ -93,6 +101,10 @@ func WeightedOperations( weightMsgEditSubspace, SimulateMsgEditSubspace(k, ak, bk), ), + sim.NewWeightedOperation( + weightMsgDeleteSubspace, + SimulateMsgDeleteSubspace(k, ak, bk), + ), sim.NewWeightedOperation( weightMsgCreateUserGroup, SimulateMsgCreateUserGroup(k, ak, bk), diff --git a/x/subspaces/simulation/operations_subspaces.go b/x/subspaces/simulation/operations_subspaces.go index bf0121e4b1..a26448cf61 100644 --- a/x/subspaces/simulation/operations_subspaces.go +++ b/x/subspaces/simulation/operations_subspaces.go @@ -77,7 +77,7 @@ func randomSubspaceCreateFields( return } -// ___________________________________________________________________________________________________________________ +// -------------------------------------------------------------------------------------------------------------------- // SimulateMsgEditSubspace tests and runs a single msg edit subspace func SimulateMsgEditSubspace( @@ -148,3 +148,60 @@ func randomEditSubspaceFields( return subspaceID, update, account, false } + +// -------------------------------------------------------------------------------------------------------------------- + +// SimulateMsgDeleteSubspace tests and runs a single msg delete subspace +func SimulateMsgDeleteSubspace( + k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper, +) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspaceID, editor, skip := randomDeleteSubspaceFields(r, ctx, accs, k) + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgDeleteSubspace"), nil, nil + } + + // Build the message + msg := types.NewMsgDeleteSubspace(subspaceID, editor.Address.String()) + + // Send the data + err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{editor.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgDeleteSubspace"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgDeleteSubspace", nil), nil, nil + } +} + +// randomDeleteSubspaceFields returns the data needed to delete a subspace +func randomDeleteSubspaceFields( + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, +) (subspaceID uint64, account simtypes.Account, skip bool) { + // Get a subspace id + subspaces := k.GetAllSubspaces(ctx) + if len(subspaces) == 0 { + // Skip because there are no subspaces + skip = true + return + } + subspace, _ := RandomSubspace(r, subspaces) + subspaceID = subspace.ID + + // Get an editor + editors, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionDeleteSubspace) + acc := GetAccount(RandomAddress(r, editors), accs) + if acc == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + account = *acc + + return subspaceID, account, false +} diff --git a/x/subspaces/types/events.go b/x/subspaces/types/events.go index d45db8b996..1c9ce65ca4 100644 --- a/x/subspaces/types/events.go +++ b/x/subspaces/types/events.go @@ -4,6 +4,7 @@ package types const ( EventTypeCreateSubspace = "create_subspace" EventTypeEditSubspace = "edit_subspace" + EventTypeDeleteSubspace = "delete_subspace" EventTypeCreateUserGroup = "create_user_group" EventTypeDeleteUserGroup = "delete_user_group" EventTypeAddUserToGroup = "add_group_member" diff --git a/x/subspaces/types/hooks.go b/x/subspaces/types/hooks.go new file mode 100644 index 0000000000..5c4fb3557c --- /dev/null +++ b/x/subspaces/types/hooks.go @@ -0,0 +1,90 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// Event Hooks +// These can be utilized to communicate between a subspaces keeper and another +// keeper which must take particular actions when subspaces/groups/permissions change +// state. The second keeper must implement this interface, which then the +// subspaces keeper can call. + +// SubspacesHooks event hooks for subspaces objects (noalias) +type SubspacesHooks interface { + AfterSubspaceSaved(ctx sdk.Context, subspaceID uint64) // Must be called when a subspace is saved + AfterSubspaceDeleted(ctx sdk.Context, subspaceID uint64) // Must be called when a subspace is deleted + + AfterSubspaceGroupSaved(ctx sdk.Context, subspaceID uint64, groupName string) // Must be called when a subspace group is created + AfterSubspaceGroupMemberAdded(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) // Must be called when a user is added to a group + AfterSubspaceGroupMemberRemoved(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) // Must be called when a user is removed from a group + AfterSubspaceGroupDeleted(ctx sdk.Context, subspaceID uint64, groupName string) // Must be called when a subspace group is deleted + + AfterPermissionSet(ctx sdk.Context, subspaceID uint64, target string, permissions Permission) // Must be called when a permission is set + AfterPermissionRemoved(ctx sdk.Context, subspaceID uint64, target string) // Must be called when a permission is removed +} + +// -------------------------------------------------------------------------------------------------------------------- + +// MultiSubspacesHooks combines multiple subspaces hooks, all hook functions are run in array sequence +type MultiSubspacesHooks []SubspacesHooks + +func NewMultiStakingHooks(hooks ...SubspacesHooks) MultiSubspacesHooks { + return hooks +} + +// AfterSubspaceSaved implements SubspacesHook +func (h MultiSubspacesHooks) AfterSubspaceSaved(ctx sdk.Context, subspaceID uint64) { + for _, hook := range h { + hook.AfterSubspaceSaved(ctx, subspaceID) + } +} + +// AfterSubspaceDeleted implements SubspacesHook +func (h MultiSubspacesHooks) AfterSubspaceDeleted(ctx sdk.Context, subspaceID uint64) { + for _, hook := range h { + hook.AfterSubspaceDeleted(ctx, subspaceID) + } +} + +// AfterSubspaceGroupSaved implements SubspacesHook +func (h MultiSubspacesHooks) AfterSubspaceGroupSaved(ctx sdk.Context, subspaceID uint64, groupName string) { + for _, hook := range h { + hook.AfterSubspaceGroupSaved(ctx, subspaceID, groupName) + } +} + +// AfterSubspaceGroupMemberAdded implements SubspacesHook +func (h MultiSubspacesHooks) AfterSubspaceGroupMemberAdded(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { + for _, hook := range h { + hook.AfterSubspaceGroupMemberAdded(ctx, subspaceID, groupName, user) + } +} + +// AfterSubspaceGroupMemberRemoved implements SubspacesHook +func (h MultiSubspacesHooks) AfterSubspaceGroupMemberRemoved(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { + for _, hook := range h { + hook.AfterSubspaceGroupMemberRemoved(ctx, subspaceID, groupName, user) + } +} + +// AfterSubspaceGroupDeleted implements SubspacesHook +func (h MultiSubspacesHooks) AfterSubspaceGroupDeleted(ctx sdk.Context, subspaceID uint64, groupName string) { + for _, hook := range h { + hook.AfterSubspaceGroupDeleted(ctx, subspaceID, groupName) + } +} + +// AfterPermissionSet implements SubspacesHook +func (h MultiSubspacesHooks) AfterPermissionSet(ctx sdk.Context, subspaceID uint64, target string, permissions Permission) { + for _, hook := range h { + hook.AfterPermissionSet(ctx, subspaceID, target, permissions) + } +} + +// AfterPermissionRemoved implements SubspacesHook +func (h MultiSubspacesHooks) AfterPermissionRemoved(ctx sdk.Context, subspaceID uint64, target string) { + for _, hook := range h { + hook.AfterPermissionRemoved(ctx, subspaceID, target) + } +} diff --git a/x/subspaces/types/keys.go b/x/subspaces/types/keys.go index 55e9764599..e9930a0009 100644 --- a/x/subspaces/types/keys.go +++ b/x/subspaces/types/keys.go @@ -15,6 +15,7 @@ const ( ActionCreateSubspace = "create_subspace" ActionEditSubspace = "edit_subspace" + ActionDeleteSubspace = "delete_subspace" ActionCreateUserGroup = "create_user_group" ActionDeleteUserGroup = "delete_user_group" ActionAddUserToUserGroup = "add_user_to_user_group" diff --git a/x/subspaces/types/msgs.go b/x/subspaces/types/msgs.go index 2e17060832..e17a8587cc 100644 --- a/x/subspaces/types/msgs.go +++ b/x/subspaces/types/msgs.go @@ -113,6 +113,47 @@ func (msg MsgEditSubspace) GetSigners() []sdk.AccAddress { // -------------------------------------------------------------------------------------------------------------------- +// NewMsgDeleteSubspace returns a new MsgDeleteSubspace instance +func NewMsgDeleteSubspace(subspaceID uint64, signer string) *MsgDeleteSubspace { + return &MsgDeleteSubspace{ + SubspaceID: subspaceID, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgDeleteSubspace) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgDeleteSubspace) Type() string { return ActionEditSubspace } + +// ValidateBasic implements sdk.Msg +func (msg MsgDeleteSubspace) ValidateBasic() error { + if msg.SubspaceID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgDeleteSubspace) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgDeleteSubspace) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Signer) + return []sdk.AccAddress{addr} +} + +// -------------------------------------------------------------------------------------------------------------------- + // NewMsgCreateUserGroup creates a new MsgCreateUserGroup instance func NewMsgCreateUserGroup(subspaceID uint64, name string, permissions uint32, creator string) *MsgCreateUserGroup { return &MsgCreateUserGroup{ diff --git a/x/subspaces/types/msgs.pb.go b/x/subspaces/types/msgs.pb.go index 790acd6d4e..82a4ee42fe 100644 --- a/x/subspaces/types/msgs.pb.go +++ b/x/subspaces/types/msgs.pb.go @@ -195,6 +195,82 @@ func (m *MsgEditSubspaceResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgEditSubspaceResponse proto.InternalMessageInfo +// MsgDeleteSubspace represents the message used to delete a subspace +type MsgDeleteSubspace struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + Signer string `protobuf:"bytes,2,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` +} + +func (m *MsgDeleteSubspace) Reset() { *m = MsgDeleteSubspace{} } +func (m *MsgDeleteSubspace) String() string { return proto.CompactTextString(m) } +func (*MsgDeleteSubspace) ProtoMessage() {} +func (*MsgDeleteSubspace) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{4} +} +func (m *MsgDeleteSubspace) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDeleteSubspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDeleteSubspace.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgDeleteSubspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDeleteSubspace.Merge(m, src) +} +func (m *MsgDeleteSubspace) XXX_Size() int { + return m.Size() +} +func (m *MsgDeleteSubspace) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDeleteSubspace.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDeleteSubspace proto.InternalMessageInfo + +// MsgDeleteSubspaceResponse defines the Msg/DeleteSubspace response type +type MsgDeleteSubspaceResponse struct { +} + +func (m *MsgDeleteSubspaceResponse) Reset() { *m = MsgDeleteSubspaceResponse{} } +func (m *MsgDeleteSubspaceResponse) String() string { return proto.CompactTextString(m) } +func (*MsgDeleteSubspaceResponse) ProtoMessage() {} +func (*MsgDeleteSubspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{5} +} +func (m *MsgDeleteSubspaceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgDeleteSubspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgDeleteSubspaceResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgDeleteSubspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgDeleteSubspaceResponse.Merge(m, src) +} +func (m *MsgDeleteSubspaceResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgDeleteSubspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgDeleteSubspaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgDeleteSubspaceResponse proto.InternalMessageInfo + // MsgCreateUserGroup represents the message used to create a user group type MsgCreateUserGroup struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` @@ -207,7 +283,7 @@ func (m *MsgCreateUserGroup) Reset() { *m = MsgCreateUserGroup{} } func (m *MsgCreateUserGroup) String() string { return proto.CompactTextString(m) } func (*MsgCreateUserGroup) ProtoMessage() {} func (*MsgCreateUserGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{4} + return fileDescriptor_c16a431ff9a3b35b, []int{6} } func (m *MsgCreateUserGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -272,7 +348,7 @@ func (m *MsgCreateUserGroupResponse) Reset() { *m = MsgCreateUserGroupRe func (m *MsgCreateUserGroupResponse) String() string { return proto.CompactTextString(m) } func (*MsgCreateUserGroupResponse) ProtoMessage() {} func (*MsgCreateUserGroupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{5} + return fileDescriptor_c16a431ff9a3b35b, []int{7} } func (m *MsgCreateUserGroupResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -312,7 +388,7 @@ func (m *MsgDeleteUserGroup) Reset() { *m = MsgDeleteUserGroup{} } func (m *MsgDeleteUserGroup) String() string { return proto.CompactTextString(m) } func (*MsgDeleteUserGroup) ProtoMessage() {} func (*MsgDeleteUserGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{6} + return fileDescriptor_c16a431ff9a3b35b, []int{8} } func (m *MsgDeleteUserGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -370,7 +446,7 @@ func (m *MsgDeleteUserGroupResponse) Reset() { *m = MsgDeleteUserGroupRe func (m *MsgDeleteUserGroupResponse) String() string { return proto.CompactTextString(m) } func (*MsgDeleteUserGroupResponse) ProtoMessage() {} func (*MsgDeleteUserGroupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{7} + return fileDescriptor_c16a431ff9a3b35b, []int{9} } func (m *MsgDeleteUserGroupResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -412,7 +488,7 @@ func (m *MsgAddUserToUserGroup) Reset() { *m = MsgAddUserToUserGroup{} } func (m *MsgAddUserToUserGroup) String() string { return proto.CompactTextString(m) } func (*MsgAddUserToUserGroup) ProtoMessage() {} func (*MsgAddUserToUserGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{8} + return fileDescriptor_c16a431ff9a3b35b, []int{10} } func (m *MsgAddUserToUserGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -478,7 +554,7 @@ func (m *MsgAddUserToUserGroupResponse) Reset() { *m = MsgAddUserToUserG func (m *MsgAddUserToUserGroupResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddUserToUserGroupResponse) ProtoMessage() {} func (*MsgAddUserToUserGroupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{9} + return fileDescriptor_c16a431ff9a3b35b, []int{11} } func (m *MsgAddUserToUserGroupResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -520,7 +596,7 @@ func (m *MsgRemoveUserFromUserGroup) Reset() { *m = MsgRemoveUserFromUse func (m *MsgRemoveUserFromUserGroup) String() string { return proto.CompactTextString(m) } func (*MsgRemoveUserFromUserGroup) ProtoMessage() {} func (*MsgRemoveUserFromUserGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{10} + return fileDescriptor_c16a431ff9a3b35b, []int{12} } func (m *MsgRemoveUserFromUserGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -586,7 +662,7 @@ func (m *MsgRemoveUserFromUserGroupResponse) Reset() { *m = MsgRemoveUse func (m *MsgRemoveUserFromUserGroupResponse) String() string { return proto.CompactTextString(m) } func (*MsgRemoveUserFromUserGroupResponse) ProtoMessage() {} func (*MsgRemoveUserFromUserGroupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{11} + return fileDescriptor_c16a431ff9a3b35b, []int{13} } func (m *MsgRemoveUserFromUserGroupResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -628,7 +704,7 @@ func (m *MsgSetPermissions) Reset() { *m = MsgSetPermissions{} } func (m *MsgSetPermissions) String() string { return proto.CompactTextString(m) } func (*MsgSetPermissions) ProtoMessage() {} func (*MsgSetPermissions) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{12} + return fileDescriptor_c16a431ff9a3b35b, []int{14} } func (m *MsgSetPermissions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -694,7 +770,7 @@ func (m *MsgSetPermissionsResponse) Reset() { *m = MsgSetPermissionsResp func (m *MsgSetPermissionsResponse) String() string { return proto.CompactTextString(m) } func (*MsgSetPermissionsResponse) ProtoMessage() {} func (*MsgSetPermissionsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{13} + return fileDescriptor_c16a431ff9a3b35b, []int{15} } func (m *MsgSetPermissionsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -728,6 +804,8 @@ func init() { proto.RegisterType((*MsgCreateSubspaceResponse)(nil), "desmos.subspaces.v1.MsgCreateSubspaceResponse") proto.RegisterType((*MsgEditSubspace)(nil), "desmos.subspaces.v1.MsgEditSubspace") proto.RegisterType((*MsgEditSubspaceResponse)(nil), "desmos.subspaces.v1.MsgEditSubspaceResponse") + proto.RegisterType((*MsgDeleteSubspace)(nil), "desmos.subspaces.v1.MsgDeleteSubspace") + proto.RegisterType((*MsgDeleteSubspaceResponse)(nil), "desmos.subspaces.v1.MsgDeleteSubspaceResponse") proto.RegisterType((*MsgCreateUserGroup)(nil), "desmos.subspaces.v1.MsgCreateUserGroup") proto.RegisterType((*MsgCreateUserGroupResponse)(nil), "desmos.subspaces.v1.MsgCreateUserGroupResponse") proto.RegisterType((*MsgDeleteUserGroup)(nil), "desmos.subspaces.v1.MsgDeleteUserGroup") @@ -743,57 +821,59 @@ func init() { func init() { proto.RegisterFile("desmos/subspaces/v1/msgs.proto", fileDescriptor_c16a431ff9a3b35b) } var fileDescriptor_c16a431ff9a3b35b = []byte{ - // 797 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x96, 0xcd, 0x6e, 0xd3, 0x40, - 0x10, 0xc7, 0xe3, 0x24, 0x0d, 0xed, 0xf4, 0x23, 0xd4, 0xa5, 0x34, 0x35, 0x60, 0xa3, 0x6d, 0x55, - 0x28, 0x2a, 0xb1, 0x1a, 0x90, 0x40, 0xbd, 0x11, 0x5a, 0x50, 0x25, 0x02, 0xc8, 0x85, 0x0b, 0x97, - 0xca, 0x89, 0x17, 0xd7, 0x22, 0x8e, 0x23, 0xaf, 0x13, 0xe8, 0xb9, 0x17, 0x8e, 0x95, 0x78, 0x81, - 0x3e, 0x08, 0x57, 0x24, 0x8e, 0x3d, 0x72, 0xb2, 0x50, 0xca, 0x01, 0x38, 0xfa, 0x09, 0x90, 0xd7, - 0x1f, 0x71, 0x9c, 0xb8, 0x4d, 0x50, 0x0e, 0x88, 0x9b, 0x3d, 0xf3, 0xdb, 0x8f, 0xf9, 0xcf, 0xee, - 0xcc, 0x02, 0xaf, 0x60, 0xa2, 0x1b, 0x44, 0x24, 0xad, 0x2a, 0x69, 0xca, 0x35, 0x4c, 0xc4, 0xf6, - 0xa6, 0xa8, 0x13, 0x95, 0x14, 0x9b, 0xa6, 0x61, 0x19, 0xec, 0x82, 0xe7, 0x2f, 0x86, 0xfe, 0x62, - 0x7b, 0x93, 0xbb, 0xa2, 0x1a, 0xaa, 0x41, 0xfd, 0xa2, 0xfb, 0xe5, 0xa1, 0x1c, 0x1a, 0x34, 0x55, - 0xf0, 0xe3, 0x31, 0xe8, 0x28, 0x0d, 0xf3, 0x15, 0xa2, 0x3e, 0x36, 0xb1, 0x6c, 0xe1, 0x3d, 0xdf, - 0xc7, 0xae, 0x40, 0xb6, 0x21, 0xeb, 0xb8, 0xc0, 0xdc, 0x64, 0x6e, 0x4f, 0x95, 0xf3, 0x8e, 0x2d, - 0x4c, 0x1f, 0xca, 0x7a, 0x7d, 0x0b, 0xb9, 0x56, 0x24, 0x51, 0x27, 0xfb, 0x10, 0xa6, 0x15, 0x4c, - 0x6a, 0xa6, 0xd6, 0xb4, 0x34, 0xa3, 0x51, 0x48, 0x53, 0xf6, 0xaa, 0x63, 0x0b, 0xac, 0xc7, 0x46, - 0x9c, 0x48, 0x8a, 0xa2, 0xac, 0x08, 0x93, 0x96, 0x89, 0x65, 0xd2, 0x32, 0x0f, 0x0b, 0x19, 0x3a, - 0x6c, 0xc1, 0xb1, 0x85, 0xbc, 0x37, 0x2c, 0xf0, 0x20, 0x29, 0x84, 0xd8, 0x35, 0x98, 0x30, 0xde, - 0x37, 0xb0, 0x59, 0xc8, 0x52, 0xfa, 0xb2, 0x63, 0x0b, 0x33, 0x1e, 0x4d, 0xcd, 0x48, 0xf2, 0xdc, - 0xec, 0x06, 0x5c, 0xaa, 0xb9, 0x91, 0x18, 0x66, 0x61, 0x82, 0x92, 0xac, 0x63, 0x0b, 0x73, 0x1e, - 0xe9, 0x3b, 0x90, 0x14, 0x20, 0x5b, 0x93, 0x1f, 0x4f, 0x84, 0xd4, 0xcf, 0x13, 0x21, 0x85, 0xaa, - 0xb0, 0xdc, 0x27, 0x82, 0x84, 0x49, 0xd3, 0x68, 0x10, 0xcc, 0xee, 0xc0, 0x74, 0x20, 0xda, 0xbe, - 0xa6, 0x50, 0x4d, 0xb2, 0xe5, 0xd5, 0x8e, 0x2d, 0x40, 0x80, 0xee, 0x6e, 0x77, 0xa3, 0x8e, 0xa0, - 0x48, 0x82, 0xe0, 0x6f, 0x57, 0x41, 0x5f, 0xd2, 0x90, 0xaf, 0x10, 0x75, 0x47, 0xd1, 0xac, 0x50, - 0xe7, 0xf1, 0x4c, 0x1d, 0xa6, 0x2b, 0x3d, 0x42, 0xba, 0x32, 0x7f, 0x97, 0xae, 0xec, 0x48, 0xe9, - 0x9a, 0x38, 0x3f, 0x5d, 0xeb, 0x90, 0x23, 0x9a, 0xea, 0x82, 0x39, 0x0a, 0xce, 0x3b, 0xb6, 0x30, - 0xeb, 0xc7, 0x4a, 0xed, 0x48, 0xf2, 0x81, 0x48, 0xae, 0x96, 0x61, 0x29, 0x26, 0x63, 0x90, 0x29, - 0x74, 0x9c, 0x06, 0x36, 0xcc, 0xe3, 0x6b, 0x82, 0xcd, 0xa7, 0xa6, 0xd1, 0x6a, 0x8e, 0x4b, 0xe5, - 0xfb, 0x00, 0xaa, 0x3b, 0xdf, 0x7e, 0x44, 0xeb, 0x45, 0xc7, 0x16, 0xe6, 0xbd, 0x71, 0x5d, 0x1f, - 0x92, 0xa6, 0xe8, 0xcf, 0x73, 0x57, 0xf6, 0x17, 0xb0, 0xa0, 0xe0, 0xb7, 0x72, 0xab, 0x6e, 0xed, - 0x37, 0xb1, 0xa9, 0x6b, 0x84, 0x68, 0x46, 0x83, 0x50, 0xf9, 0x67, 0xcb, 0xbc, 0x63, 0x0b, 0x5c, - 0x20, 0x7f, 0x1f, 0x84, 0x24, 0xd6, 0xb7, 0xbe, 0xec, 0x1a, 0xa3, 0x67, 0x3c, 0x7b, 0xe1, 0x19, - 0x47, 0xd7, 0x81, 0xeb, 0x57, 0x24, 0x14, 0xec, 0x33, 0x43, 0x05, 0xdb, 0xc6, 0x75, 0xfc, 0xcf, - 0x08, 0xd6, 0x3d, 0x14, 0x99, 0x0b, 0x0e, 0x85, 0x1f, 0x5c, 0x6c, 0xf7, 0x61, 0x70, 0x3f, 0x18, - 0x58, 0xac, 0x10, 0xf5, 0x91, 0xa2, 0xb8, 0xbe, 0x57, 0xc6, 0xd8, 0xe3, 0x5b, 0x81, 0x6c, 0x8b, - 0x60, 0xb3, 0xff, 0xda, 0xb9, 0x56, 0x24, 0x51, 0x67, 0x4c, 0x84, 0xcc, 0xc8, 0x22, 0x64, 0x2f, - 0x12, 0x41, 0x80, 0x1b, 0x03, 0xa3, 0x0c, 0x75, 0xf8, 0xc5, 0x50, 0x99, 0x24, 0xac, 0x1b, 0x6d, - 0x2a, 0xd3, 0x13, 0xd3, 0xd0, 0xff, 0x53, 0x31, 0x56, 0x01, 0x25, 0x87, 0x1a, 0x2a, 0xf2, 0x9b, - 0xa1, 0x4d, 0x6f, 0x0f, 0xf7, 0x5c, 0xac, 0x31, 0x09, 0xb1, 0x0e, 0x39, 0x4b, 0x36, 0x55, 0x6c, - 0xf9, 0x52, 0x44, 0x76, 0xeb, 0xd9, 0x91, 0xe4, 0x03, 0x6e, 0x49, 0xee, 0xaf, 0x09, 0x91, 0x92, - 0xdc, 0x53, 0x0b, 0xa2, 0xe8, 0x28, 0x92, 0x5c, 0xa3, 0xbd, 0xad, 0x37, 0xd6, 0x40, 0x89, 0xd2, - 0xa7, 0x1c, 0x64, 0x2a, 0x44, 0x65, 0x0f, 0x60, 0x2e, 0xf6, 0x04, 0x58, 0x2b, 0x0e, 0x78, 0x68, - 0x14, 0xfb, 0xba, 0x24, 0x57, 0x1c, 0x8e, 0x0b, 0xbb, 0x69, 0x15, 0x66, 0x7a, 0x5a, 0xe0, 0x6a, - 0xd2, 0xf8, 0x28, 0xc5, 0x6d, 0x0c, 0x43, 0x85, 0x6b, 0xbc, 0x83, 0x7c, 0xbc, 0x07, 0xdc, 0x3a, - 0x7f, 0x9b, 0x21, 0xc8, 0x89, 0x43, 0x82, 0xd1, 0xc5, 0xe2, 0xf5, 0x33, 0x71, 0xb1, 0x18, 0x98, - 0xbc, 0x58, 0x42, 0x4d, 0x63, 0x2d, 0x60, 0x07, 0xd4, 0xb3, 0x3b, 0x49, 0xd3, 0xf4, 0xb3, 0x5c, - 0x69, 0x78, 0x36, 0x5c, 0xf5, 0x88, 0x81, 0xa5, 0xa4, 0xf2, 0x91, 0x18, 0x42, 0xc2, 0x00, 0xee, - 0xc1, 0x88, 0x03, 0xc2, 0x5d, 0x1c, 0xc0, 0x5c, 0xec, 0xc6, 0x26, 0x9e, 0xd1, 0x5e, 0x2e, 0xf9, - 0x8c, 0x0e, 0xbe, 0x15, 0xe5, 0x67, 0x5f, 0x3b, 0x3c, 0x73, 0xda, 0xe1, 0x99, 0xef, 0x1d, 0x9e, - 0x39, 0x3e, 0xe3, 0x53, 0xa7, 0x67, 0x7c, 0xea, 0xdb, 0x19, 0x9f, 0x7a, 0x53, 0x52, 0x35, 0xeb, - 0xa0, 0x55, 0x2d, 0xd6, 0x0c, 0x5d, 0xf4, 0xe6, 0xbc, 0x5b, 0x97, 0xab, 0xc4, 0xff, 0x16, 0xdb, - 0x25, 0xf1, 0x43, 0xe4, 0xb9, 0x6d, 0x1d, 0x36, 0x31, 0xa9, 0xe6, 0xe8, 0x4b, 0xfb, 0xde, 0x9f, - 0x00, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x41, 0x4a, 0xae, 0xda, 0x0b, 0x00, 0x00, + // 832 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x97, 0x3d, 0x6f, 0xd3, 0x5c, + 0x14, 0xc7, 0xe3, 0x24, 0xcd, 0xd3, 0x9e, 0xbe, 0xe4, 0xa9, 0x4b, 0x69, 0x6a, 0xc0, 0x46, 0xb7, + 0x55, 0x0b, 0xa8, 0xc4, 0x6a, 0x40, 0x02, 0x75, 0x23, 0xb4, 0xa0, 0x4a, 0x04, 0x90, 0x0b, 0x0b, + 0x4b, 0xe5, 0xc4, 0x17, 0xd7, 0x22, 0x8e, 0x23, 0x5f, 0x27, 0xd0, 0xb9, 0x0b, 0x1b, 0xfd, 0x08, + 0xfd, 0x20, 0xac, 0x48, 0x8c, 0x1d, 0x99, 0x2c, 0x94, 0x32, 0x00, 0xa3, 0x77, 0x24, 0xe4, 0xeb, + 0x97, 0x38, 0x4e, 0xdc, 0x26, 0x28, 0x03, 0x62, 0xb3, 0xef, 0xf9, 0xdd, 0x97, 0xf3, 0x3f, 0xe7, + 0x9e, 0x63, 0x03, 0xaf, 0x60, 0xa2, 0x1b, 0x44, 0x24, 0xad, 0x2a, 0x69, 0xca, 0x35, 0x4c, 0xc4, + 0xf6, 0xa6, 0xa8, 0x13, 0x95, 0x14, 0x9b, 0xa6, 0x61, 0x19, 0xec, 0x82, 0x67, 0x2f, 0x86, 0xf6, + 0x62, 0x7b, 0x93, 0xbb, 0xa4, 0x1a, 0xaa, 0x41, 0xed, 0xa2, 0xfb, 0xe4, 0xa1, 0x1c, 0x1a, 0xb4, + 0x54, 0xf0, 0xe2, 0x31, 0xe8, 0x28, 0x0d, 0xf3, 0x15, 0xa2, 0x3e, 0x34, 0xb1, 0x6c, 0xe1, 0x3d, + 0xdf, 0xc6, 0xae, 0x40, 0xb6, 0x21, 0xeb, 0xb8, 0xc0, 0x5c, 0x67, 0x6e, 0x4c, 0x95, 0xf3, 0x8e, + 0x2d, 0x4c, 0x1f, 0xca, 0x7a, 0x7d, 0x0b, 0xb9, 0xa3, 0x48, 0xa2, 0x46, 0xf6, 0x3e, 0x4c, 0x2b, + 0x98, 0xd4, 0x4c, 0xad, 0x69, 0x69, 0x46, 0xa3, 0x90, 0xa6, 0xec, 0x65, 0xc7, 0x16, 0x58, 0x8f, + 0x8d, 0x18, 0x91, 0x14, 0x45, 0x59, 0x11, 0x26, 0x2d, 0x13, 0xcb, 0xa4, 0x65, 0x1e, 0x16, 0x32, + 0x74, 0xda, 0x82, 0x63, 0x0b, 0x79, 0x6f, 0x5a, 0x60, 0x41, 0x52, 0x08, 0xb1, 0x6b, 0x30, 0x61, + 0xbc, 0x6d, 0x60, 0xb3, 0x90, 0xa5, 0xf4, 0xff, 0x8e, 0x2d, 0xcc, 0x78, 0x34, 0x1d, 0x46, 0x92, + 0x67, 0x66, 0x37, 0xe0, 0xbf, 0x9a, 0xeb, 0x89, 0x61, 0x16, 0x26, 0x28, 0xc9, 0x3a, 0xb6, 0x30, + 0xe7, 0x91, 0xbe, 0x01, 0x49, 0x01, 0xb2, 0x35, 0xf9, 0xfe, 0x44, 0x48, 0x7d, 0x3f, 0x11, 0x52, + 0xa8, 0x0a, 0xcb, 0x7d, 0x22, 0x48, 0x98, 0x34, 0x8d, 0x06, 0xc1, 0xec, 0x0e, 0x4c, 0x07, 0xa2, + 0xed, 0x6b, 0x0a, 0xd5, 0x24, 0x5b, 0x5e, 0xed, 0xd8, 0x02, 0x04, 0xe8, 0xee, 0x76, 0xd7, 0xeb, + 0x08, 0x8a, 0x24, 0x08, 0xde, 0x76, 0x15, 0xf4, 0x29, 0x0d, 0xf9, 0x0a, 0x51, 0x77, 0x14, 0xcd, + 0x0a, 0x75, 0x1e, 0xcf, 0xd2, 0x61, 0xb8, 0xd2, 0x23, 0x84, 0x2b, 0xf3, 0x67, 0xe1, 0xca, 0x8e, + 0x14, 0xae, 0x89, 0xf3, 0xc3, 0x75, 0x13, 0x72, 0x44, 0x53, 0x5d, 0x30, 0x47, 0xc1, 0x79, 0xc7, + 0x16, 0x66, 0x7d, 0x5f, 0xe9, 0x38, 0x92, 0x7c, 0x20, 0x12, 0xab, 0x65, 0x58, 0x8a, 0xc9, 0x18, + 0x44, 0x0a, 0x7d, 0x60, 0x68, 0x32, 0x6f, 0xe3, 0x3a, 0x8e, 0x24, 0xf3, 0x98, 0x44, 0xee, 0x1e, + 0x36, 0x3d, 0xfc, 0x61, 0xaf, 0xd0, 0xc4, 0xea, 0x3d, 0x50, 0x78, 0xdc, 0xe3, 0x34, 0xb0, 0x61, + 0xda, 0xbd, 0x24, 0xd8, 0x7c, 0x6c, 0x1a, 0xad, 0xe6, 0xb8, 0xce, 0x7b, 0x17, 0x40, 0x75, 0xd7, + 0xdb, 0x8f, 0xa4, 0xc6, 0xa2, 0x63, 0x0b, 0xf3, 0xde, 0xbc, 0xae, 0x0d, 0x49, 0x53, 0xf4, 0xe5, + 0xa9, 0x9b, 0x25, 0xcf, 0x60, 0x41, 0xc1, 0xaf, 0xe5, 0x56, 0xdd, 0xda, 0x6f, 0x62, 0x53, 0xd7, + 0x08, 0xd1, 0x8c, 0x06, 0xa1, 0xd9, 0x32, 0x5b, 0xe6, 0x1d, 0x5b, 0xe0, 0x82, 0x6c, 0xe9, 0x83, + 0x90, 0xc4, 0xfa, 0xa3, 0xcf, 0xbb, 0x83, 0xd1, 0x2b, 0x99, 0xbd, 0xf0, 0x4a, 0xa2, 0xab, 0xc0, + 0xf5, 0x2b, 0x12, 0x0a, 0xf6, 0x91, 0xa1, 0x82, 0x79, 0x72, 0xfe, 0x25, 0x82, 0x75, 0xd3, 0x22, + 0x73, 0x41, 0x5a, 0xf8, 0xce, 0xc5, 0x4e, 0x1f, 0x3a, 0xf7, 0x8d, 0x81, 0xc5, 0x0a, 0x51, 0x1f, + 0x28, 0x8a, 0x6b, 0x7b, 0x61, 0x8c, 0xdd, 0xbf, 0x15, 0xc8, 0xb6, 0x48, 0x98, 0xbe, 0x91, 0x2a, + 0xe1, 0x8e, 0x22, 0x89, 0x1a, 0x63, 0x22, 0x64, 0x46, 0x16, 0x21, 0x7b, 0x91, 0x08, 0x02, 0x5c, + 0x1b, 0xe8, 0x65, 0xa8, 0xc3, 0x0f, 0x86, 0xca, 0x24, 0x61, 0xdd, 0x68, 0x53, 0x99, 0x1e, 0x99, + 0x86, 0xfe, 0x8f, 0x8a, 0xb1, 0x0a, 0x28, 0xd9, 0xd5, 0x50, 0x91, 0x9f, 0x5e, 0x59, 0xdb, 0xc3, + 0x3d, 0x17, 0x6b, 0x7c, 0x65, 0xcd, 0x92, 0x4d, 0x15, 0x5b, 0xfd, 0x65, 0xcd, 0x1b, 0x47, 0x92, + 0x0f, 0xb8, 0x1d, 0xa4, 0xbf, 0x26, 0x44, 0x3a, 0x48, 0x4f, 0x2d, 0x88, 0xa2, 0xa3, 0x48, 0xe2, + 0x55, 0xcc, 0x5e, 0x5f, 0x03, 0x25, 0x4a, 0xbf, 0x72, 0x90, 0xa9, 0x10, 0x95, 0x3d, 0x80, 0xb9, + 0xd8, 0x17, 0xcb, 0x5a, 0x71, 0xc0, 0x77, 0x51, 0xb1, 0xaf, 0xa9, 0x73, 0xc5, 0xe1, 0xb8, 0xb0, + 0xf9, 0x57, 0x61, 0xa6, 0xa7, 0x63, 0xaf, 0x26, 0xcd, 0x8f, 0x52, 0xdc, 0xc6, 0x30, 0x54, 0xb8, + 0xc7, 0x01, 0xcc, 0xc5, 0x5a, 0x56, 0xa2, 0x37, 0xbd, 0x5c, 0xb2, 0x37, 0x83, 0x3b, 0x0e, 0xfb, + 0x06, 0xf2, 0xf1, 0x6e, 0xb3, 0x7e, 0xbe, 0x20, 0x21, 0xc8, 0x89, 0x43, 0x82, 0xd1, 0xcd, 0xe2, + 0x95, 0x7a, 0xfd, 0xfc, 0xf3, 0x0e, 0xb1, 0x59, 0x42, 0xf5, 0x64, 0x2d, 0x60, 0x07, 0x54, 0xce, + 0x5b, 0x49, 0xcb, 0xf4, 0xb3, 0x5c, 0x69, 0x78, 0x36, 0xdc, 0xf5, 0x88, 0x81, 0xa5, 0xa4, 0x42, + 0x95, 0xe8, 0x42, 0xc2, 0x04, 0xee, 0xde, 0x88, 0x13, 0xa2, 0xf9, 0x13, 0xab, 0x0d, 0x89, 0xf9, + 0xd3, 0xcb, 0x25, 0xe7, 0xcf, 0xe0, 0xfb, 0x57, 0x7e, 0xf2, 0xb9, 0xc3, 0x33, 0xa7, 0x1d, 0x9e, + 0xf9, 0xda, 0xe1, 0x99, 0xe3, 0x33, 0x3e, 0x75, 0x7a, 0xc6, 0xa7, 0xbe, 0x9c, 0xf1, 0xa9, 0x57, + 0x25, 0x55, 0xb3, 0x0e, 0x5a, 0xd5, 0x62, 0xcd, 0xd0, 0x45, 0x6f, 0xcd, 0xdb, 0x75, 0xb9, 0x4a, + 0xfc, 0x67, 0xb1, 0x5d, 0x12, 0xdf, 0x45, 0xfe, 0x43, 0xac, 0xc3, 0x26, 0x26, 0xd5, 0x1c, 0xfd, + 0x05, 0xb9, 0xf3, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xd7, 0xa0, 0x24, 0x14, 0xf3, 0x0c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -812,6 +892,8 @@ type MsgClient interface { CreateSubspace(ctx context.Context, in *MsgCreateSubspace, opts ...grpc.CallOption) (*MsgCreateSubspaceResponse, error) // EditSubspace allows to edit a subspace EditSubspace(ctx context.Context, in *MsgEditSubspace, opts ...grpc.CallOption) (*MsgEditSubspaceResponse, error) + // DeleteSubspace allows to delete a subspace + DeleteSubspace(ctx context.Context, in *MsgDeleteSubspace, opts ...grpc.CallOption) (*MsgDeleteSubspaceResponse, error) // CreateUserGroup allows to create a user group CreateUserGroup(ctx context.Context, in *MsgCreateUserGroup, opts ...grpc.CallOption) (*MsgCreateUserGroupResponse, error) // DeleteUserGroup allows to delete an existing user group @@ -851,6 +933,15 @@ func (c *msgClient) EditSubspace(ctx context.Context, in *MsgEditSubspace, opts return out, nil } +func (c *msgClient) DeleteSubspace(ctx context.Context, in *MsgDeleteSubspace, opts ...grpc.CallOption) (*MsgDeleteSubspaceResponse, error) { + out := new(MsgDeleteSubspaceResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/DeleteSubspace", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *msgClient) CreateUserGroup(ctx context.Context, in *MsgCreateUserGroup, opts ...grpc.CallOption) (*MsgCreateUserGroupResponse, error) { out := new(MsgCreateUserGroupResponse) err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/CreateUserGroup", in, out, opts...) @@ -902,6 +993,8 @@ type MsgServer interface { CreateSubspace(context.Context, *MsgCreateSubspace) (*MsgCreateSubspaceResponse, error) // EditSubspace allows to edit a subspace EditSubspace(context.Context, *MsgEditSubspace) (*MsgEditSubspaceResponse, error) + // DeleteSubspace allows to delete a subspace + DeleteSubspace(context.Context, *MsgDeleteSubspace) (*MsgDeleteSubspaceResponse, error) // CreateUserGroup allows to create a user group CreateUserGroup(context.Context, *MsgCreateUserGroup) (*MsgCreateUserGroupResponse, error) // DeleteUserGroup allows to delete an existing user group @@ -925,6 +1018,9 @@ func (*UnimplementedMsgServer) CreateSubspace(ctx context.Context, req *MsgCreat func (*UnimplementedMsgServer) EditSubspace(ctx context.Context, req *MsgEditSubspace) (*MsgEditSubspaceResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method EditSubspace not implemented") } +func (*UnimplementedMsgServer) DeleteSubspace(ctx context.Context, req *MsgDeleteSubspace) (*MsgDeleteSubspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteSubspace not implemented") +} func (*UnimplementedMsgServer) CreateUserGroup(ctx context.Context, req *MsgCreateUserGroup) (*MsgCreateUserGroupResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateUserGroup not implemented") } @@ -981,6 +1077,24 @@ func _Msg_EditSubspace_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Msg_DeleteSubspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgDeleteSubspace) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).DeleteSubspace(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/DeleteSubspace", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).DeleteSubspace(ctx, req.(*MsgDeleteSubspace)) + } + return interceptor(ctx, in, info, handler) +} + func _Msg_CreateUserGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MsgCreateUserGroup) if err := dec(in); err != nil { @@ -1083,6 +1197,10 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "EditSubspace", Handler: _Msg_EditSubspace_Handler, }, + { + MethodName: "DeleteSubspace", + Handler: _Msg_DeleteSubspace_Handler, + }, { MethodName: "CreateUserGroup", Handler: _Msg_CreateUserGroup_Handler, @@ -1280,6 +1398,64 @@ func (m *MsgEditSubspaceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } +func (m *MsgDeleteSubspace) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgDeleteSubspace) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDeleteSubspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x12 + } + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgDeleteSubspaceResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgDeleteSubspaceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDeleteSubspaceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + func (m *MsgCreateUserGroup) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -1722,6 +1898,31 @@ func (m *MsgEditSubspaceResponse) Size() (n int) { return n } +func (m *MsgDeleteSubspace) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + return n +} + +func (m *MsgDeleteSubspaceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + func (m *MsgCreateUserGroup) Size() (n int) { if m == nil { return 0 @@ -2445,6 +2646,157 @@ func (m *MsgEditSubspaceResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *MsgDeleteSubspace) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDeleteSubspace: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDeleteSubspace: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDeleteSubspaceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDeleteSubspaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDeleteSubspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/x/subspaces/types/msgs_test.go b/x/subspaces/types/msgs_test.go index 633093d959..3166f71451 100644 --- a/x/subspaces/types/msgs_test.go +++ b/x/subspaces/types/msgs_test.go @@ -184,6 +184,66 @@ func TestMsgEditSubspace_GetSigners(t *testing.T) { // -------------------------------------------------------------------------------------------------------------------- +var msgDeleteSubspace = types.NewMsgDeleteSubspace( + 1, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", +) + +func TestMsgDeleteSubspace_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgDeleteSubspace.Route()) +} + +func TestMsgDeleteSubspace_Type(t *testing.T) { + require.Equal(t, types.ActionEditSubspace, msgDeleteSubspace.Type()) +} + +func TestMsgDeleteSubspace_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgDeleteSubspace + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types.NewMsgDeleteSubspace(0, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"), + shouldErr: true, + }, + { + name: "invalid signer returns error", + msg: types.NewMsgDeleteSubspace(1, "cosmos1m0czrla04f7rp3z"), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgDeleteSubspace, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgDeleteSubspace_GetSignBytes(t *testing.T) { + expected := `{"signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1"}` + require.Equal(t, expected, string(msgDeleteSubspace.GetSignBytes())) +} + +func TestMsgDeleteSubspace_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgDeleteSubspace.Signer) + require.Equal(t, []sdk.AccAddress{addr}, msgDeleteSubspace.GetSigners()) +} + +// -------------------------------------------------------------------------------------------------------------------- + var msgCreateUserGroup = types.NewMsgCreateUserGroup( 1, "group", diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go index 751f3ced92..a258e38a0c 100644 --- a/x/subspaces/types/permissions.go +++ b/x/subspaces/types/permissions.go @@ -29,6 +29,9 @@ const ( // This includes managing user groups and the associated permissions PermissionSetPermissions = Permission(0b010000) + // PermissionDeleteSubspace allows users to delete the subspace. + PermissionDeleteSubspace = Permission(0b100000) + // PermissionEverything allows to do everything. // This should usually be reserved only to the owner (which has it by default) PermissionEverything = Permission(0b111111) From 12a14c1008f86ea33c0a626d864096810ad8b361 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 27 Jan 2022 11:00:50 +0100 Subject: [PATCH 24/47] removed begin blocker todo Signed-off-by: Riccardo Montagnin --- app/app.go | 1 - 1 file changed, 1 deletion(-) diff --git a/app/app.go b/app/app.go index 2f71834d04..6984b77bf6 100644 --- a/app/app.go +++ b/app/app.go @@ -535,7 +535,6 @@ func NewDesmosApp( app.mm.SetOrderBeginBlockers( upgradetypes.ModuleName, capabilitytypes.ModuleName, minttypes.ModuleName, distrtypes.ModuleName, slashingtypes.ModuleName, evidencetypes.ModuleName, stakingtypes.ModuleName, ibchost.ModuleName, - // TODO: See if we need a BeginBlocker for the subspaces module ) app.mm.SetOrderEndBlockers(crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName) From e68ffdd4f1bda5c530ae9a9d4c9bfd285ef42e20 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 27 Jan 2022 12:16:29 +0100 Subject: [PATCH 25/47] added store tests Signed-off-by: Riccardo Montagnin --- x/profiles/legacy/v230/keys.go | 40 ++++++++++++ x/profiles/legacy/v300/store.go | 65 ++++++++++--------- x/profiles/legacy/v300/store_test.go | 95 ++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 31 deletions(-) create mode 100644 x/profiles/legacy/v230/keys.go create mode 100644 x/profiles/legacy/v300/store_test.go diff --git a/x/profiles/legacy/v230/keys.go b/x/profiles/legacy/v230/keys.go new file mode 100644 index 0000000000..fa90f2fe84 --- /dev/null +++ b/x/profiles/legacy/v230/keys.go @@ -0,0 +1,40 @@ +package v230 + +var ( + RelationshipsStorePrefix = []byte("relationships") + UsersBlocksStorePrefix = []byte("users_blocks") +) + +// UserRelationshipsPrefix returns the prefix used to store all relationships created +// by the user with the given address +func UserRelationshipsPrefix(user string) []byte { + return append(RelationshipsStorePrefix, []byte(user)...) +} + +// UserRelationshipsSubspacePrefix returns the prefix used to store all the relationships created by the user +// with the given address for the subspace having the given id +func UserRelationshipsSubspacePrefix(user, subspace string) []byte { + return append(UserRelationshipsPrefix(user), []byte(subspace)...) +} + +// RelationshipsStoreKey returns the store key used to store the relationships containing the given data +func RelationshipsStoreKey(user, subspace, recipient string) []byte { + return append(UserRelationshipsSubspacePrefix(user, subspace), []byte(recipient)...) +} + +// BlockerPrefix returns the store prefix used to store the blocks created by the given blocker +func BlockerPrefix(blocker string) []byte { + return append(UsersBlocksStorePrefix, []byte(blocker)...) +} + +// BlockerSubspacePrefix returns the store prefix used to store the blocks that the given blocker +// has created inside the specified subspace +func BlockerSubspacePrefix(blocker string, subspace string) []byte { + return append(BlockerPrefix(blocker), []byte(subspace)...) +} + +// UserBlockStoreKey returns the store key used to save the block made by the given blocker, +// inside the specified subspace and towards the given blocked user +func UserBlockStoreKey(blocker string, subspace string, blockedUser string) []byte { + return append(BlockerSubspacePrefix(blocker, subspace), []byte(blockedUser)...) +} diff --git a/x/profiles/legacy/v300/store.go b/x/profiles/legacy/v300/store.go index fdcd78da9f..96db74ad79 100644 --- a/x/profiles/legacy/v300/store.go +++ b/x/profiles/legacy/v300/store.go @@ -5,6 +5,8 @@ import ( "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" + subspacestypes "github.com/desmos-labs/desmos/v2/x/subspaces/types" + v230 "github.com/desmos-labs/desmos/v2/x/profiles/legacy/v230" "github.com/desmos-labs/desmos/v2/x/profiles/types" ) @@ -32,17 +34,12 @@ func MigrateStore(ctx sdk.Context, storeKey sdk.StoreKey, cdc codec.BinaryCodec) // migrateUserBlocks migrates the user blocks stored to the new type, converting the subspace from string to uint64 func migrateUserBlocks(store sdk.KVStore, cdc codec.BinaryCodec) error { - var keys [][]byte var values []v230.UserBlock - userBlocksStore := prefix.NewStore(store, types.UsersBlocksStorePrefix) + userBlocksStore := prefix.NewStore(store, v230.UsersBlocksStorePrefix) iterator := userBlocksStore.Iterator(nil, nil) for ; iterator.Valid(); iterator.Next() { - // Get the keys - keys = append(keys, iterator.Key()) - - // Get the associated values var block v230.UserBlock err := cdc.Unmarshal(iterator.Value(), &block) if err != nil { @@ -57,20 +54,25 @@ func migrateUserBlocks(store sdk.KVStore, cdc codec.BinaryCodec) error { return err } - for i := 0; i < len(keys); i++ { + for _, v230Block := range values { + // Delete the previous key + store.Delete(v230.UserBlockStoreKey(v230Block.Blocker, v230Block.Subspace, v230Block.Blocked)) + + // Get the subspace id + subspaceID, err := subspacestypes.ParseSubspaceID(v230Block.Subspace) + if err != nil { + return err + } + // Serialize the block as the new type - blockBz, err := cdc.Marshal(&types.UserBlock{ - Blocker: values[i].Blocker, - Blocked: values[i].Blocked, - Reason: values[i].Reason, - Subspace: 0, - }) + v300Block := types.NewUserBlock(v230Block.Blocker, v230Block.Blocked, v230Block.Reason, subspaceID) + blockBz, err := cdc.Marshal(&v300Block) if err != nil { return err } - // Set the key inside the store - store.Set(keys[i], blockBz) + // Store the new value inside the store + store.Set(types.UserBlockStoreKey(v300Block.Blocker, v300Block.Subspace, v300Block.Blocked), blockBz) } return nil @@ -78,23 +80,18 @@ func migrateUserBlocks(store sdk.KVStore, cdc codec.BinaryCodec) error { // migrateRelationships migrates the relationships stored to the new type, converting the subspace from string to uint64 func migrateRelationships(store sdk.KVStore, cdc codec.BinaryCodec) error { - var keys [][]byte var values []v230.Relationship relationshipsStore := prefix.NewStore(store, types.RelationshipsStorePrefix) iterator := relationshipsStore.Iterator(nil, nil) for ; iterator.Valid(); iterator.Next() { - // Get the keys - keys = append(keys, iterator.Key()) - - // Get the associated values - var block v230.Relationship - err := cdc.Unmarshal(iterator.Value(), &block) + var relationship v230.Relationship + err := cdc.Unmarshal(iterator.Value(), &relationship) if err != nil { return err } - values = append(values, block) + values = append(values, relationship) } // Close the iterator @@ -103,19 +100,25 @@ func migrateRelationships(store sdk.KVStore, cdc codec.BinaryCodec) error { return err } - for i := 0; i < len(keys); i++ { + for _, v230Relationship := range values { + // Delete the previous key + store.Delete(v230.RelationshipsStoreKey(v230Relationship.Creator, v230Relationship.Subspace, v230Relationship.Recipient)) + + // Get the subspace id + subspaceID, err := subspacestypes.ParseSubspaceID(v230Relationship.Subspace) + if err != nil { + return err + } + // Serialize the relationship as the new type - blockBz, err := cdc.Marshal(&types.Relationship{ - Creator: values[i].Creator, - Recipient: values[i].Recipient, - Subspace: 0, - }) + v300Relationship := types.NewRelationship(v230Relationship.Creator, v230Relationship.Recipient, subspaceID) + relationshipBz, err := cdc.Marshal(&v300Relationship) if err != nil { return err } - // Set the key inside the store - store.Set(keys[i], blockBz) + // Store the new relationship inside the store + store.Set(types.RelationshipsStoreKey(v300Relationship.Creator, v300Relationship.Subspace, v300Relationship.Recipient), relationshipBz) } return nil diff --git a/x/profiles/legacy/v300/store_test.go b/x/profiles/legacy/v300/store_test.go new file mode 100644 index 0000000000..ea31c9c680 --- /dev/null +++ b/x/profiles/legacy/v300/store_test.go @@ -0,0 +1,95 @@ +package v300_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/testutil" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" + + "github.com/desmos-labs/desmos/v2/app" + v230 "github.com/desmos-labs/desmos/v2/x/profiles/legacy/v230" + v300 "github.com/desmos-labs/desmos/v2/x/profiles/legacy/v300" + "github.com/desmos-labs/desmos/v2/x/profiles/types" +) + +func TestMigrateStore(t *testing.T) { + cdc, _ := app.MakeCodecs() + storeKey := sdk.NewKVStoreKey(types.StoreKey) + testCases := []struct { + name string + store func(ctx sdk.Context) + shouldErr bool + check func(ctx sdk.Context) + }{ + { + name: "valid data returns no error", + store: func(ctx sdk.Context) { + store := ctx.KVStore(storeKey) + + block := v230.UserBlock{ + Blocker: "blocker", + Blocked: "blocked", + Reason: "reason", + Subspace: "", + } + blockBz := cdc.MustMarshal(&block) + store.Set(v230.UserBlockStoreKey(block.Blocker, block.Subspace, block.Blocked), blockBz) + + relationship := v230.Relationship{ + Creator: "user", + Recipient: "recipient", + Subspace: "2", + } + relBz := cdc.MustMarshal(&relationship) + store.Set(append(types.RelationshipsStorePrefix, 0x01), relBz) + }, + shouldErr: false, + check: func(ctx sdk.Context) { + store := ctx.KVStore(storeKey) + + oldBlockKey := v230.UserBlockStoreKey("blocker", "", "blocked") + require.False(t, store.Has(oldBlockKey)) + + expectedBlock := types.NewUserBlock("blocker", "blocked", "reason", 0) + expectedBlockKey := types.UserBlockStoreKey(expectedBlock.Blocker, expectedBlock.Subspace, expectedBlock.Blocked) + require.True(t, store.Has(expectedBlockKey)) + + var storedBlock types.UserBlock + cdc.MustUnmarshal(store.Get(expectedBlockKey), &storedBlock) + require.Equal(t, expectedBlock, storedBlock) + + oldRelationshipKey := v230.RelationshipsStoreKey("user", "2", "recipient") + require.False(t, store.Has(oldRelationshipKey)) + + expectedRelationship := types.NewRelationship("user", "recipient", 2) + expectedRelationshipKey := types.RelationshipsStoreKey(expectedRelationship.Creator, expectedRelationship.Subspace, expectedRelationship.Recipient) + require.True(t, store.Has(expectedRelationshipKey)) + + var storedRelationship types.Relationship + cdc.MustUnmarshal(store.Get(expectedRelationshipKey), &storedRelationship) + require.Equal(t, expectedRelationship, storedRelationship) + }, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + ctx := testutil.DefaultContext(storeKey, sdk.NewTransientStoreKey("test")) + if tc.store != nil { + tc.store(ctx) + } + + err := v300.MigrateStore(ctx, storeKey, cdc) + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} From 0b0ecc39d2845f4a3d9a9a92461328bf82916739 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 27 Jan 2022 12:23:17 +0100 Subject: [PATCH 26/47] fixed comments Signed-off-by: Riccardo Montagnin --- proto/desmos/subspaces/v1/genesis.proto | 2 +- proto/desmos/subspaces/v1/msgs.proto | 4 ++-- x/subspaces/types/genesis.pb.go | 2 +- x/subspaces/types/msgs.pb.go | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/proto/desmos/subspaces/v1/genesis.proto b/proto/desmos/subspaces/v1/genesis.proto index 1b613febee..657c5d7a8c 100644 --- a/proto/desmos/subspaces/v1/genesis.proto +++ b/proto/desmos/subspaces/v1/genesis.proto @@ -23,7 +23,7 @@ message GenesisState { repeated UserGroup user_groups = 4 [ (gogoproto.nullable) = false ]; } -// ACL represents a single Access Control List entry +// ACLEntry represents a single Access Control List entry message ACLEntry { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = true; diff --git a/proto/desmos/subspaces/v1/msgs.proto b/proto/desmos/subspaces/v1/msgs.proto index ecc6baf3e5..4f821063be 100644 --- a/proto/desmos/subspaces/v1/msgs.proto +++ b/proto/desmos/subspaces/v1/msgs.proto @@ -133,8 +133,8 @@ message MsgDeleteUserGroupResponse {} // -------------------------------------------------------------------------------------------------------------------- -// MsgSetUserGroupPermissions represents the message used to add a user to a -// user group +// MsgAddUserToUserGroup represents the message used to add a user to a user +// group message MsgAddUserToUserGroup { uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID", diff --git a/x/subspaces/types/genesis.pb.go b/x/subspaces/types/genesis.pb.go index 19c794bd84..2bc69d64be 100644 --- a/x/subspaces/types/genesis.pb.go +++ b/x/subspaces/types/genesis.pb.go @@ -92,7 +92,7 @@ func (m *GenesisState) GetUserGroups() []UserGroup { return nil } -// ACL represents a single Access Control List entry +// ACLEntry represents a single Access Control List entry type ACLEntry struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` // Either a group name or user address diff --git a/x/subspaces/types/msgs.pb.go b/x/subspaces/types/msgs.pb.go index 82a4ee42fe..e67ee90f36 100644 --- a/x/subspaces/types/msgs.pb.go +++ b/x/subspaces/types/msgs.pb.go @@ -475,8 +475,8 @@ func (m *MsgDeleteUserGroupResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgDeleteUserGroupResponse proto.InternalMessageInfo -// MsgSetUserGroupPermissions represents the message used to add a user to a -// user group +// MsgAddUserToUserGroup represents the message used to add a user to a user +// group type MsgAddUserToUserGroup struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` From 3298147180e522a43d3616958ed0c7590adfcc5b Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 27 Jan 2022 15:38:37 +0100 Subject: [PATCH 27/47] implemented the user groups Signed-off-by: Riccardo Montagnin --- app/params/weights.go | 4 +- proto/desmos/subspaces/v1/genesis.proto | 29 +- .../v1/{subspace.proto => models.proto} | 22 + proto/desmos/subspaces/v1/msgs.proto | 108 +- proto/desmos/subspaces/v1/query.proto | 92 +- x/profiles/simulation/genesis.go | 12 +- x/subspaces/client/cli/cli_test.go | 125 +- x/subspaces/client/cli/query.go | 7 +- x/subspaces/client/cli/tx.go | 240 ++- x/subspaces/handler.go | 10 +- x/subspaces/keeper/alias_functions.go | 54 +- x/subspaces/keeper/genesis.go | 78 +- x/subspaces/keeper/genesis_test.go | 330 ++-- x/subspaces/keeper/groups.go | 101 +- x/subspaces/keeper/groups_test.go | 426 +++-- x/subspaces/keeper/grpc_query.go | 74 +- x/subspaces/keeper/grpc_query_test.go | 254 ++- x/subspaces/keeper/hooks.go | 28 +- x/subspaces/keeper/invariants.go | 58 +- x/subspaces/keeper/invariants_test.go | 44 +- x/subspaces/keeper/msg_server.go | 235 ++- x/subspaces/keeper/msg_server_test.go | 209 +- x/subspaces/keeper/permissions.go | 95 +- x/subspaces/keeper/permissions_test.go | 365 ++-- x/subspaces/keeper/subspaces.go | 47 +- x/subspaces/keeper/subspaces_test.go | 193 +- x/subspaces/simulation/decoder.go | 13 +- x/subspaces/simulation/decoder_test.go | 25 +- x/subspaces/simulation/genesis.go | 86 +- x/subspaces/simulation/operations.go | 36 +- x/subspaces/simulation/operations_groups.go | 195 +- .../simulation/operations_permissions.go | 25 +- .../simulation/operations_subspaces.go | 16 + x/subspaces/simulation/utils.go | 5 + x/subspaces/types/codec.go | 8 +- x/subspaces/types/events.go | 21 +- x/subspaces/types/genesis.go | 169 +- x/subspaces/types/genesis.pb.go | 508 +++-- x/subspaces/types/genesis_test.go | 497 ++++- x/subspaces/types/hooks.go | 40 +- x/subspaces/types/keys.go | 74 +- x/subspaces/types/{subspace.go => models.go} | 81 + x/subspaces/types/models.pb.go | 1046 ++++++++++ .../{subspace_test.go => models_test.go} | 200 ++ x/subspaces/types/msgs.go | 153 +- x/subspaces/types/msgs.pb.go | 1683 +++++++++++++---- x/subspaces/types/msgs_test.go | 250 ++- x/subspaces/types/permissions.go | 43 +- x/subspaces/types/query.go | 20 +- x/subspaces/types/query.pb.go | 1251 +++++++----- x/subspaces/types/query.pb.gw.go | 272 ++- x/subspaces/types/subspace.pb.go | 678 ------- 52 files changed, 7616 insertions(+), 3019 deletions(-) rename proto/desmos/subspaces/v1/{subspace.proto => models.proto} (67%) rename x/subspaces/types/{subspace.go => models.go} (57%) create mode 100644 x/subspaces/types/models.pb.go rename x/subspaces/types/{subspace_test.go => models_test.go} (56%) delete mode 100644 x/subspaces/types/subspace.pb.go diff --git a/app/params/weights.go b/app/params/weights.go index 33dfaf43ab..f970c887ec 100644 --- a/app/params/weights.go +++ b/app/params/weights.go @@ -18,8 +18,10 @@ const ( DefaultWeightMsgEditSubspace int = 30 DefaultWeightMsgDeleteSubspace int = 5 DefaultWeightMsgCreateUserGroup int = 10 + DefaultWeightMsgEditUserGroup int = 30 + DefaultWeightMsgSetUserGroupPermissions int = 50 DefaultWeightMsgDeleteUserGroup int = 5 DefaultWeightMsgAddUserToUserGroup int = 7 DefaultWeightMsgRemoveUserFromUserGroup int = 3 - DefaultWeightMsgSetPermissions int = 85 + DefaultWeightMsgSetUserPermissions int = 85 ) diff --git a/proto/desmos/subspaces/v1/genesis.proto b/proto/desmos/subspaces/v1/genesis.proto index 657c5d7a8c..8e5481946f 100644 --- a/proto/desmos/subspaces/v1/genesis.proto +++ b/proto/desmos/subspaces/v1/genesis.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package desmos.subspaces.v1; import "gogoproto/gogo.proto"; -import "desmos/subspaces/v1/subspace.proto"; +import "desmos/subspaces/v1/models.proto"; option go_package = "github.com/desmos-labs/desmos/v2/x/subspaces/types"; @@ -14,13 +14,24 @@ message GenesisState { uint64 initial_subspace_id = 1 [ (gogoproto.customname) = "InitialSubspaceID" ]; - repeated desmos.subspaces.v1.Subspace subspaces = 2 - [ (gogoproto.nullable) = false ]; + repeated GenesisSubspace subspaces = 2 [ (gogoproto.nullable) = false ]; repeated ACLEntry acl = 3 [ (gogoproto.customname) = "ACL", (gogoproto.nullable) = false ]; repeated UserGroup user_groups = 4 [ (gogoproto.nullable) = false ]; + + repeated UserGroupMembersEntry user_groups_members = 5 + [ (gogoproto.nullable) = false ]; +} + +// GenesisSubspace contains the genesis data for a single subspace +message GenesisSubspace { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + + Subspace subspace = 1 [ (gogoproto.nullable) = false ]; + uint32 initial_group_id = 2 [ (gogoproto.customname) = "InitialGroupID" ]; } // ACLEntry represents a single Access Control List entry @@ -29,19 +40,17 @@ message ACLEntry { option (gogoproto.goproto_stringer) = true; uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID" ]; - - // Either a group name or user address - string target = 2; - + string user = 2; uint32 permissions = 3; } -// UserGroup contains the data of a single user group present inside a subspace -message UserGroup { +// UserGroupMembersEntry contains all the members of a specific user group +message UserGroupMembersEntry { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = true; uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID" ]; - string name = 2; + uint32 group_id = 2 [ (gogoproto.customname) = "GroupID" ]; + ; repeated string members = 3; } \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/subspace.proto b/proto/desmos/subspaces/v1/models.proto similarity index 67% rename from proto/desmos/subspaces/v1/subspace.proto rename to proto/desmos/subspaces/v1/models.proto index bb54788b69..676e497816 100644 --- a/proto/desmos/subspaces/v1/subspace.proto +++ b/proto/desmos/subspaces/v1/models.proto @@ -38,3 +38,25 @@ message Subspace { (gogoproto.moretags) = "yaml:\"creation_time\"" ]; } + +// UserGroup represents a group of users +message UserGroup { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = true; + + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + + // Unique id that identifies the group + uint32 id = 2 + [ (gogoproto.customname) = "ID", (gogoproto.moretags) = "yaml:\"id\"" ]; + + // Human-readable name of the user group + string name = 3 [ (gogoproto.moretags) = "yaml:\"name\"" ]; + + string description = 4 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + + uint32 permissions = 5 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; +} \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/msgs.proto b/proto/desmos/subspaces/v1/msgs.proto index 4f821063be..170687bcfd 100644 --- a/proto/desmos/subspaces/v1/msgs.proto +++ b/proto/desmos/subspaces/v1/msgs.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package desmos.subspaces.v1; import "gogoproto/gogo.proto"; -import "desmos/subspaces/v1/subspace.proto"; +import "desmos/subspaces/v1/models.proto"; option go_package = "github.com/desmos-labs/desmos/v2/x/subspaces/types"; @@ -21,6 +21,13 @@ service Msg { // CreateUserGroup allows to create a user group rpc CreateUserGroup(MsgCreateUserGroup) returns (MsgCreateUserGroupResponse); + // EditUserGroup allows to edit a user group + rpc EditUserGroup(MsgEditUserGroup) returns (MsgEditUserGroupResponse); + + // SetUserGroupPermissions allows to set the permissions for a specific group + rpc SetUserGroupPermissions(MsgSetUserGroupPermissions) + returns (MsgSetUserGroupPermissionsResponse); + // DeleteUserGroup allows to delete an existing user group rpc DeleteUserGroup(MsgDeleteUserGroup) returns (MsgDeleteUserGroupResponse); @@ -33,8 +40,9 @@ service Msg { rpc RemoveUserFromUserGroup(MsgRemoveUserFromUserGroup) returns (MsgRemoveUserFromUserGroupResponse); - // SetPermissions allows to set another user's permissions - rpc SetPermissions(MsgSetPermissions) returns (MsgSetPermissionsResponse); + // SetUserPermissions allows to set the permissions for a specific user + rpc SetUserPermissions(MsgSetUserPermissions) + returns (MsgSetUserPermissionsResponse); } // -------------------------------------------------------------------------------------------------------------------- @@ -107,14 +115,68 @@ message MsgCreateUserGroup { (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; - string group_name = 2 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; - uint32 default_permissions = 3 + // Name of the group + string name = 2 [ (gogoproto.moretags) = "yaml:\"name\"" ]; + + // Optional description of the group + string description = 3 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + + // Default permissions to be applied to the group + uint32 default_permissions = 4 [ (gogoproto.moretags) = "yaml:\"default_permissions\"" ]; - string creator = 4 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; + + // Creator of the group + string creator = 5 [ (gogoproto.moretags) = "yaml:\"creator\"" ]; } // MsgCreateUserGroupResponse defines the Msg/CreateUserGroup response type -message MsgCreateUserGroupResponse {} +message MsgCreateUserGroupResponse { + uint32 group_id = 1 [ + (gogoproto.customname) = "GroupID", + (gogoproto.moretags) = "yaml:\"group_id\"" + ]; +} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgEditUserGroup represents the message used to edit a user group +message MsgEditUserGroup { + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + uint32 group_id = 2 [ + (gogoproto.customname) = "GroupID", + (gogoproto.moretags) = "yaml:\"group_id\"" + ]; + string name = 3 [ (gogoproto.moretags) = "yaml:\"name\"" ]; + string description = 4 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + string signer = 5 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; +} + +// MsgEditUserGroupResponse defines the Msg/EditUserGroup response type +message MsgEditUserGroupResponse {} + +// -------------------------------------------------------------------------------------------------------------------- + +// MsgSetUserGroupPermissions represents the message used to set the permissions +// of a user group +message MsgSetUserGroupPermissions { + uint64 subspace_id = 1 [ + (gogoproto.customname) = "SubspaceID", + (gogoproto.moretags) = "yaml:\"subspace_id\"" + ]; + uint32 group_id = 2 [ + (gogoproto.customname) = "GroupID", + (gogoproto.moretags) = "yaml:\"group_id\"" + ]; + uint32 permissions = 3 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; + string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; +} + +// MsgSetUserGroupPermissionsResponse defines the +// Msg/SetUserGroupPermissionsResponse response type +message MsgSetUserGroupPermissionsResponse {} // -------------------------------------------------------------------------------------------------------------------- @@ -124,7 +186,10 @@ message MsgDeleteUserGroup { (gogoproto.customname) = "SubspaceID", (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; - string group_name = 2 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; + uint32 group_id = 2 [ + (gogoproto.customname) = "GroupID", + (gogoproto.moretags) = "yaml:\"group_id\"" + ]; string signer = 3 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; } @@ -140,8 +205,11 @@ message MsgAddUserToUserGroup { (gogoproto.customname) = "SubspaceID", (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; - string user = 2 [ (gogoproto.moretags) = "yaml:\"user\"" ]; - string group_name = 3 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; + uint32 group_id = 2 [ + (gogoproto.customname) = "GroupID", + (gogoproto.moretags) = "yaml:\"group_id\"" + ]; + string user = 3 [ (gogoproto.moretags) = "yaml:\"user\"" ]; string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; } @@ -158,8 +226,11 @@ message MsgRemoveUserFromUserGroup { (gogoproto.customname) = "SubspaceID", (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; - string user = 2 [ (gogoproto.moretags) = "yaml:\"user\"" ]; - string group_name = 3 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; + uint32 group_id = 2 [ + (gogoproto.customname) = "GroupID", + (gogoproto.moretags) = "yaml:\"group_id\"" + ]; + string user = 3 [ (gogoproto.moretags) = "yaml:\"user\"" ]; string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; } @@ -169,19 +240,18 @@ message MsgRemoveUserFromUserGroupResponse {} // -------------------------------------------------------------------------------------------------------------------- -// MsgSetPermissions represents the message used to set the permissions of a -// user or user group -message MsgSetPermissions { +// MsgSetUserPermissions represents the message used to set the permissions of a +// specific user +message MsgSetUserPermissions { uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID", (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; - - string target = 2 [ (gogoproto.moretags) = "yaml:\"target\"" ]; + string user = 2 [ (gogoproto.moretags) = "yaml:\"user\"" ]; uint32 permissions = 3 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; string signer = 4 [ (gogoproto.moretags) = "yaml:\"signer\"" ]; } -// MsgSetPermissionsResponse defines the Msg/SetPermissionsResponse +// MsgSetUserPermissionsResponse defines the Msg/SetPermissionsResponse // response type -message MsgSetPermissionsResponse {} \ No newline at end of file +message MsgSetUserPermissionsResponse {} \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/query.proto b/proto/desmos/subspaces/v1/query.proto index 8195d67dca..aef6cedf44 100644 --- a/proto/desmos/subspaces/v1/query.proto +++ b/proto/desmos/subspaces/v1/query.proto @@ -3,7 +3,7 @@ package desmos.subspaces.v1; import "gogoproto/gogo.proto"; import "google/api/annotations.proto"; -import "desmos/subspaces/v1/subspace.proto"; +import "desmos/subspaces/v1/models.proto"; import "cosmos/base/query/v1beta1/pagination.proto"; option go_package = "github.com/desmos-labs/desmos/v2/x/subspaces/types"; @@ -11,54 +11,47 @@ option go_package = "github.com/desmos-labs/desmos/v2/x/subspaces/types"; // Query defines the gRPC querier service service Query { - // Subspace queries all the information about the subspace with the given id - rpc Subspace(QuerySubspaceRequest) returns (QuerySubspaceResponse) { - option (google.api.http).get = "/desmos/subspaces/v1/{subspace_id}"; - } - // Subspaces queries all the subspaces inside Desmos rpc Subspaces(QuerySubspacesRequest) returns (QuerySubspacesResponse) { option (google.api.http).get = "/desmos/subspaces/v1/subspaces"; } + // Subspace queries all the information about the subspace with the given id + rpc Subspace(QuerySubspaceRequest) returns (QuerySubspaceResponse) { + option (google.api.http).get = + "/desmos/subspaces/v1/subspaces/{subspace_id}"; + } + // UserGroups queries all the groups that are present inside the subspace with // the given id rpc UserGroups(QueryUserGroupsRequest) returns (QueryUserGroupsResponse) { - option (google.api.http).get = "/desmos/subspaces/v1/{subspace_id}/groups"; + option (google.api.http).get = "/desmos/subspaces/v1/groups/{subspace_id}"; + } + + // UserGroup queries the user group having the given id inside the specific + // subspace + rpc UserGroup(QueryUserGroupRequest) returns (QueryUserGroupResponse) { + option (google.api.http).get = + "/desmos/subspaces/v1/groups/{subspace_id}/{group_id}"; } // UserGroupMembers queries all the members of a given user group rpc UserGroupMembers(QueryUserGroupMembersRequest) returns (QueryUserGroupMembersResponse) { option (google.api.http).get = - "/desmos/subspaces/v1/{subspace_id}/groups/{group_name}/members"; + "/desmos/subspaces/v1/groups/{subspace_id}/{group_id}/members"; } - // Permissions queries the permissions for the given target (user address or - // group name) - rpc Permissions(QueryPermissionsRequest) returns (QueryPermissionsResponse) { + // UserPermissions queries the permissions for the given user + rpc UserPermissions(QueryUserPermissionsRequest) + returns (QueryUserPermissionsResponse) { option (google.api.http).get = - "/desmos/subspaces/v1/{subspace_id}/permissions/{target}"; + "/desmos/subspaces/v1/permissions/{subspace_id}/{user}"; } } // -------------------------------------------------------------------------------------------------------------------- -// QuerySubspace is the request type for the Query/Subspace RPC method -message QuerySubspaceRequest { - option (gogoproto.equal) = false; - option (gogoproto.goproto_getters) = false; - - uint64 subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; -} - -// QuerySubspaceResponse is the response type for the Query/Subspace method -message QuerySubspaceResponse { - desmos.subspaces.v1.Subspace subspace = 1 [ (gogoproto.nullable) = false ]; -} - -// -------------------------------------------------------------------------------------------------------------------- - // QuerySubspacesRequest is the request type for the Query/Subspaces RPC method message QuerySubspacesRequest { // pagination defines an optional pagination for the request. @@ -74,6 +67,21 @@ message QuerySubspacesResponse { // -------------------------------------------------------------------------------------------------------------------- +// QuerySubspace is the request type for the Query/Subspace RPC method +message QuerySubspaceRequest { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + + uint64 subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; +} + +// QuerySubspaceResponse is the response type for the Query/Subspace method +message QuerySubspaceResponse { + desmos.subspaces.v1.Subspace subspace = 1 [ (gogoproto.nullable) = false ]; +} + +// -------------------------------------------------------------------------------------------------------------------- + // QueryUserGroupsRequest is the request type for the Query/UserGroups RPC // method message QueryUserGroupsRequest { @@ -86,17 +94,31 @@ message QueryUserGroupsRequest { // QueryUserGroupsResponse is the response type for the Query/UserGroups RPC // method message QueryUserGroupsResponse { - repeated string groups = 1; + repeated UserGroup groups = 1 [ (gogoproto.nullable) = false ]; cosmos.base.query.v1beta1.PageResponse pagination = 2; } // -------------------------------------------------------------------------------------------------------------------- +// QueryUserGroupRequest is the request type for the Query/UserGroup RPC method +message QueryUserGroupRequest { + uint64 subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; + uint32 group_id = 2 [ (gogoproto.moretags) = "yaml:\"group_id\"" ]; +} + +// QueryUserGroupResponse is the response type for the Query/UserGroup RPC +// method +message QueryUserGroupResponse { + UserGroup group = 1 [ (gogoproto.nullable) = false ]; +} + +// -------------------------------------------------------------------------------------------------------------------- + // QueryUserGroupMembersRequest is the request type for the // Query/UserGroupMembers RPC method message QueryUserGroupMembersRequest { uint64 subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; - string group_name = 2 [ (gogoproto.moretags) = "yaml:\"group_name\"" ]; + uint32 group_id = 2 [ (gogoproto.moretags) = "yaml:\"group_id\"" ]; // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageRequest pagination = 3; @@ -111,16 +133,18 @@ message QueryUserGroupMembersResponse { // -------------------------------------------------------------------------------------------------------------------- -// QuerySubspace is the request type for the Query/Subspace RPC method -message QueryPermissionsRequest { +// QueryUserPermissionsRequest is the request type for the Query/UserPermissions +// RPC method +message QueryUserPermissionsRequest { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; uint64 subspace_id = 1 [ (gogoproto.moretags) = "yaml:\"subspace_id\"" ]; - string target = 2 [ (gogoproto.moretags) = "yaml:\"target\"" ]; + string user = 2 [ (gogoproto.moretags) = "yaml:\"user\"" ]; } -// QuerySubspaceResponse is the response type for the Query/Subspace method -message QueryPermissionsResponse { +// QueryUserPermissionsRequest is the response type for the +// Query/UserPermissions method +message QueryUserPermissionsResponse { uint32 permissions = 1 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; } \ No newline at end of file diff --git a/x/profiles/simulation/genesis.go b/x/profiles/simulation/genesis.go index 4a2020c087..164262d5ef 100644 --- a/x/profiles/simulation/genesis.go +++ b/x/profiles/simulation/genesis.go @@ -145,7 +145,7 @@ func containsDTagTransferRequest(slice []types.DTagTransferRequest, request type // randomRelationships returns randomly generated genesis relationships and their associated users - IDs map func randomRelationships( - profiles []*types.Profile, subspaces []subspacestypes.Subspace, simState *module.SimulationState, number int, + profiles []*types.Profile, subspaces []subspacestypes.GenesisSubspace, simState *module.SimulationState, number int, ) []types.Relationship { relationships := make([]types.Relationship, number) for index := 0; index < number; { @@ -157,11 +157,11 @@ func randomRelationships( continue } - subspace, _ := subspacessim.RandomSubspace(simState.Rand, subspaces) + subspace := subspacessim.RandomGenesisSubspace(simState.Rand, subspaces) relationship := types.NewRelationship( profile1.GetAddress().String(), profile2.GetAddress().String(), - subspace.ID, + subspace.Subspace.ID, ) if !containsRelationship(relationships, relationship) { @@ -188,7 +188,7 @@ func containsRelationship(slice []types.Relationship, relationship types.Relatio // randomUsersBlocks func randomUsersBlocks( - profiles []*types.Profile, subspaces []subspacestypes.Subspace, simState *module.SimulationState, number int, + profiles []*types.Profile, subspaces []subspacestypes.GenesisSubspace, simState *module.SimulationState, number int, ) []types.UserBlock { usersBlocks := make([]types.UserBlock, number) for index := 0; index < number; { @@ -200,12 +200,12 @@ func randomUsersBlocks( continue } - subspace, _ := subspacessim.RandomSubspace(simState.Rand, subspaces) + subspace := subspacessim.RandomGenesisSubspace(simState.Rand, subspaces) block := types.NewUserBlock( profile1.GetAddress().String(), profile2.GetAddress().String(), "reason", - subspace.ID, + subspace.Subspace.ID, ) if !containsUserBlock(usersBlocks, block) { diff --git a/x/subspaces/client/cli/cli_test.go b/x/subspaces/client/cli/cli_test.go index e964f7e0b0..cbd2c5e706 100644 --- a/x/subspaces/client/cli/cli_test.go +++ b/x/subspaces/client/cli/cli_test.go @@ -40,56 +40,68 @@ func (s *IntegrationTestSuite) SetupSuite() { cfg.NumValidators = 2 // Initialize the module genesis data - var subspacesData types.GenesisState - s.Require().NoError(cfg.Codec.UnmarshalJSON(genesisState[types.ModuleName], &subspacesData)) - - subspacesData.InitialSubspaceID = 3 - subspacesData.Subspaces = []types.Subspace{ - types.NewSubspace( - 1, - "Test subspace", - "This is a test subspace", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), - ), - types.NewSubspace( - 2, - "Another test subspace", - "This is another test subspace", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), - ), - types.NewSubspace( - 3, - "Subspace to delete", - "This is a test subspace that will be deleted", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), - ), - } - subspacesData.ACL = []types.ACLEntry{ - types.NewACLEntry(1, "group", types.PermissionWrite), - types.NewACLEntry(2, "another-group", types.PermissionManageGroups), - } - subspacesData.UserGroups = []types.UserGroup{ - types.NewUserGroup(1, "group", []string{ - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - }), - types.NewUserGroup(2, "another-group", []string{ - "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - }), - types.NewUserGroup(2, "third-group", nil), - } + genesis := types.NewGenesisState( + 3, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + types.NewGenesisSubspace( + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + 3, + ), + types.NewGenesisSubspace( + types.NewSubspace( + 3, + "Subspace to delete", + "This is a test subspace that will be deleted", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, + []types.ACLEntry{ + types.NewACLEntry(1, "cosmos1xw69y2z3yf00rgfnly99628gn5c0x7fryyfv5e", types.PermissionWrite), + types.NewACLEntry(2, "cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd", types.PermissionManageGroups), + }, + []types.UserGroup{ + types.NewUserGroup(1, 1, "Test group", "", types.PermissionWrite), + types.NewUserGroup(2, 1, "Another test group", "", types.PermissionManageGroups), + types.NewUserGroup(2, 2, "Third group", "", types.PermissionWrite), + }, + []types.UserGroupMembersEntry{ + types.NewUserGroupMembersEntry(1, 1, []string{ + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + }), + types.NewUserGroupMembersEntry(2, 1, []string{ + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + }), + }, + ) // Store the genesis data - subspacesDataBz, err := cfg.Codec.MarshalJSON(&subspacesData) + subspacesDataBz, err := cfg.Codec.MarshalJSON(genesis) s.Require().NoError(err) genesisState[types.ModuleName] = subspacesDataBz cfg.GenesisState = genesisState @@ -235,7 +247,10 @@ func (s *IntegrationTestSuite) TestCmdQueryUserGroups() { }, shouldErr: false, expResponse: types.QueryUserGroupsResponse{ - Groups: []string{"another-group", "third-group"}, + Groups: []types.UserGroup{ + types.NewUserGroup(2, 1, "Another test group", "", types.PermissionManageGroups), + types.NewUserGroup(2, 2, "Third group", "", types.PermissionWrite), + }, }, }, } @@ -498,7 +513,7 @@ func (s *IntegrationTestSuite) TestCmdDeleteUserGroup() { { name: "valid data returns no error", args: []string{ - "2", "testing-group", + "2", "1", fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), @@ -546,13 +561,13 @@ func (s *IntegrationTestSuite) TestCmdAddUserToUserGroup() { }, { name: "invalid user returns error", - args: []string{"1", "group", ""}, + args: []string{"1", "1", ""}, shouldErr: true, }, { name: "valid data returns no error", args: []string{ - "2", "testing-group", "cosmos1et50whs236j9dacacz7feh05jjum9jk04cdt9u", + "2", "1", "cosmos1et50whs236j9dacacz7feh05jjum9jk04cdt9u", fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), @@ -606,7 +621,7 @@ func (s *IntegrationTestSuite) TestCmdRemoveUserFromUserGroup() { { name: "valid data returns no error", args: []string{ - "2", "testing-group", "cosmos1et50whs236j9dacacz7feh05jjum9jk04cdt9u", + "2", "1", "cosmos1et50whs236j9dacacz7feh05jjum9jk04cdt9u", fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), @@ -660,7 +675,7 @@ func (s *IntegrationTestSuite) TestCmdSetPermissions() { { name: "valid data returns no error", args: []string{ - "1", "group", "Write", + "1", "cosmos1xw69y2z3yf00rgfnly99628gn5c0x7fryyfv5e", "Write", fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), @@ -674,7 +689,7 @@ func (s *IntegrationTestSuite) TestCmdSetPermissions() { for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - cmd := cli.GetCmdSetPermissions() + cmd := cli.GetCmdSetUserPermissions() clientCtx := val.ClientCtx out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) diff --git a/x/subspaces/client/cli/query.go b/x/subspaces/client/cli/query.go index eed3f2f978..ef6d2e4f70 100644 --- a/x/subspaces/client/cli/query.go +++ b/x/subspaces/client/cli/query.go @@ -170,11 +170,14 @@ func GetCmdQueryUserGroupMembers() *cobra.Command { return err } - groupName := args[1] + groupID, err := types.ParseGroupID(args[1]) + if err != nil { + return err + } res, err := queryClient.UserGroupMembers( context.Background(), - types.NewQueryUserGroupMembersRequest(subspaceID, groupName, pageReq), + types.NewQueryUserGroupMembersRequest(subspaceID, groupID, pageReq), ) if err != nil { return err diff --git a/x/subspaces/client/cli/tx.go b/x/subspaces/client/cli/tx.go index 08549d850b..dbba0d8fa7 100644 --- a/x/subspaces/client/cli/tx.go +++ b/x/subspaces/client/cli/tx.go @@ -20,6 +20,7 @@ const ( FlagDescription = "description" FlagTreasury = "treasury" FlagOwner = "owner" + FlagPermissions = "permissions" ) // NewTxCmd returns a new command to perform subspaces transactions @@ -35,11 +36,10 @@ func NewTxCmd() *cobra.Command { subspacesTxCmd.AddCommand( GetCmdCreateSubspace(), GetCmdEditSubspace(), - GetCmdCreateUserGroup(), - GetCmdDeleteUserGroup(), - GetCmdAddUserToUserGroup(), - GetCmdRemoveUserFromUserGroup(), - GetCmdSetPermissions(), + + NewGroupsTxCmd(), + + GetCmdSetUserPermissions(), ) return subspacesTxCmd @@ -197,18 +197,47 @@ func GetCmdDeleteSubspace() *cobra.Command { return cmd } +// ------------------------------------------------------------------------------------------------------------------- + +// NewGroupsTxCmd returns a new command to perform subspaces groups transactions +func NewGroupsTxCmd() *cobra.Command { + groupsTxCmd := &cobra.Command{ + Use: "groups", + Short: "Subspace groups transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + groupsTxCmd.AddCommand( + GetCmdCreateUserGroup(), + GetCmdEditUserGroup(), + GetCmdSetUserGroupPermissions(), + GetCmdDeleteUserGroup(), + GetCmdAddUserToUserGroup(), + GetCmdRemoveUserFromUserGroup(), + ) + + return groupsTxCmd +} + // GetCmdCreateUserGroup returns the command to create a user group func GetCmdCreateUserGroup() *cobra.Command { cmd := &cobra.Command{ - Use: "create-user-group [subspace-id] [group-name] [[permissions]]", + Use: "create [subspace-id] [group-name] [[permissions]]", Args: cobra.MinimumNArgs(2), Short: "Create a new user group within a subspace", - Long: `Create a new user group within the subspace having the provided id. -The permissions of this group can be set using the third (optional) parameter. + Long: fmt.Sprintf(`Create a new user group within the subspace having the provided id. + +An optional description of this group can be provided with the %[1]s flag. + +The permissions of this group can be set using the %[2]s flag. If no permissions are set, the default PermissionNothing will be used instead. -Multiple permissions must be specified separating them with a comma (,).`, +Multiple permissions must be specified separating them with a comma (,).`, FlagDescription, FlagPermissions), Example: fmt.Sprintf(` -%s tx subspaces create-user-group 1 "Admins" "Write,ModerateContent,SetPermissions" \ +%s tx subspaces groups create-user-group 1 "Admins" \ + --description "Group of the subspace admins" \ + --permissions "Write,ModerateContent,SetUserPermissions" \ --from alice `, version.AppName), RunE: func(cmd *cobra.Command, args []string) error { @@ -224,18 +253,135 @@ Multiple permissions must be specified separating them with a comma (,).`, name := args[1] + description, err := cmd.Flags().GetString(FlagDescription) + if err != nil { + return err + } + + permissions, err := cmd.Flags().GetStringSlice(FlagPermissions) + if err != nil { + return err + } + permission := types.PermissionNothing - if len(args) > 2 { - for _, permArg := range strings.Split(args[2], ",") { - perm, err := types.ParsePermission(permArg) - if err != nil { - return err - } - permission = types.CombinePermissions(permission, perm) + for _, permArg := range permissions { + perm, err := types.ParsePermission(permArg) + if err != nil { + return err } + permission = types.CombinePermissions(permission, perm) } - msg := types.NewMsgCreateUserGroup(subspaceID, name, permission, clientCtx.FromAddress.String()) + msg := types.NewMsgCreateUserGroup(subspaceID, name, description, permission, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().String(FlagDescription, "", "Description of the group") + cmd.Flags().StringSlice(FlagPermissions, []string{types.SerializePermission(types.PermissionNothing)}, "Permissions of the group") + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdEditUserGroup returns the command to edit a user group +func GetCmdEditUserGroup() *cobra.Command { + cmd := &cobra.Command{ + Use: "edit [subspace-id] [group-id]", + Args: cobra.ExactArgs(1), + Short: "Edit the group with the given id", + Example: fmt.Sprintf(` +%s tx subspaces groups edit 1 1 \ + --name "Super admins" + --description "This is the group of super users" \ + --from alice +`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + subspaceID, err := types.ParseSubspaceID(args[0]) + if err != nil { + return err + } + + groupID, err := types.ParseGroupID(args[1]) + if err != nil { + return err + } + + name, err := cmd.Flags().GetString(FlagName) + if err != nil { + return err + } + + description, err := cmd.Flags().GetString(FlagDescription) + if err != nil { + return err + } + + msg := types.NewMsgEditUserGroup(subspaceID, groupID, name, description, clientCtx.FromAddress.String()) + if err = msg.ValidateBasic(); err != nil { + return fmt.Errorf("message validation failed: %w", err) + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().String(FlagName, types.DoNotModify, "New human readable name of the group") + cmd.Flags().String(FlagDescription, types.DoNotModify, "Description of the group") + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} + +// GetCmdSetUserGroupPermissions returns the command to set the permissions for a user group +func GetCmdSetUserGroupPermissions() *cobra.Command { + cmd := &cobra.Command{ + Use: "set-permissions [subspace-id] [group-id] [permissions]", + Args: cobra.MinimumNArgs(3), + Short: "Set the permissions for a specific group", + Long: `Set the permissions for a specific user group a given subspace. +It is mandatory to specify at least one permission to be set. +When specifying multiple permissions, they must be separated by a comma (,).`, + Example: fmt.Sprintf(` +%s tx subspaces groups set-permissions 1 1 "Write,ModerateContent,SetUserPermissions" \ + --from alice +`, version.AppName), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + subspaceID, err := types.ParseSubspaceID(args[0]) + if err != nil { + return err + } + + groupID, err := types.ParseGroupID(args[1]) + if err != nil { + return err + } + + permission := types.PermissionNothing + for _, arg := range strings.Split(args[2], ",") { + perm, err := types.ParsePermission(arg) + if err != nil { + return err + } + permission = types.CombinePermissions(permission, perm) + } + + msg := types.NewMsgSetUserGroupPermissions(subspaceID, groupID, permission, clientCtx.FromAddress.String()) if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } @@ -252,11 +398,11 @@ Multiple permissions must be specified separating them with a comma (,).`, // GetCmdDeleteUserGroup returns the command to delete a user group func GetCmdDeleteUserGroup() *cobra.Command { cmd := &cobra.Command{ - Use: "delete-user-group [subspace-id] [group-name]", + Use: "delete [subspace-id] [group-name]", Args: cobra.ExactArgs(2), Short: "Delete a user group from a subspace", Example: fmt.Sprintf(` -%s tx subspaces delete-user-group 1 "Admins" --from alice +%s tx subspaces groups delete-user-group 1 "Admins" --from alice `, version.AppName), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientTxContext(cmd) @@ -269,9 +415,12 @@ func GetCmdDeleteUserGroup() *cobra.Command { return err } - name := args[1] + groupID, err := types.ParseGroupID(args[1]) + if err != nil { + return err + } - msg := types.NewMsgDeleteUserGroup(subspaceID, name, clientCtx.FromAddress.String()) + msg := types.NewMsgDeleteUserGroup(subspaceID, groupID, clientCtx.FromAddress.String()) if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } @@ -288,11 +437,11 @@ func GetCmdDeleteUserGroup() *cobra.Command { // GetCmdAddUserToUserGroup returns the command to add a user to a user group func GetCmdAddUserToUserGroup() *cobra.Command { cmd := &cobra.Command{ - Use: "add-user-to-group [subspace-id] [group-name] [user]", + Use: "add-user [subspace-id] [group-name] [user]", Args: cobra.ExactArgs(3), Short: "Add a user to a user group", Example: fmt.Sprintf(` -%s tx subspaces add-user-to-user-group 1 "Admins" desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ +%s tx subspaces groups add-user-to-user-group 1 "Admins" desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ --from alice `, version.AppName), RunE: func(cmd *cobra.Command, args []string) error { @@ -306,10 +455,14 @@ func GetCmdAddUserToUserGroup() *cobra.Command { return err } - name := args[1] + groupID, err := types.ParseGroupID(args[1]) + if err != nil { + return err + } + user := args[2] - msg := types.NewMsgAddUserToUserGroup(subspaceID, name, user, clientCtx.FromAddress.String()) + msg := types.NewMsgAddUserToUserGroup(subspaceID, groupID, user, clientCtx.FromAddress.String()) if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } @@ -326,11 +479,11 @@ func GetCmdAddUserToUserGroup() *cobra.Command { // GetCmdRemoveUserFromUserGroup returns the command to remove a user from a user group func GetCmdRemoveUserFromUserGroup() *cobra.Command { cmd := &cobra.Command{ - Use: "remove-user-from-group [subspace-id] [group-name] [user]", + Use: "remove-user [subspace-id] [group-name] [user]", Args: cobra.ExactArgs(3), Short: "Remove a user from a user group", Example: fmt.Sprintf(` -%s tx subspaces remove-user-from-user-group 1 "Admins" desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ +%s tx subspaces groups remove-user-from-user-group 1 "Admins" desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ --from alice `, version.AppName), RunE: func(cmd *cobra.Command, args []string) error { @@ -344,10 +497,14 @@ func GetCmdRemoveUserFromUserGroup() *cobra.Command { return err } - name := args[1] + groupID, err := types.ParseGroupID(args[1]) + if err != nil { + return err + } + user := args[2] - msg := types.NewMsgRemoveUserFromUserGroup(subspaceID, name, user, clientCtx.FromAddress.String()) + msg := types.NewMsgRemoveUserFromUserGroup(subspaceID, groupID, user, clientCtx.FromAddress.String()) if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } @@ -361,20 +518,19 @@ func GetCmdRemoveUserFromUserGroup() *cobra.Command { return cmd } -// GetCmdSetPermissions returns the command to set the permissions for a target -func GetCmdSetPermissions() *cobra.Command { +// -------------------------------------------------------------------------------------------------------------------- + +// GetCmdSetUserPermissions returns the command to set the permissions for a user +func GetCmdSetUserPermissions() *cobra.Command { cmd := &cobra.Command{ - Use: "set-permissions [subspace-id] [target] [permissions]", + Use: "set-user-permissions [subspace-id] [user] [permissions]", Args: cobra.MinimumNArgs(3), - Short: "Set the permissions for a specific target", - Long: `Set the permissions for a specific target inside a given subspace. -The target can be either a group (in this case the name should be used), -or a user (in this case the address should be used). - -In both cases, it is mandatory to specify at least one permission to be set. + Short: "Set the permissions for a specific user", + Long: `Set the permissions for a specific user inside a given subspace. +It is mandatory to specify at least one permission to be set. When specifying multiple permissions, they must be separated by a comma (,).`, Example: fmt.Sprintf(` -%s tx subspaces set-permissions 1 "Admins" "Write,ModerateContent,SetPermissions" \ +%s tx subspaces sset-user-permissions 1 desmos1463vltcqk6ql6zpk0g6s595jjcrzk4804hyqw7 "Write,ModerateContent,SetUserPermissions" \ --from alice `, version.AppName), RunE: func(cmd *cobra.Command, args []string) error { @@ -388,7 +544,7 @@ When specifying multiple permissions, they must be separated by a comma (,).`, return err } - target := args[1] + user := args[1] permission := types.PermissionNothing for _, arg := range strings.Split(args[2], ",") { @@ -399,7 +555,7 @@ When specifying multiple permissions, they must be separated by a comma (,).`, permission = types.CombinePermissions(permission, perm) } - msg := types.NewMsgSetPermissions(subspaceID, target, permission, clientCtx.FromAddress.String()) + msg := types.NewMsgSetUserPermissions(subspaceID, user, permission, clientCtx.FromAddress.String()) if err = msg.ValidateBasic(); err != nil { return fmt.Errorf("message validation failed: %w", err) } diff --git a/x/subspaces/handler.go b/x/subspaces/handler.go index a761ed3939..bae2683cdc 100644 --- a/x/subspaces/handler.go +++ b/x/subspaces/handler.go @@ -26,6 +26,12 @@ func NewHandler(k keeper.Keeper) sdk.Handler { case *types.MsgCreateUserGroup: res, err := msgServer.CreateUserGroup(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgEditUserGroup: + res, err := msgServer.EditUserGroup(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgSetUserGroupPermissions: + res, err := msgServer.SetUserGroupPermissions(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) case *types.MsgDeleteUserGroup: res, err := msgServer.DeleteUserGroup(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) @@ -35,8 +41,8 @@ func NewHandler(k keeper.Keeper) sdk.Handler { case *types.MsgRemoveUserFromUserGroup: res, err := msgServer.RemoveUserFromUserGroup(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) - case *types.MsgSetPermissions: - res, err := msgServer.SetPermissions(sdk.WrapSDKContext(ctx), msg) + case *types.MsgSetUserPermissions: + res, err := msgServer.SetUserPermissions(sdk.WrapSDKContext(ctx), msg) return sdk.WrapServiceResult(ctx, res, err) default: diff --git a/x/subspaces/keeper/alias_functions.go b/x/subspaces/keeper/alias_functions.go index 48477d2c47..b66d119103 100644 --- a/x/subspaces/keeper/alias_functions.go +++ b/x/subspaces/keeper/alias_functions.go @@ -39,9 +39,27 @@ func (k Keeper) GetAllSubspaces(ctx sdk.Context) []types.Subspace { // -------------------------------------------------------------------------------------------------------------------- +// IterateUserGroups iterates over all the users groups stored +func (k Keeper) IterateUserGroups(ctx sdk.Context, fn func(index int64, group types.UserGroup) (stop bool)) { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.GroupsPrefix) + defer iterator.Close() + + i := int64(0) + for ; iterator.Valid(); iterator.Next() { + var group types.UserGroup + k.cdc.MustUnmarshal(iterator.Value(), &group) + stop := fn(i, group) + if stop { + break + } + i++ + } +} + // IterateSubspaceGroups allows iterating over all the groups that are part of the subspace having the given id func (k Keeper) IterateSubspaceGroups( - ctx sdk.Context, subspaceID uint64, fn func(index int64, groupName string) (stop bool), + ctx sdk.Context, subspaceID uint64, fn func(index int64, group types.UserGroup) (stop bool), ) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, types.GroupsStoreKey(subspaceID)) @@ -49,8 +67,9 @@ func (k Keeper) IterateSubspaceGroups( i := int64(0) for ; iterator.Valid(); iterator.Next() { - nameBz := bytes.TrimPrefix(iterator.Key(), types.GroupsStoreKey(subspaceID)) - stop := fn(i, types.GetGroupNameFromBytes(nameBz)) + var group types.UserGroup + k.cdc.MustUnmarshal(iterator.Value(), &group) + stop := fn(i, group) if stop { break } @@ -59,10 +78,10 @@ func (k Keeper) IterateSubspaceGroups( } // GetSubspaceGroups returns the list of all groups present inside a given subspace -func (k Keeper) GetSubspaceGroups(ctx sdk.Context, subspaceID uint64) []string { - var groups []string - k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, groupName string) (stop bool) { - groups = append(groups, groupName) +func (k Keeper) GetSubspaceGroups(ctx sdk.Context, subspaceID uint64) []types.UserGroup { + var groups []types.UserGroup + k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, group types.UserGroup) (stop bool) { + groups = append(groups, group) return false }) return groups @@ -70,17 +89,18 @@ func (k Keeper) GetSubspaceGroups(ctx sdk.Context, subspaceID uint64) []string { // IterateGroupMembers iterates over all the members of the group with the given name present inside the given subspace func (k Keeper) IterateGroupMembers( - ctx sdk.Context, subspaceID uint64, groupName string, fn func(index int64, member sdk.AccAddress) (stop bool), + ctx sdk.Context, subspaceID uint64, groupID uint32, fn func(index int64, member sdk.AccAddress) (stop bool), ) { store := ctx.KVStore(k.storeKey) - prefix := types.GroupMembersStoreKey(subspaceID, groupName) + prefix := types.GroupMembersStoreKey(subspaceID, groupID) iterator := sdk.KVStorePrefixIterator(store, prefix) defer iterator.Close() i := int64(0) for ; iterator.Valid(); iterator.Next() { - member := types.GetGroupMemberFromBytes(bytes.TrimPrefix(iterator.Key(), prefix)) + member := types.GetAddressFromBytes(bytes.TrimPrefix(iterator.Key(), prefix)) + stop := fn(i, member) if stop { break @@ -90,9 +110,9 @@ func (k Keeper) IterateGroupMembers( } // GetGroupMembers iterates returns all the members of a group inside a specific subspace -func (k Keeper) GetGroupMembers(ctx sdk.Context, subspaceID uint64, groupName string) []sdk.AccAddress { +func (k Keeper) GetGroupMembers(ctx sdk.Context, subspaceID uint64, groupID uint32) []sdk.AccAddress { var members []sdk.AccAddress - k.IterateGroupMembers(ctx, subspaceID, groupName, func(index int64, member sdk.AccAddress) (stop bool) { + k.IterateGroupMembers(ctx, subspaceID, groupID, func(index int64, member sdk.AccAddress) (stop bool) { members = append(members, member) return false }) @@ -101,9 +121,9 @@ func (k Keeper) GetGroupMembers(ctx sdk.Context, subspaceID uint64, groupName st // -------------------------------------------------------------------------------------------------------------------- -// IteratePermissions iterates over all the permissions set for the subspace with the given id -func (k Keeper) IteratePermissions( - ctx sdk.Context, subspaceID uint64, fn func(index int64, target string, permission types.Permission) (stop bool), +// IterateSubspacePermissions iterates over all the permissions set for the subspace with the given id +func (k Keeper) IterateSubspacePermissions( + ctx sdk.Context, subspaceID uint64, fn func(index int64, user sdk.AccAddress, permission types.Permission) (stop bool), ) { store := ctx.KVStore(k.storeKey) @@ -113,10 +133,10 @@ func (k Keeper) IteratePermissions( i := int64(0) for ; iterator.Valid(); iterator.Next() { - target := types.GetTargetFromBytes(bytes.TrimPrefix(iterator.Key(), prefix)) + user := types.GetAddressFromBytes(bytes.TrimPrefix(iterator.Key(), prefix)) permission := types.UnmarshalPermission(iterator.Value()) - stop := fn(i, target, permission) + stop := fn(i, user, permission) if stop { break } diff --git a/x/subspaces/keeper/genesis.go b/x/subspaces/keeper/genesis.go index 44a5b7ff64..01e57e08c7 100644 --- a/x/subspaces/keeper/genesis.go +++ b/x/subspaces/keeper/genesis.go @@ -1,6 +1,8 @@ package keeper import ( + "fmt" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" sdk "github.com/cosmos/cosmos-sdk/types" @@ -15,23 +17,41 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { return types.NewGenesisState( subspaceID, - k.GetAllSubspaces(ctx), - k.GetAllUserGroups(ctx), + k.GetGenesisSubspaces(ctx, k.GetAllSubspaces(ctx)), k.GetAllPermissions(ctx), + k.GetAllUserGroups(ctx), + k.GetUserAllGroupsMembers(ctx), ) } +// GetGenesisSubspaces maps the given subspaces to the corresponding GenesisSubspace instance +func (k Keeper) GetGenesisSubspaces(ctx sdk.Context, subspaces []types.Subspace) []types.GenesisSubspace { + if subspaces == nil { + return nil + } + + genesisSubspaces := make([]types.GenesisSubspace, len(subspaces)) + for i, subspace := range subspaces { + groupID, err := k.GetGroupID(ctx, subspace.ID) + if err != nil { + panic(err) + } + + genesisSubspaces[i] = types.NewGenesisSubspace(subspace, groupID) + } + return genesisSubspaces +} + // GetAllPermissions returns all the stored permissions for all subspaces func (k Keeper) GetAllPermissions(ctx sdk.Context) []types.ACLEntry { var entries []types.ACLEntry k.IterateSubspaces(ctx, func(index int64, subspace types.Subspace) (stop bool) { - k.IteratePermissions(ctx, subspace.ID, func(index int64, target string, permission types.Permission) (stop bool) { - entries = append(entries, types.NewACLEntry(subspace.ID, target, permission)) + k.IterateSubspacePermissions(ctx, subspace.ID, func(index int64, user sdk.AccAddress, permission types.Permission) (stop bool) { + entries = append(entries, types.NewACLEntry(subspace.ID, user.String(), permission)) return false }) return false }) - return entries } @@ -39,48 +59,62 @@ func (k Keeper) GetAllPermissions(ctx sdk.Context) []types.ACLEntry { func (k Keeper) GetAllUserGroups(ctx sdk.Context) []types.UserGroup { var groups []types.UserGroup k.IterateSubspaces(ctx, func(index int64, subspace types.Subspace) (stop bool) { - k.IterateSubspaceGroups(ctx, subspace.ID, func(index int64, groupName string) (stop bool) { + k.IterateSubspaceGroups(ctx, subspace.ID, func(index int64, group types.UserGroup) (stop bool) { + groups = append(groups, group) + return false + }) + return false + }) + return groups +} +// GetUserAllGroupsMembers returns all the UserGroupMembersEntry +func (k Keeper) GetUserAllGroupsMembers(ctx sdk.Context) []types.UserGroupMembersEntry { + var entries []types.UserGroupMembersEntry + k.IterateSubspaces(ctx, func(index int64, subspace types.Subspace) (stop bool) { + k.IterateSubspaceGroups(ctx, subspace.ID, func(index int64, group types.UserGroup) (stop bool) { var members []string - k.IterateGroupMembers(ctx, subspace.ID, groupName, func(index int64, member sdk.AccAddress) (stop bool) { + k.IterateGroupMembers(ctx, subspace.ID, group.ID, func(index int64, member sdk.AccAddress) (stop bool) { members = append(members, member.String()) return false }) - - groups = append(groups, types.NewUserGroup(subspace.ID, groupName, members)) + entries = append(entries, types.NewUserGroupMembersEntry(subspace.ID, group.ID, members)) return false }) - return false }) - return groups + return entries } // -------------------------------------------------------------------------------------------------------------------- // InitGenesis initializes the chain state based on the given GenesisState func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { - // Set the initial subspace id - k.SetSubspaceID(ctx, data.InitialSubspaceID) - // Initialize the subspaces - for _, subspace := range data.Subspaces { - k.SaveSubspace(ctx, subspace) + for _, subspaceData := range data.Subspaces { + k.SaveSubspace(ctx, subspaceData.Subspace) + k.SetGroupID(ctx, subspaceData.Subspace.ID, subspaceData.InitialGroupID) } + // Initialize the subspace id setting it to be the max id found + 1 + k.SetSubspaceID(ctx, data.InitialSubspaceID) + // Initialize the groups with default permission PermissionNothing // The real permission will be set later when initializing the various permissions for _, group := range data.UserGroups { - k.SaveUserGroup(ctx, group.SubspaceID, group.Name, types.PermissionNothing) + k.SaveUserGroup(ctx, group) + } + // Initialize the group members + for _, entry := range data.UserGroupsMembers { // Initialize the members - for _, member := range group.Members { + for _, member := range entry.Members { userAddr, err := sdk.AccAddressFromBech32(member) if err != nil { panic(err) } - err = k.AddUserToGroup(ctx, group.SubspaceID, group.Name, userAddr) + err = k.AddUserToGroup(ctx, entry.SubspaceID, entry.GroupID, userAddr) if err != nil { panic(err) } @@ -89,6 +123,10 @@ func (k Keeper) InitGenesis(ctx sdk.Context, data types.GenesisState) { // Initialize the permissions for _, entry := range data.ACL { - k.SetPermissions(ctx, entry.SubspaceID, entry.Target, entry.Permissions) + userAddr, err := sdk.AccAddressFromBech32(entry.User) + if err != nil { + panic(fmt.Errorf("invalid user address: %s", entry.User)) + } + k.SetUserPermissions(ctx, entry.SubspaceID, userAddr, entry.Permissions) } } diff --git a/x/subspaces/keeper/genesis_test.go b/x/subspaces/keeper/genesis_test.go index 5cb4d685dc..a732f8fe8d 100644 --- a/x/subspaces/keeper/genesis_test.go +++ b/x/subspaces/keeper/genesis_test.go @@ -17,14 +17,14 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { { name: "subspace id is exported properly", store: func(ctx sdk.Context) { - suite.k.SetSubspaceID(ctx, 2) + suite.k.SetSubspaceID(ctx, 1) }, - expGenesis: types.NewGenesisState(2, nil, nil, nil), + expGenesis: types.NewGenesisState(1, nil, nil, nil, nil), }, { name: "subspaces are exported correctly", store: func(ctx sdk.Context) { - suite.k.SetSubspaceID(ctx, 1) + suite.k.SetSubspaceID(ctx, 3) suite.k.SaveSubspace(ctx, types.NewSubspace( 1, "Test subspace", @@ -34,7 +34,6 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveSubspace(ctx, types.NewSubspace( 2, "Another test subspace", @@ -46,46 +45,42 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { )) }, expGenesis: types.NewGenesisState( - 1, - []types.Subspace{ - types.NewSubspace( + 3, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), ), - types.NewSubspace( - 2, - "Another test subspace", - "This is another test subspace", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + types.NewGenesisSubspace( + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + 1, ), }, nil, nil, + nil, ), }, { name: "permissions are exported correctly", store: func(ctx sdk.Context) { - suite.k.SetSubspaceID(ctx, 1) - suite.k.SaveSubspace(ctx, types.NewSubspace( - 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), - )) - suite.k.SetPermissions(ctx, 1, "group", types.PermissionWrite) - + suite.k.SetSubspaceID(ctx, 3) suite.k.SaveSubspace(ctx, types.NewSubspace( 2, "Another test subspace", @@ -95,41 +90,38 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), )) - suite.k.SetPermissions(ctx, 2, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", types.PermissionSetPermissions) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 2, sdkAddr, types.PermissionSetPermissions) }, expGenesis: types.NewGenesisState( - 1, - []types.Subspace{ - types.NewSubspace( + 3, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), - ), - types.NewSubspace( - 2, - "Another test subspace", - "This is another test subspace", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), ), }, - nil, []types.ACLEntry{ - types.NewACLEntry(1, "group", types.PermissionWrite), types.NewACLEntry(2, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", types.PermissionSetPermissions), }, + nil, + nil, ), }, { name: "user groups are exported properly", store: func(ctx sdk.Context) { - suite.k.SetSubspaceID(ctx, 1) + suite.k.SetSubspaceID(ctx, 3) suite.k.SaveSubspace(ctx, types.NewSubspace( 1, "Test subspace", @@ -139,11 +131,18 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SetGroupID(ctx, 1, 2) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) suite.k.SaveSubspace(ctx, types.NewSubspace( 2, @@ -154,52 +153,77 @@ func (suite *KeeperTestsuite) TestKeeper_ExportGenesis() { "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), )) - - suite.k.SaveUserGroup(ctx, 2, "another-group", types.PermissionManageGroups) + suite.k.SetGroupID(ctx, 2, 2) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 2, + 1, + "Another test group", + "This is another test group", + types.PermissionWrite, + )) userAddr, err = sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 2, "another-group", userAddr) + err = suite.k.AddUserToGroup(ctx, 2, 1, userAddr) userAddr, err = sdk.AccAddressFromBech32("cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 2, "another-group", userAddr) + err = suite.k.AddUserToGroup(ctx, 2, 1, userAddr) }, expGenesis: types.NewGenesisState( - 1, - []types.Subspace{ - types.NewSubspace( - 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + 3, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 2, ), - types.NewSubspace( + types.NewGenesisSubspace( + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), 2, - "Another test subspace", - "This is another test subspace", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), ), }, + nil, []types.UserGroup{ - types.NewUserGroup(1, "group", []string{ + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + types.NewUserGroup( + 2, + 1, + "Another test group", + "This is another test group", + types.PermissionWrite, + ), + }, + []types.UserGroupMembersEntry{ + types.NewUserGroupMembersEntry(1, 1, []string{ "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", }), - types.NewUserGroup(2, "another-group", []string{ + types.NewUserGroupMembersEntry(2, 1, []string{ "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", }), }, - []types.ACLEntry{ - types.NewACLEntry(1, "group", types.PermissionWrite), - types.NewACLEntry(2, "another-group", types.PermissionManageGroups), - }, ), }, } @@ -227,36 +251,64 @@ func (suite *KeeperTestsuite) TestKeeper_InitGenesis() { { name: "all data is imported properly", genesis: types.GenesisState{ - InitialSubspaceID: 2, - Subspaces: []types.Subspace{ - types.NewSubspace( - 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), - ), - types.NewSubspace( + InitialSubspaceID: 3, + Subspaces: []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), 2, - "Another test subspace", - "This is another test subspace", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + types.NewGenesisSubspace( + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), + 14, ), }, ACL: []types.ACLEntry{ - types.NewACLEntry(1, "group", types.PermissionWrite), - types.NewACLEntry(2, "another-group", types.PermissionManageGroups), + types.NewACLEntry(2, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", types.PermissionSetPermissions), }, UserGroups: []types.UserGroup{ - types.NewUserGroup(1, "group", []string{ + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + types.NewUserGroup( + 2, + 1, + "Another test group", + "This is another test group", + types.PermissionWrite, + ), + types.NewUserGroup( + 2, + 13, + "High id test group", + "This is another test group", + types.PermissionWrite, + ), + }, + UserGroupsMembers: []types.UserGroupMembersEntry{ + types.NewUserGroupMembersEntry(1, 1, []string{ "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", }), - types.NewUserGroup(2, "another-group", []string{ + types.NewUserGroupMembersEntry(2, 1, []string{ "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", }), @@ -265,44 +317,72 @@ func (suite *KeeperTestsuite) TestKeeper_InitGenesis() { check: func(ctx sdk.Context) { subspaceID, err := suite.k.GetSubspaceID(ctx) suite.Require().NoError(err) - suite.Require().Equal(uint64(2), subspaceID) + suite.Require().Equal(uint64(3), subspaceID) subspaces := suite.k.GetAllSubspaces(ctx) suite.Require().Len(subspaces, 2) - var firstSubspaceGroups = 0 - suite.k.IterateSubspaceGroups(ctx, 1, func(index int64, groupName string) (stop bool) { - firstSubspaceGroups += 1 - return false - }) - suite.Require().Equal(firstSubspaceGroups, 1) + // Check the fist subspace data + firstSubspaceGroupID, err := suite.k.GetGroupID(ctx, 1) + suite.Require().NoError(err) + suite.Require().Equal(uint32(2), firstSubspaceGroupID) - groupPermissions := suite.k.GetPermissions(ctx, 1, "group") - suite.Require().Equal(types.PermissionWrite, groupPermissions) + expectedFirstSubspaceGroups := []types.UserGroup{ + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + } + storedFirstSubspacesGroups := suite.k.GetSubspaceGroups(ctx, 1) + suite.Require().Equal(expectedFirstSubspaceGroups, storedFirstSubspacesGroups) var groupMembers = 0 - suite.k.IterateGroupMembers(ctx, 1, "group", func(index int64, member sdk.AccAddress) (stop bool) { + suite.k.IterateGroupMembers(ctx, 1, 1, func(index int64, member sdk.AccAddress) (stop bool) { groupMembers += 1 return false }) suite.Require().Equal(1, groupMembers) - var secondSubspaceGroups = 0 - suite.k.IterateSubspaceGroups(ctx, 2, func(index int64, groupName string) (stop bool) { - secondSubspaceGroups += 1 - return false - }) - suite.Require().Equal(secondSubspaceGroups, 1) + // Check the second subspace data + secondSubspaceGroupID, err := suite.k.GetGroupID(ctx, 2) + suite.Require().NoError(err) + suite.Require().Equal(uint32(14), secondSubspaceGroupID) + + expectedSecondSubspaceGroups := []types.UserGroup{ + types.NewUserGroup( + 2, + 1, + "Another test group", + "This is another test group", + types.PermissionWrite, + ), + types.NewUserGroup( + 2, + 13, + "High id test group", + "This is another test group", + types.PermissionWrite, + ), + } + storedSecondSubspaceGroups := suite.k.GetSubspaceGroups(ctx, 2) + suite.Require().Equal(expectedSecondSubspaceGroups, storedSecondSubspaceGroups) var anotherGroupMembers = 0 - suite.k.IterateGroupMembers(ctx, 2, "another-group", func(index int64, member sdk.AccAddress) (stop bool) { + suite.k.IterateGroupMembers(ctx, 2, 1, func(index int64, member sdk.AccAddress) (stop bool) { anotherGroupMembers += 1 return false }) suite.Require().Equal(2, anotherGroupMembers) - anotherGroupPermissions := suite.k.GetPermissions(ctx, 2, "another-group") - suite.Require().Equal(types.PermissionManageGroups, anotherGroupPermissions) + // Check user permissions + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + + storedUserPermissions := suite.k.GetUserPermissions(ctx, 2, userAddr) + suite.Require().Equal(types.PermissionSetPermissions, storedUserPermissions) }, }, } diff --git a/x/subspaces/keeper/groups.go b/x/subspaces/keeper/groups.go index ca014d2718..b70287f658 100644 --- a/x/subspaces/keeper/groups.go +++ b/x/subspaces/keeper/groups.go @@ -7,78 +7,107 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) -// HasUserGroup returns whether the given subspace has a group with the specified name or not -func (k Keeper) HasUserGroup(ctx sdk.Context, subspaceID uint64, groupName string) bool { +// SetGroupID sets the new group id for the specific subspace to the store +func (k Keeper) SetGroupID(ctx sdk.Context, subspaceID uint64, groupID uint32) { store := ctx.KVStore(k.storeKey) - return store.Has(types.GroupStoreKey(subspaceID, groupName)) + store.Set(types.GroupIDStoreKey(subspaceID), types.GetGroupIDBytes(groupID)) } -// SaveUserGroup saves within the subspace having the given id the group with the specified name and permissions -func (k Keeper) SaveUserGroup(ctx sdk.Context, subspaceID uint64, groupName string, permissions types.Permission) { +// GetGroupID gets the highest group id for the subspace with the given id +func (k Keeper) GetGroupID(ctx sdk.Context, subspaceID uint64) (groupID uint32, err error) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.GroupIDStoreKey(subspaceID)) + if bz == nil { + return 0, sdkerrors.Wrap(types.ErrInvalidGenesis, "initial group ID hasn't been set") + } + + groupID = types.GetGroupIDFromBytes(bz) + return groupID, nil +} + +// -------------------------------------------------------------------------------------------------------------------- + +// SaveUserGroup saves within the subspace having the given id the provided group +func (k Keeper) SaveUserGroup(ctx sdk.Context, group types.UserGroup) { store := ctx.KVStore(k.storeKey) // Save the group - store.Set(types.GroupStoreKey(subspaceID, groupName), []byte{0x01}) + store.Set(types.GroupStoreKey(group.SubspaceID, group.ID), k.cdc.MustMarshal(&group)) - // Save the permissions - k.SetPermissions(ctx, subspaceID, groupName, permissions) + k.Logger(ctx).Info("group saved", "subspace_id", group.SubspaceID, "group_id", group.ID) + k.AfterSubspaceGroupSaved(ctx, group.SubspaceID, group.ID) +} - k.Logger(ctx).Info("group saved", "subspace_id", subspaceID, "group_name", groupName) - k.AfterSubspaceGroupSaved(ctx, subspaceID, groupName) +// HasUserGroup returns whether the given subspace has a group with the specified id or not +func (k Keeper) HasUserGroup(ctx sdk.Context, subspaceID uint64, groupID uint32) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.GroupStoreKey(subspaceID, groupID)) } -// DeleteUserGroup deletes the group with the given name from the subspace with the provided id -func (k Keeper) DeleteUserGroup(ctx sdk.Context, subspaceID uint64, groupName string) { +// GetUserGroup returns the group associated with the given id inside the subspace with the provided id. +// If there is no group associated with the given id the function will return an empty group and false. +func (k Keeper) GetUserGroup(ctx sdk.Context, subspaceID uint64, groupID uint32) (group types.UserGroup, found bool) { + store := ctx.KVStore(k.storeKey) + key := types.GroupStoreKey(subspaceID, groupID) + if !store.Has(key) { + return group, false + } + + k.cdc.MustUnmarshal(store.Get(key), &group) + return group, true +} + +// DeleteUserGroup deletes the group with the given id from the subspace with the provided id +func (k Keeper) DeleteUserGroup(ctx sdk.Context, subspaceID uint64, groupID uint32) { store := ctx.KVStore(k.storeKey) // Remove all the members from this group var members []sdk.AccAddress - k.IterateGroupMembers(ctx, subspaceID, groupName, func(index int64, member sdk.AccAddress) (stop bool) { + k.IterateGroupMembers(ctx, subspaceID, groupID, func(index int64, member sdk.AccAddress) (stop bool) { members = append(members, member) return false }) for _, member := range members { - k.RemoveUserFromGroup(ctx, subspaceID, groupName, member) + k.RemoveUserFromGroup(ctx, subspaceID, groupID, member) } - // Remove the group permissions - k.RemovePermissions(ctx, subspaceID, groupName) - // Delete the group - store.Delete(types.GroupStoreKey(subspaceID, groupName)) + store.Delete(types.GroupStoreKey(subspaceID, groupID)) - k.Logger(ctx).Info("group deleted", "subspace_id", subspaceID, "group_name", groupName) - k.AfterSubspaceGroupDeleted(ctx, subspaceID, groupName) + k.Logger(ctx).Info("group deleted", "subspace_id", subspaceID, "group_id", groupID) + k.AfterSubspaceGroupDeleted(ctx, subspaceID, groupID) } -// IsMemberOfGroup returns whether the given user is part of the group with -// the specified name inside the provided subspace -func (k Keeper) IsMemberOfGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) bool { - store := ctx.KVStore(k.storeKey) - return store.Has(types.GroupMemberStoreKey(subspaceID, groupName, user)) -} +// -------------------------------------------------------------------------------------------------------------------- -// AddUserToGroup adds the given user to the group having the provided name inside the specified subspace. +// AddUserToGroup adds the given user to the group having the provided id inside the specified subspace. // If the group does not exist inside the subspace, it returns an error. -func (k Keeper) AddUserToGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) error { - if !k.HasUserGroup(ctx, subspaceID, groupName) { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidVersion, "group with name %s does not exist", groupName) +func (k Keeper) AddUserToGroup(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) error { + if !k.HasUserGroup(ctx, subspaceID, groupID) { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group with id %d does not exist", groupID) } store := ctx.KVStore(k.storeKey) - store.Set(types.GroupMemberStoreKey(subspaceID, groupName, user), []byte{0x01}) + store.Set(types.GroupMemberStoreKey(subspaceID, groupID, user), []byte{0x01}) - k.AfterSubspaceGroupMemberAdded(ctx, subspaceID, groupName, user) + k.AfterSubspaceGroupMemberAdded(ctx, subspaceID, groupID, user) return nil } -// RemoveUserFromGroup removes the specified user from the subspace group having the given name. +// IsMemberOfGroup returns whether the given user is part of the group with +// the specified id inside the provided subspace +func (k Keeper) IsMemberOfGroup(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.GroupMemberStoreKey(subspaceID, groupID, user)) +} + +// RemoveUserFromGroup removes the specified user from the subspace group having the given id. // If the group does not exist inside the subspace, it returns an error. -func (k Keeper) RemoveUserFromGroup(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { +func (k Keeper) RemoveUserFromGroup(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) { store := ctx.KVStore(k.storeKey) - store.Delete(types.GroupMemberStoreKey(subspaceID, groupName, user)) + store.Delete(types.GroupMemberStoreKey(subspaceID, groupID, user)) - k.AfterSubspaceGroupMemberRemoved(ctx, subspaceID, groupName, user) + k.AfterSubspaceGroupMemberRemoved(ctx, subspaceID, groupID, user) } diff --git a/x/subspaces/keeper/groups_test.go b/x/subspaces/keeper/groups_test.go index cf0b6c9ea7..3dfa989e72 100644 --- a/x/subspaces/keeper/groups_test.go +++ b/x/subspaces/keeper/groups_test.go @@ -1,44 +1,75 @@ package keeper_test import ( - "time" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) -func (suite *KeeperTestsuite) TestKeeper_HasUserGroup() { +func (suite *KeeperTestsuite) TestKeeper_SetGroupID() { + testCases := []struct { + name string + subspaceID uint64 + groupID uint32 + check func(ctx sdk.Context) + }{ + { + name: "zero group id", + subspaceID: 1, + groupID: 0, + check: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + groupID := types.GetGroupIDFromBytes(store.Get(types.GroupIDStoreKey(1))) + suite.Require().Equal(uint32(0), groupID) + }, + }, + { + name: "non-zero group id", + subspaceID: 1, + groupID: 5, + check: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + groupID := types.GetGroupIDFromBytes(store.Get(types.GroupIDStoreKey(1))) + suite.Require().Equal(uint32(5), groupID) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + + suite.k.SetGroupID(ctx, tc.subspaceID, tc.groupID) + if tc.check != nil { + tc.check(ctx) + } + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_GetGroupID() { testCases := []struct { name string store func(ctx sdk.Context) subspaceID uint64 - groupName string - expResult bool + shouldErr bool + expID uint32 }{ { - name: "not found group returns false", + name: "group id not set", subspaceID: 1, - groupName: "group", - expResult: false, + shouldErr: true, }, { - name: "found group returns true", + name: "group id set", store: func(ctx sdk.Context) { - suite.k.SaveSubspace(ctx, types.NewSubspace( - 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), - )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + store := ctx.KVStore(suite.storeKey) + store.Set(types.GroupIDStoreKey(1), types.GetGroupIDBytes(1)) }, subspaceID: 1, - groupName: "group", - expResult: true, + shouldErr: false, + expID: 1, }, } @@ -50,48 +81,78 @@ func (suite *KeeperTestsuite) TestKeeper_HasUserGroup() { tc.store(ctx) } - result := suite.k.HasUserGroup(ctx, tc.subspaceID, tc.groupName) - suite.Require().Equal(tc.expResult, result) + id, err := suite.k.GetGroupID(ctx, tc.subspaceID) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expID, id) + } }) } } +// -------------------------------------------------------------------------------------------------------------------- + func (suite *KeeperTestsuite) TestKeeper_SaveUserGroup() { testCases := []struct { name string store func(ctx sdk.Context) - subspaceID uint64 - groupName string + group types.UserGroup permissions types.Permission check func(ctx sdk.Context) }{ { - name: "non existing group is stored properly", - subspaceID: 1, - groupName: "group", + name: "non existing group is stored properly", + group: types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), permissions: types.PermissionWrite, check: func(ctx sdk.Context) { - hasGroup := suite.k.HasUserGroup(ctx, 1, "group") - suite.Require().True(hasGroup) - - permissions := suite.k.GetPermissions(ctx, 1, "group") - suite.Require().Equal(types.PermissionWrite, permissions) + group, found := suite.k.GetUserGroup(ctx, 1, 1) + suite.Require().True(found) + suite.Require().Equal(types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), group) }, }, { - name: "existing group permissions are updated properly", + name: "existing group is updated properly", store: func(ctx sdk.Context) { - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) }, - subspaceID: 1, - groupName: "group", + group: types.NewUserGroup( + 1, + 1, + "Edited test group", + "This is an edited test group", + types.PermissionChangeInfo, + ), permissions: types.PermissionManageGroups, check: func(ctx sdk.Context) { - hasGroup := suite.k.HasUserGroup(ctx, 1, "group") - suite.Require().True(hasGroup) - - permissions := suite.k.GetPermissions(ctx, 1, "group") - suite.Require().Equal(types.PermissionManageGroups, permissions) + group, found := suite.k.GetUserGroup(ctx, 1, 1) + suite.Require().True(found) + suite.Require().Equal(types.NewUserGroup( + 1, + 1, + "Edited test group", + "This is an edited test group", + types.PermissionChangeInfo, + ), group) }, }, } @@ -104,7 +165,7 @@ func (suite *KeeperTestsuite) TestKeeper_SaveUserGroup() { tc.store(ctx) } - suite.k.SaveUserGroup(ctx, tc.subspaceID, tc.groupName, tc.permissions) + suite.k.SaveUserGroup(ctx, tc.group) if tc.check != nil { tc.check(ctx) } @@ -112,62 +173,157 @@ func (suite *KeeperTestsuite) TestKeeper_SaveUserGroup() { } } +func (suite *KeeperTestsuite) TestKeeper_HasUserGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + groupID uint32 + expResult bool + }{ + { + name: "not found group returns false", + subspaceID: 1, + groupID: 1, + expResult: false, + }, + { + name: "found group returns true", + store: func(ctx sdk.Context) { + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + }, + subspaceID: 1, + groupID: 1, + expResult: true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + result := suite.k.HasUserGroup(ctx, tc.subspaceID, tc.groupID) + suite.Require().Equal(tc.expResult, result) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_GetUserGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + groupID uint32 + expFound bool + expGroup types.UserGroup + }{ + { + name: "not found group returns false", + subspaceID: 1, + groupID: 1, + expFound: false, + }, + { + name: "found group returns true", + store: func(ctx sdk.Context) { + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + }, + subspaceID: 1, + groupID: 1, + expFound: true, + expGroup: types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + group, found := suite.k.GetUserGroup(ctx, tc.subspaceID, tc.groupID) + suite.Require().Equal(tc.expFound, found) + if tc.expFound { + suite.Require().Equal(tc.expGroup, group) + } + }) + } +} + func (suite *KeeperTestsuite) TestKeeper_DeleteUserGroup() { testCases := []struct { name string store func(ctx sdk.Context) subspaceID uint64 - groupName string + groupID uint32 check func(ctx sdk.Context) }{ { name: "non existing group is deleted properly", subspaceID: 1, - groupName: "group", + groupID: 1, check: func(ctx sdk.Context) { - hasGroup := suite.k.HasUserGroup(ctx, 1, "group") + hasGroup := suite.k.HasUserGroup(ctx, 1, 1) suite.Require().False(hasGroup) }, }, { - name: "existing group is deleted properly, members are deleted and permissions are cleared", + name: "existing group is deleted properly and members are cleared", store: func(ctx sdk.Context) { - suite.k.SaveSubspace(ctx, types.NewSubspace( + suite.k.SaveUserGroup(ctx, types.NewUserGroup( 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + 1, + "Test group", + "This is a test group", + types.PermissionWrite, )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) suite.Require().NoError(err) userAddr, err = sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) suite.Require().NoError(err) }, subspaceID: 1, - groupName: "group", + groupID: 1, check: func(ctx sdk.Context) { - hasGroup := suite.k.HasUserGroup(ctx, 1, "group") + hasGroup := suite.k.HasUserGroup(ctx, 1, 1) suite.Require().False(hasGroup) var members []sdk.AccAddress - suite.k.IterateGroupMembers(ctx, 1, "group", func(index int64, member sdk.AccAddress) (stop bool) { + suite.k.IterateGroupMembers(ctx, 1, 1, func(index int64, member sdk.AccAddress) (stop bool) { members = append(members, member) return false }) suite.Require().Empty(members) - - store := ctx.KVStore(suite.storeKey) - suite.Require().False(store.Has(types.PermissionStoreKey(1, "group"))) }, }, } @@ -180,7 +336,7 @@ func (suite *KeeperTestsuite) TestKeeper_DeleteUserGroup() { tc.store(ctx) } - suite.k.DeleteUserGroup(ctx, tc.subspaceID, tc.groupName) + suite.k.DeleteUserGroup(ctx, tc.subspaceID, tc.groupID) if tc.check != nil { tc.check(ctx) } @@ -188,45 +344,47 @@ func (suite *KeeperTestsuite) TestKeeper_DeleteUserGroup() { } } -func (suite *KeeperTestsuite) TestKeeper_IsMemberOfGroup() { +// -------------------------------------------------------------------------------------------------------------------- + +func (suite *KeeperTestsuite) TestKeeper_AddUserToGroup() { testCases := []struct { name string store func(ctx sdk.Context) subspaceID uint64 - groupName string + groupID uint32 user string - expResult bool + shouldErr bool + check func(ctx sdk.Context) }{ { - name: "not being part of group returns false", + name: "non existing group returns error", subspaceID: 1, - groupName: "group", + groupID: 1, user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - expResult: false, + shouldErr: true, }, { - name: "being part of group returns true", + name: "user is added properly to group", store: func(ctx sdk.Context) { - suite.k.SaveSubspace(ctx, types.NewSubspace( + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + "Test group", + "This is a test group", + types.PermissionWrite, )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) - - userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") - suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) - suite.Require().NoError(err) }, subspaceID: 1, - groupName: "group", + groupID: 1, user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - expResult: true, + shouldErr: false, + check: func(ctx sdk.Context) { + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + suite.Require().NoError(err) + + isMember := suite.k.IsMemberOfGroup(ctx, 1, 1, userAddr) + suite.Require().True(isMember) + }, }, } @@ -241,54 +399,57 @@ func (suite *KeeperTestsuite) TestKeeper_IsMemberOfGroup() { userAddr, err := sdk.AccAddressFromBech32(tc.user) suite.Require().NoError(err) - result := suite.k.IsMemberOfGroup(ctx, tc.subspaceID, tc.groupName, userAddr) - suite.Require().Equal(tc.expResult, result) + err = suite.k.AddUserToGroup(ctx, tc.subspaceID, tc.groupID, userAddr) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + + if tc.check != nil { + tc.check(ctx) + } + } }) } } -func (suite *KeeperTestsuite) TestKeeper_AddUserToGroup() { +func (suite *KeeperTestsuite) TestKeeper_IsMemberOfGroup() { testCases := []struct { name string store func(ctx sdk.Context) subspaceID uint64 - groupName string + groupID uint32 user string - shouldErr bool - check func(ctx sdk.Context) + expResult bool }{ { - name: "non existing group returns error", + name: "not being part of group returns false", subspaceID: 1, - groupName: "group", + groupID: 1, user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - shouldErr: true, + expResult: false, }, { - name: "user is added properly to group", + name: "being part of group returns true", store: func(ctx sdk.Context) { - suite.k.SaveSubspace(ctx, types.NewSubspace( + + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + "Test group", + "This is a test group", + types.PermissionWrite, )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) - }, - subspaceID: 1, - groupName: "group", - user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - shouldErr: false, - check: func(ctx sdk.Context) { + userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - - isMember := suite.k.IsMemberOfGroup(ctx, 1, "group", userAddr) - suite.Require().True(isMember) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) + suite.Require().NoError(err) }, + subspaceID: 1, + groupID: 1, + user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + expResult: true, }, } @@ -303,16 +464,8 @@ func (suite *KeeperTestsuite) TestKeeper_AddUserToGroup() { userAddr, err := sdk.AccAddressFromBech32(tc.user) suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, tc.subspaceID, tc.groupName, userAddr) - if tc.shouldErr { - suite.Require().Error(err) - } else { - suite.Require().NoError(err) - - if tc.check != nil { - tc.check(ctx) - } - } + result := suite.k.IsMemberOfGroup(ctx, tc.subspaceID, tc.groupID, userAddr) + suite.Require().Equal(tc.expResult, result) }) } } @@ -322,50 +475,47 @@ func (suite *KeeperTestsuite) TestKeeper_RemoveUserFromGroup() { name string store func(ctx sdk.Context) subspaceID uint64 - groupName string + groupID uint32 user string check func(ctx sdk.Context) }{ { name: "non existing user is removed properly", subspaceID: 1, - groupName: "group", + groupID: 1, user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", check: func(ctx sdk.Context) { userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - isMember := suite.k.IsMemberOfGroup(ctx, 1, "group", userAddr) + isMember := suite.k.IsMemberOfGroup(ctx, 1, 1, userAddr) suite.Require().False(isMember) }, }, { name: "existing user is removed properly", store: func(ctx sdk.Context) { - suite.k.SaveSubspace(ctx, types.NewSubspace( + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, 1, - "Test subspace", - "This is a test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + "Test group", + "This is a test group", + types.PermissionWrite, )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) suite.Require().NoError(err) }, subspaceID: 1, - groupName: "group", + groupID: 1, user: "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", check: func(ctx sdk.Context) { userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - isMember := suite.k.IsMemberOfGroup(ctx, 1, "group", userAddr) + isMember := suite.k.IsMemberOfGroup(ctx, 1, 1, userAddr) suite.Require().False(isMember) }, }, @@ -382,7 +532,7 @@ func (suite *KeeperTestsuite) TestKeeper_RemoveUserFromGroup() { userAddr, err := sdk.AccAddressFromBech32(tc.user) suite.Require().NoError(err) - suite.k.RemoveUserFromGroup(ctx, tc.subspaceID, tc.groupName, userAddr) + suite.k.RemoveUserFromGroup(ctx, tc.subspaceID, tc.groupID, userAddr) if tc.check != nil { tc.check(ctx) } diff --git a/x/subspaces/keeper/grpc_query.go b/x/subspaces/keeper/grpc_query.go index cfa1bd2e19..4b4c5413b3 100644 --- a/x/subspaces/keeper/grpc_query.go +++ b/x/subspaces/keeper/grpc_query.go @@ -16,18 +16,6 @@ import ( var _ types.QueryServer = Keeper{} -// Subspace implements the Query/Subspace gRPC method -func (k Keeper) Subspace(ctx context.Context, request *types.QuerySubspaceRequest) (*types.QuerySubspaceResponse, error) { - sdkCtx := sdk.UnwrapSDKContext(ctx) - - subspace, found := k.GetSubspace(sdkCtx, request.SubspaceId) - if !found { - return nil, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "subspace with id %d not found", request.SubspaceId) - } - - return &types.QuerySubspaceResponse{Subspace: subspace}, nil -} - // Subspaces implements the Query/Subspaces gRPC method func (k Keeper) Subspaces(ctx context.Context, request *types.QuerySubspacesRequest) (*types.QuerySubspacesResponse, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) @@ -53,6 +41,18 @@ func (k Keeper) Subspaces(ctx context.Context, request *types.QuerySubspacesRequ return &types.QuerySubspacesResponse{Subspaces: subspaces, Pagination: pageRes}, nil } +// Subspace implements the Query/Subspace gRPC method +func (k Keeper) Subspace(ctx context.Context, request *types.QuerySubspaceRequest) (*types.QuerySubspaceResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + + subspace, found := k.GetSubspace(sdkCtx, request.SubspaceId) + if !found { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "subspace with id %d not found", request.SubspaceId) + } + + return &types.QuerySubspaceResponse{Subspace: subspace}, nil +} + // UserGroups implements the Query/UserGroups gRPC method func (k Keeper) UserGroups(ctx context.Context, request *types.QueryUserGroupsRequest) (*types.QueryUserGroupsResponse, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) @@ -66,10 +66,15 @@ func (k Keeper) UserGroups(ctx context.Context, request *types.QueryUserGroupsRe storePrefix := types.GroupsStoreKey(request.SubspaceId) groupsStore := prefix.NewStore(store, storePrefix) - var groups []string + var groups []types.UserGroup pageRes, err := query.Paginate(groupsStore, request.Pagination, func(key []byte, value []byte) error { - groupName := types.GetGroupNameFromBytes(bytes.TrimPrefix(key, storePrefix)) - groups = append(groups, groupName) + var group types.UserGroup + err := k.cdc.Unmarshal(value, &group) + if err != nil { + return err + } + + groups = append(groups, group) return nil }) @@ -80,6 +85,24 @@ func (k Keeper) UserGroups(ctx context.Context, request *types.QueryUserGroupsRe return &types.QueryUserGroupsResponse{Groups: groups, Pagination: pageRes}, nil } +// UserGroup implements the Query/UserGroup gRPC method +func (k Keeper) UserGroup(ctx context.Context, request *types.QueryUserGroupRequest) (*types.QueryUserGroupResponse, error) { + sdkCtx := sdk.UnwrapSDKContext(ctx) + + // Check if the subspace exists + if !k.HasSubspace(sdkCtx, request.SubspaceId) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", request.SubspaceId) + } + + // Get the group + group, found := k.GetUserGroup(sdkCtx, request.SubspaceId, request.GroupId) + if !found { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %d could not be found", request.GroupId) + } + + return &types.QueryUserGroupResponse{Group: group}, nil +} + // UserGroupMembers implements the Query/UserGroupMembers gRPC method func (k Keeper) UserGroupMembers(ctx context.Context, request *types.QueryUserGroupMembersRequest) (*types.QueryUserGroupMembersResponse, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) @@ -90,17 +113,17 @@ func (k Keeper) UserGroupMembers(ctx context.Context, request *types.QueryUserGr } // Check if the group exists - if !k.HasUserGroup(sdkCtx, request.SubspaceId, request.GroupName) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %s could not be found", request.GroupName) + if !k.HasUserGroup(sdkCtx, request.SubspaceId, request.GroupId) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %d could not be found", request.GroupId) } store := sdkCtx.KVStore(k.storeKey) - storePrefix := types.GroupMembersStoreKey(request.SubspaceId, request.GroupName) + storePrefix := types.GroupMembersStoreKey(request.SubspaceId, request.GroupId) membersStore := prefix.NewStore(store, storePrefix) var members []string pageRes, err := query.Paginate(membersStore, request.Pagination, func(key []byte, value []byte) error { - member := types.GetGroupMemberFromBytes(bytes.TrimPrefix(key, storePrefix)) + member := types.GetAddressFromBytes(bytes.TrimPrefix(key, storePrefix)) members = append(members, member.String()) return nil }) @@ -112,8 +135,8 @@ func (k Keeper) UserGroupMembers(ctx context.Context, request *types.QueryUserGr return &types.QueryUserGroupMembersResponse{Members: members, Pagination: pageRes}, nil } -// Permissions implements the Query/Permissions gRPC method -func (k Keeper) Permissions(ctx context.Context, request *types.QueryPermissionsRequest) (*types.QueryPermissionsResponse, error) { +// UserPermissions implements the Query/UserPermissions gRPC method +func (k Keeper) UserPermissions(ctx context.Context, request *types.QueryUserPermissionsRequest) (*types.QueryUserPermissionsResponse, error) { sdkCtx := sdk.UnwrapSDKContext(ctx) // Check if the subspace exists @@ -121,6 +144,11 @@ func (k Keeper) Permissions(ctx context.Context, request *types.QueryPermissions return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", request.SubspaceId) } - permission := k.GetPermissions(sdkCtx, request.SubspaceId, request.Target) - return &types.QueryPermissionsResponse{Permissions: permission}, nil + sdkAddr, err := sdk.AccAddressFromBech32(request.User) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address: %s", request.User) + } + + permission := k.GetUserPermissions(sdkCtx, request.SubspaceId, sdkAddr) + return &types.QueryUserPermissionsResponse{Permissions: permission}, nil } diff --git a/x/subspaces/keeper/grpc_query_test.go b/x/subspaces/keeper/grpc_query_test.go index c5caf9ed76..84c3e671ed 100644 --- a/x/subspaces/keeper/grpc_query_test.go +++ b/x/subspaces/keeper/grpc_query_test.go @@ -9,6 +9,80 @@ import ( "github.com/cosmos/cosmos-sdk/types/query" ) +func (suite *KeeperTestsuite) TestQueryServer_Subspaces() { + testCases := []struct { + name string + store func(ctx sdk.Context) + req *types.QuerySubspacesRequest + expSubspaces []types.Subspace + }{ + + { + name: "invalid pagination returns empty slice", + req: types.NewQuerySubspacesRequest(&query.PageRequest{ + Limit: 1, + Offset: 1, + }), + expSubspaces: nil, + }, + { + name: "valid pagination returns result properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveSubspace(ctx, types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + req: &types.QuerySubspacesRequest{ + Pagination: &query.PageRequest{ + Offset: 1, + Limit: 1, + CountTotal: true, + }, + }, + expSubspaces: []types.Subspace{ + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + res, err := suite.k.Subspaces(sdk.WrapSDKContext(ctx), tc.req) + suite.Require().NoError(err) + suite.Require().Equal(tc.expSubspaces, res.Subspaces) + }) + } +} + func (suite *KeeperTestsuite) TestQueryServer_Subspace() { testCases := []struct { name string @@ -70,24 +144,21 @@ func (suite *KeeperTestsuite) TestQueryServer_Subspace() { } } -func (suite *KeeperTestsuite) TestQueryServer_Subspaces() { +func (suite *KeeperTestsuite) TestQueryServer_UserGroups() { testCases := []struct { - name string - store func(ctx sdk.Context) - req *types.QuerySubspacesRequest - expSubspaces []types.Subspace + name string + store func(ctx sdk.Context) + req *types.QueryUserGroupsRequest + shouldErr bool + expGroups []types.UserGroup }{ - { - name: "invalid pagination returns empty slice", - req: types.NewQuerySubspacesRequest(&query.PageRequest{ - Limit: 1, - Offset: 1, - }), - expSubspaces: nil, + name: "non existing subspace returns error", + req: types.NewQueryUserGroupsRequest(1, nil), + shouldErr: true, }, { - name: "valid pagination returns result properly", + name: "existing groups are returned properly", store: func(ctx sdk.Context) { suite.k.SaveSubspace(ctx, types.NewSubspace( 1, @@ -98,32 +169,48 @@ func (suite *KeeperTestsuite) TestQueryServer_Subspaces() { "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveSubspace(ctx, types.NewSubspace( + + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "First test group", + "This is a test group", + types.PermissionWrite, + )) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, 2, - "Another test subspace", - "This is another test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + "Second test group", + "This is a test group", + types.PermissionWrite, + )) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 3, + "Third test group", + "This is a test group", + types.PermissionWrite, )) }, - req: &types.QuerySubspacesRequest{ - Pagination: &query.PageRequest{ - Offset: 1, - Limit: 1, - CountTotal: true, - }, - }, - expSubspaces: []types.Subspace{ - types.NewSubspace( + req: types.NewQueryUserGroupsRequest(1, &query.PageRequest{ + Offset: 1, + Limit: 2, + }), + shouldErr: false, + expGroups: []types.UserGroup{ + types.NewUserGroup( + 1, 2, - "Another test subspace", - "This is another test subspace", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + "Second test group", + "This is a test group", + types.PermissionWrite, + ), + types.NewUserGroup( + 1, + 3, + "Third test group", + "This is a test group", + types.PermissionWrite, ), }, }, @@ -137,28 +224,32 @@ func (suite *KeeperTestsuite) TestQueryServer_Subspaces() { tc.store(ctx) } - res, err := suite.k.Subspaces(sdk.WrapSDKContext(ctx), tc.req) - suite.Require().NoError(err) - suite.Require().Equal(tc.expSubspaces, res.Subspaces) + res, err := suite.k.UserGroups(sdk.WrapSDKContext(ctx), tc.req) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expGroups, res.Groups) + } }) } } -func (suite *KeeperTestsuite) TestQueryServer_UserGroups() { +func (suite *KeeperTestsuite) TestQueryServer_UserGroup() { testCases := []struct { name string store func(ctx sdk.Context) + req *types.QueryUserGroupRequest shouldErr bool - req *types.QueryUserGroupsRequest - expGroups []string + expGroup types.UserGroup }{ { - name: "non existing subspace returns error", - req: types.NewQueryUserGroupsRequest(1, nil), + name: "not found group returns error", + req: types.NewQueryUserGroupRequest(1, 1), shouldErr: true, }, { - name: "existing groups are returned properly", + name: "found group is returned properly", store: func(ctx sdk.Context) { suite.k.SaveSubspace(ctx, types.NewSubspace( 1, @@ -170,16 +261,23 @@ func (suite *KeeperTestsuite) TestQueryServer_UserGroups() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "1-group", types.PermissionWrite) - suite.k.SaveUserGroup(ctx, 1, "2-group", types.PermissionWrite) - suite.k.SaveUserGroup(ctx, 1, "3-group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) }, - req: types.NewQueryUserGroupsRequest(1, &query.PageRequest{ - Offset: 1, - Limit: 2, - }), + req: types.NewQueryUserGroupRequest(1, 1), shouldErr: false, - expGroups: []string{"2-group", "3-group"}, + expGroup: types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), }, } @@ -191,12 +289,12 @@ func (suite *KeeperTestsuite) TestQueryServer_UserGroups() { tc.store(ctx) } - res, err := suite.k.UserGroups(sdk.WrapSDKContext(ctx), tc.req) + res, err := suite.k.UserGroup(sdk.WrapSDKContext(ctx), tc.req) if tc.shouldErr { suite.Require().Error(err) } else { suite.Require().NoError(err) - suite.Require().Equal(tc.expGroups, res.Groups) + suite.Require().Equal(tc.expGroup, res.Group) } }) } @@ -212,7 +310,7 @@ func (suite *KeeperTestsuite) TestQueryServer_UserGroupMembers() { }{ { name: "non existing subspace returns error", - req: types.NewQueryUserGroupMembersRequest(1, "group", nil), + req: types.NewQueryUserGroupMembersRequest(1, 1, nil), shouldErr: true, }, { @@ -228,7 +326,7 @@ func (suite *KeeperTestsuite) TestQueryServer_UserGroupMembers() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) }, - req: types.NewQueryUserGroupMembersRequest(1, "group", nil), + req: types.NewQueryUserGroupMembersRequest(1, 1, nil), shouldErr: true, }, { @@ -244,27 +342,33 @@ func (suite *KeeperTestsuite) TestQueryServer_UserGroupMembers() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) userAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) suite.Require().NoError(err) userAddr, err = sdk.AccAddressFromBech32("cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) suite.Require().NoError(err) userAddr, err = sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) suite.Require().NoError(err) }, - req: types.NewQueryUserGroupMembersRequest(1, "group", &query.PageRequest{ + req: types.NewQueryUserGroupMembersRequest(1, 1, &query.PageRequest{ Offset: 1, Limit: 1, }), @@ -292,21 +396,24 @@ func (suite *KeeperTestsuite) TestQueryServer_UserGroupMembers() { } } -func (suite *KeeperTestsuite) TestQueryServer_Permissions() { +func (suite *KeeperTestsuite) TestQueryServer_UserPermissions() { testCases := []struct { name string store func(ctx sdk.Context) - req *types.QueryPermissionsRequest + req *types.QueryUserPermissionsRequest shouldErr bool expPermissions types.Permission }{ { name: "not found subspace returns error", shouldErr: true, - req: types.NewQueryPermissionsRequest(1, "group"), + req: types.NewQueryUserPermissionsRequest( + 1, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), }, { - name: "not found target returns PermissionNothing", + name: "not found user returns PermissionNothing", store: func(ctx sdk.Context) { suite.k.SaveSubspace(ctx, types.NewSubspace( 1, @@ -318,7 +425,10 @@ func (suite *KeeperTestsuite) TestQueryServer_Permissions() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) }, - req: types.NewQueryPermissionsRequest(1, "group"), + req: types.NewQueryUserPermissionsRequest( + 1, + "cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", + ), shouldErr: false, expPermissions: types.PermissionNothing, }, @@ -334,9 +444,15 @@ func (suite *KeeperTestsuite) TestQueryServer_Permissions() { "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SetPermissions(ctx, 1, "group", types.PermissionWrite) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionWrite) }, - req: types.NewQueryPermissionsRequest(1, "group"), + req: types.NewQueryUserPermissionsRequest( + 1, + "cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", + ), shouldErr: false, expPermissions: types.PermissionWrite, }, @@ -350,7 +466,7 @@ func (suite *KeeperTestsuite) TestQueryServer_Permissions() { tc.store(ctx) } - res, err := suite.k.Permissions(sdk.WrapSDKContext(ctx), tc.req) + res, err := suite.k.UserPermissions(sdk.WrapSDKContext(ctx), tc.req) if tc.shouldErr { suite.Require().Error(err) } else { diff --git a/x/subspaces/keeper/hooks.go b/x/subspaces/keeper/hooks.go index 4c06067aa3..524c381127 100644 --- a/x/subspaces/keeper/hooks.go +++ b/x/subspaces/keeper/hooks.go @@ -24,43 +24,43 @@ func (k Keeper) AfterSubspaceDeleted(ctx sdk.Context, subspaceID uint64) { } // AfterSubspaceGroupSaved - call if hook is registered -func (k Keeper) AfterSubspaceGroupSaved(ctx sdk.Context, subspaceID uint64, groupName string) { +func (k Keeper) AfterSubspaceGroupSaved(ctx sdk.Context, subspaceID uint64, groupID uint32) { if k.hooks != nil { - k.hooks.AfterSubspaceGroupSaved(ctx, subspaceID, groupName) + k.hooks.AfterSubspaceGroupSaved(ctx, subspaceID, groupID) } } // AfterSubspaceGroupMemberAdded - call if hook is registered -func (k Keeper) AfterSubspaceGroupMemberAdded(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { +func (k Keeper) AfterSubspaceGroupMemberAdded(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) { if k.hooks != nil { - k.hooks.AfterSubspaceGroupMemberAdded(ctx, subspaceID, groupName, user) + k.hooks.AfterSubspaceGroupMemberAdded(ctx, subspaceID, groupID, user) } } // AfterSubspaceGroupMemberRemoved - call if hook is registered -func (k Keeper) AfterSubspaceGroupMemberRemoved(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { +func (k Keeper) AfterSubspaceGroupMemberRemoved(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) { if k.hooks != nil { - k.hooks.AfterSubspaceGroupMemberRemoved(ctx, subspaceID, groupName, user) + k.hooks.AfterSubspaceGroupMemberRemoved(ctx, subspaceID, groupID, user) } } // AfterSubspaceGroupDeleted - call if hook is registered -func (k Keeper) AfterSubspaceGroupDeleted(ctx sdk.Context, subspaceID uint64, groupName string) { +func (k Keeper) AfterSubspaceGroupDeleted(ctx sdk.Context, subspaceID uint64, groupID uint32) { if k.hooks != nil { - k.hooks.AfterSubspaceGroupDeleted(ctx, subspaceID, groupName) + k.hooks.AfterSubspaceGroupDeleted(ctx, subspaceID, groupID) } } -// AfterPermissionSet - call if hook is registered -func (k Keeper) AfterPermissionSet(ctx sdk.Context, subspaceID uint64, target string, permissions types.Permission) { +// AfterUserPermissionSet - call if hook is registered +func (k Keeper) AfterUserPermissionSet(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress, permissions types.Permission) { if k.hooks != nil { - k.hooks.AfterPermissionSet(ctx, subspaceID, target, permissions) + k.hooks.AfterUserPermissionSet(ctx, subspaceID, user, permissions) } } -// AfterPermissionRemoved - call if hook is registered -func (k Keeper) AfterPermissionRemoved(ctx sdk.Context, subspaceID uint64, target string) { +// AfterUserPermissionRemoved - call if hook is registered +func (k Keeper) AfterUserPermissionRemoved(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress) { if k.hooks != nil { - k.hooks.AfterPermissionRemoved(ctx, subspaceID, target) + k.hooks.AfterUserPermissionRemoved(ctx, subspaceID, user) } } diff --git a/x/subspaces/keeper/invariants.go b/x/subspaces/keeper/invariants.go index f1db7f42ed..fdbfe76205 100644 --- a/x/subspaces/keeper/invariants.go +++ b/x/subspaces/keeper/invariants.go @@ -12,6 +12,8 @@ import ( func RegisterInvariants(ir sdk.InvariantRegistry, keeper Keeper) { ir.RegisterRoute(types.ModuleName, "valid-subspaces", ValidSubspacesInvariant(keeper)) + ir.RegisterRoute(types.ModuleName, "valid-user-groups", + ValidUserGroupsInvariant(keeper)) } // AllInvariants runs all invariants of the module @@ -22,17 +24,16 @@ func AllInvariants(k Keeper) sdk.Invariant { return res, true } + res, broken = ValidUserGroupsInvariant(k)(ctx) + if broken { + return res, true + } + return "Every invariant condition is fulfilled correctly", false } } -// formatOutputSubspaces concatenate the subspaces given into a unique string -func formatOutputSubspaces(subspaces []types.Subspace) (outputSubspaces string) { - for _, subspace := range subspaces { - outputSubspaces += fmt.Sprintf("%d\n", subspace.ID) - } - return outputSubspaces -} +// -------------------------------------------------------------------------------------------------------------------- // ValidSubspacesInvariant checks that all the subspaces are valid func ValidSubspacesInvariant(k Keeper) sdk.Invariant { @@ -51,3 +52,46 @@ func ValidSubspacesInvariant(k Keeper) sdk.Invariant { ), invalidSubspaces != nil } } + +// formatOutputSubspaces concatenate the subspaces given into a unique string +func formatOutputSubspaces(subspaces []types.Subspace) (outputSubspaces string) { + for _, subspace := range subspaces { + outputSubspaces += fmt.Sprintf("%d\n", subspace.ID) + } + return outputSubspaces +} + +// -------------------------------------------------------------------------------------------------------------------- + +// ValidUserGroupsInvariant checks that all the subspaces are valid +func ValidUserGroupsInvariant(k Keeper) sdk.Invariant { + return func(ctx sdk.Context) (string, bool) { + var invalidUserGroups []types.UserGroup + k.IterateUserGroups(ctx, func(_ int64, group types.UserGroup) (stop bool) { + err := group.Validate() + if err != nil { + // The group is not valid + invalidUserGroups = append(invalidUserGroups, group) + } + + if !k.HasSubspace(ctx, group.SubspaceID) { + // The subspace for this group does not exist anymore + invalidUserGroups = append(invalidUserGroups, group) + } + + return false + }) + + return sdk.FormatInvariant(types.ModuleName, "invalid user groups", + fmt.Sprintf("the following user groups are invalid:\n %s", formatOutputUserGroups(invalidUserGroups)), + ), invalidUserGroups != nil + } +} + +// formatOutputUserGroups concatenate the subspaces given into a unique string +func formatOutputUserGroups(groups []types.UserGroup) (outputUserGroups string) { + for _, group := range groups { + outputUserGroups += fmt.Sprintf("%d\n", group.ID) + } + return outputUserGroups +} diff --git a/x/subspaces/keeper/invariants_test.go b/x/subspaces/keeper/invariants_test.go index e62bcb65cb..d284284c9e 100644 --- a/x/subspaces/keeper/invariants_test.go +++ b/x/subspaces/keeper/invariants_test.go @@ -16,11 +16,11 @@ func (suite *KeeperTestsuite) TestInvariants() { expBroken bool }{ { - name: "all invariants are not violated", + name: "valid subspace invariant violated", store: func(ctx sdk.Context) { suite.k.SaveSubspace(ctx, types.NewSubspace( 1, - "Test subspace", + "", "This is a test subspace", "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", @@ -28,10 +28,10 @@ func (suite *KeeperTestsuite) TestInvariants() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) }, - expBroken: false, + expBroken: true, }, { - name: "valid subspace invariant violated", + name: "valid user groups invariant violated - invalid data", store: func(ctx sdk.Context) { suite.k.SaveSubspace(ctx, types.NewSubspace( 1, @@ -42,9 +42,45 @@ func (suite *KeeperTestsuite) TestInvariants() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) + + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 0, + "This is a test group", + "This is a test group", + types.PermissionWrite, + )) }, expBroken: true, }, + { + name: "valid user groups invariant violated - missing associated subspace", + store: func(ctx sdk.Context) { + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "This is a test group", + "This is a test group", + types.PermissionWrite, + )) + }, + expBroken: true, + }, + { + name: "no invariant is violated", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + expBroken: false, + }, } for _, test := range tests { diff --git a/x/subspaces/keeper/msg_server.go b/x/subspaces/keeper/msg_server.go index e47ed73ba7..4ff2c88840 100644 --- a/x/subspaces/keeper/msg_server.go +++ b/x/subspaces/keeper/msg_server.go @@ -75,14 +75,19 @@ func (k msgServer) EditSubspace(goCtx context.Context, msg *types.MsgEditSubspac return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) } + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address: %s", msg.Signer) + } + // Check the permission to edit - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionChangeInfo) { - return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot edit this subspace") + if !k.HasPermission(ctx, msg.SubspaceID, signer, types.PermissionChangeInfo) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage this subspace") } // Update the subspace and validate it updated := subspace.Update(types.NewSubspaceUpdate(msg.Name, msg.Description, msg.Owner, msg.Treasury)) - err := updated.Validate() + err = updated.Validate() if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) } @@ -114,9 +119,14 @@ func (k msgServer) DeleteSubspace(goCtx context.Context, msg *types.MsgDeleteSub return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) } + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address: %s", msg.Signer) + } + // Check the permission to edit - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionDeleteSubspace) { - return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot edit this subspace") + if !k.HasPermission(ctx, msg.SubspaceID, signer, types.PermissionDeleteSubspace) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage this subspace") } // Delete the subspace @@ -143,21 +153,36 @@ func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUs // Check if the subspace exists if !k.HasSubspace(ctx, msg.SubspaceID) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group with id %d not found", msg.SubspaceID) } - // Check if there is another group with the same name - if k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupName) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group with name %s already exists", msg.GroupName) + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address: %s", msg.Creator) } // Check the permission to create a group - if !k.HasPermission(ctx, msg.SubspaceID, msg.Creator, types.PermissionManageGroups) { + if !k.HasPermission(ctx, msg.SubspaceID, creator, types.PermissionManageGroups) { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot create user groups in this subspace") } - // Store the group - k.SaveUserGroup(ctx, msg.SubspaceID, msg.GroupName, msg.DefaultPermissions) + // Get the next group ID + groupID, err := k.GetGroupID(ctx, msg.SubspaceID) + if err != nil { + return nil, err + } + + // Create and validate the group + group := types.NewUserGroup(msg.SubspaceID, groupID, msg.Name, msg.Description, msg.DefaultPermissions) + if err := group.Validate(); err != nil { + return nil, err + } + + // Save the group + k.SaveUserGroup(ctx, group) + + // Update the id for the next group + k.SetGroupID(ctx, msg.SubspaceID, group.ID+1) ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( @@ -168,11 +193,107 @@ func (k msgServer) CreateUserGroup(goCtx context.Context, msg *types.MsgCreateUs sdk.NewEvent( types.EventTypeCreateUserGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), - sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), + sdk.NewAttribute(types.AttributeKeyUserGroupID, fmt.Sprintf("%d", group.ID)), + ), + }) + + return &types.MsgCreateUserGroupResponse{GroupID: groupID}, nil +} + +// EditUserGroup defines a rpc method for MsgEditUserGroup +func (k msgServer) EditUserGroup(goCtx context.Context, msg *types.MsgEditUserGroup) (*types.MsgEditUserGroupResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // Check if the subspace exists + if !k.HasSubspace(ctx, msg.SubspaceID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group with id %d not found", msg.SubspaceID) + } + + // Check if the group exists + group, found := k.GetUserGroup(ctx, msg.SubspaceID, msg.GroupID) + if !found { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group with id %d not found", msg.GroupID) + } + + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address: %s", msg.Signer) + } + + // Check the permission to create a group + if !k.HasPermission(ctx, msg.SubspaceID, signer, types.PermissionManageGroups) { + return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage user groups in this subspace") + } + + // Update the group and validate it + updated := group.Update(types.NewGroupUpdate(msg.Name, msg.Description)) + err = updated.Validate() + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) + } + + // Save the group + k.SaveUserGroup(ctx, group) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), + ), + sdk.NewEvent( + types.EventTypeEditUserGroup, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), + sdk.NewAttribute(types.AttributeKeyUserGroupID, fmt.Sprintf("%d", msg.GroupID)), + ), + }) + + return &types.MsgEditUserGroupResponse{}, nil +} + +// SetUserGroupPermissions defines a rpc method for MsgSetUserGroupPermissions +func (k msgServer) SetUserGroupPermissions(goCtx context.Context, msg *types.MsgSetUserGroupPermissions) (*types.MsgSetUserGroupPermissionsResponse, error) { + ctx := sdk.UnwrapSDKContext(goCtx) + + // Check if the subspace exists + if !k.HasSubspace(ctx, msg.SubspaceID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) + } + + // Check if the group exists + group, found := k.GetUserGroup(ctx, msg.SubspaceID, msg.GroupID) + if !found { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group with id %d not found", msg.GroupID) + } + + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address: %s", msg.Signer) + } + + // Check the permissions + if !k.HasPermission(ctx, msg.SubspaceID, signer, types.PermissionSetPermissions) { + return nil, sdkerrors.Wrapf(types.ErrPermissionDenied, "you cannot manage permissions in this subspace") + } + + // Set the group permissions and store the group + group.Permissions = msg.Permissions + k.SaveUserGroup(ctx, group) + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, signer.String()), + ), + sdk.NewEvent( + types.ActionSetUserGroupPermissions, + sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), + sdk.NewAttribute(types.AttributeKeyUserGroupID, fmt.Sprintf("%d", msg.GroupID)), ), }) - return &types.MsgCreateUserGroupResponse{}, nil + return &types.MsgSetUserGroupPermissionsResponse{}, nil } // DeleteUserGroup defines a rpc method for MsgDeleteUserGroup @@ -185,17 +306,22 @@ func (k msgServer) DeleteUserGroup(goCtx context.Context, msg *types.MsgDeleteUs } // Check if the group exists - if !k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupName) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %s could not be found", msg.GroupName) + if !k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %d could not be found", msg.GroupID) + } + + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address: %s", msg.Signer) } // Check for permissions - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionManageGroups) { + if !k.HasPermission(ctx, msg.SubspaceID, signer, types.PermissionManageGroups) { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot delete user groups in this subspace") } // Delete the group - k.Keeper.DeleteUserGroup(ctx, msg.SubspaceID, msg.GroupName) + k.Keeper.DeleteUserGroup(ctx, msg.SubspaceID, msg.GroupID) ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( @@ -206,7 +332,7 @@ func (k msgServer) DeleteUserGroup(goCtx context.Context, msg *types.MsgDeleteUs sdk.NewEvent( types.EventTypeDeleteUserGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), - sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), + sdk.NewAttribute(types.AttributeKeyUserGroupID, fmt.Sprintf("%d", msg.GroupID)), ), }) @@ -223,12 +349,17 @@ func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUs } // Check if the group exists - if !k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupName) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %s could not be found", msg.GroupName) + if !k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %d could not be found", msg.GroupID) + } + + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address: %s", msg.Signer) } // Check the permissions - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + if !k.HasPermission(ctx, msg.SubspaceID, signer, types.PermissionSetPermissions) { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage user group members in this subspace") } @@ -238,12 +369,12 @@ func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUs } // Check if the user is already part of the group - if k.IsMemberOfGroup(ctx, msg.SubspaceID, msg.GroupName, user) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user is already part of group %s", msg.GroupName) + if k.IsMemberOfGroup(ctx, msg.SubspaceID, msg.GroupID, user) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user is already part of group %d", msg.GroupID) } // Set the user group - err = k.AddUserToGroup(ctx, msg.SubspaceID, msg.GroupName, user) + err = k.AddUserToGroup(ctx, msg.SubspaceID, msg.GroupID, user) if err != nil { return nil, err } @@ -257,7 +388,7 @@ func (k msgServer) AddUserToUserGroup(goCtx context.Context, msg *types.MsgAddUs sdk.NewEvent( types.EventTypeAddUserToGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), - sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), + sdk.NewAttribute(types.AttributeKeyUserGroupID, fmt.Sprintf("%d", msg.GroupID)), sdk.NewAttribute(types.AttributeKeyUser, msg.User), ), }) @@ -275,12 +406,17 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg } // Check if the group exists - if !k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupName) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %s could not be found", msg.GroupName) + if !k.HasUserGroup(ctx, msg.SubspaceID, msg.GroupID) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "group %d could not be found", msg.GroupID) + } + + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address: %s", msg.Signer) } // Check the permissions - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { + if !k.HasPermission(ctx, msg.SubspaceID, signer, types.PermissionSetPermissions) { return nil, sdkerrors.Wrap(types.ErrPermissionDenied, "you cannot manage user group members in this subspace") } @@ -290,12 +426,12 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg } // Check if the user is already part of the group - if !k.IsMemberOfGroup(ctx, msg.SubspaceID, msg.GroupName, user) { - return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user is not part of group %s", msg.GroupName) + if !k.IsMemberOfGroup(ctx, msg.SubspaceID, msg.GroupID, user) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "user is not part of group %d", msg.GroupID) } // Remove the user group - k.RemoveUserFromGroup(ctx, msg.SubspaceID, msg.GroupName, user) + k.RemoveUserFromGroup(ctx, msg.SubspaceID, msg.GroupID, user) ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( @@ -306,7 +442,7 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg sdk.NewEvent( types.EventTypeRemoveUserFromGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), - sdk.NewAttribute(types.AttributeKeyUserGroupName, msg.GroupName), + sdk.NewAttribute(types.AttributeKeyUserGroupID, fmt.Sprintf("%d", msg.GroupID)), sdk.NewAttribute(types.AttributeKeyUser, msg.User), ), }) @@ -314,8 +450,8 @@ func (k msgServer) RemoveUserFromUserGroup(goCtx context.Context, msg *types.Msg return &types.MsgRemoveUserFromUserGroupResponse{}, nil } -// SetPermissions defines a rpc method for MsgSetPermissions -func (k msgServer) SetPermissions(goCtx context.Context, msg *types.MsgSetPermissions) (*types.MsgSetPermissionsResponse, error) { +// SetUserPermissions defines a rpc method for MsgSetUserPermissions +func (k msgServer) SetUserPermissions(goCtx context.Context, msg *types.MsgSetUserPermissions) (*types.MsgSetUserPermissionsResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) // Check if the subspace exists @@ -323,26 +459,41 @@ func (k msgServer) SetPermissions(goCtx context.Context, msg *types.MsgSetPermis return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "subspace with id %d not found", msg.SubspaceID) } + user, err := sdk.AccAddressFromBech32(msg.User) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address: %s", msg.User) + } + + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address: %s", msg.Signer) + } + // Check the permissions - if !k.HasPermission(ctx, msg.SubspaceID, msg.Signer, types.PermissionSetPermissions) { - return nil, sdkerrors.Wrapf(types.ErrPermissionDenied, "you cannot set other users permissions") + if !k.HasPermission(ctx, msg.SubspaceID, signer, types.PermissionSetPermissions) { + return nil, sdkerrors.Wrapf(types.ErrPermissionDenied, "you cannot manage permissions in this subspace") } // Set the permissions - k.Keeper.SetPermissions(ctx, msg.SubspaceID, msg.Target, msg.Permissions) + if msg.Permissions == types.PermissionNothing { + // Remove the permission to clear the store if PermissionNothing is used + k.RemoveUserPermissions(ctx, msg.SubspaceID, user) + } else { + k.Keeper.SetUserPermissions(ctx, msg.SubspaceID, user, msg.Permissions) + } ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), - sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer), + sdk.NewAttribute(sdk.AttributeKeySender, signer.String()), ), sdk.NewEvent( - types.EventTypeSetPermissions, + types.EventTypeSetUserPermissions, sdk.NewAttribute(types.AttributeKeySubspaceID, fmt.Sprintf("%d", msg.SubspaceID)), - sdk.NewAttribute(types.AttributeKeyTarget, msg.Target), + sdk.NewAttribute(types.AttributeKeyUser, user.String()), ), }) - return &types.MsgSetPermissionsResponse{}, nil + return &types.MsgSetUserPermissionsResponse{}, nil } diff --git a/x/subspaces/keeper/msg_server_test.go b/x/subspaces/keeper/msg_server_test.go index 0e79571307..6a292b7e99 100644 --- a/x/subspaces/keeper/msg_server_test.go +++ b/x/subspaces/keeper/msg_server_test.go @@ -299,7 +299,10 @@ func (suite *KeeperTestsuite) TestMsgServer_EditSubspace() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", blockTime, )) - suite.k.SetPermissions(ctx, 1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", types.PermissionChangeInfo) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionChangeInfo) }, msg: types.NewMsgEditSubspace( 1, @@ -424,7 +427,10 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteSubspace() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SetPermissions(ctx, 1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", types.PermissionDeleteSubspace) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionDeleteSubspace) }, msg: types.NewMsgDeleteSubspace(1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5"), shouldErr: false, @@ -486,33 +492,12 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() { msg: types.NewMsgCreateUserGroup( 1, "group", + "description", types.PermissionWrite, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), shouldErr: true, }, - { - name: "duplicated group returns error", - store: func(ctx sdk.Context) { - suite.k.SaveSubspace(ctx, types.NewSubspace( - 1, - "Test subspace", - "This is a test subspace", - "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", - "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", - "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), - )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) - }, - msg: types.NewMsgCreateUserGroup( - 1, - "group", - types.PermissionWrite, - "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", - ), - shouldErr: true, - }, { name: "user without permission returns error", store: func(ctx sdk.Context) { @@ -529,6 +514,7 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() { msg: types.NewMsgCreateUserGroup( 1, "group", + "description", types.PermissionWrite, "cosmos1y4emx0mm4ncva9mnv9yvjrm7nrq3psvmwhk9ll", ), @@ -546,12 +532,24 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionChangeInfo) - suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionManageGroups) + + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + suite.k.SetGroupID(ctx, 1, 2) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionManageGroups) }, msg: types.NewMsgCreateUserGroup( 1, - "another-group", + "another group", + "another description", types.PermissionWrite, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), @@ -565,12 +563,12 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() { sdk.NewEvent( types.EventTypeCreateUserGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), - sdk.NewAttribute(types.AttributeKeyUserGroupName, "another-group"), + sdk.NewAttribute(types.AttributeKeyUserGroupID, "2"), ), }, check: func(ctx sdk.Context) { - suite.Require().True(suite.k.HasUserGroup(ctx, 1, "group")) - suite.Require().True(suite.k.HasUserGroup(ctx, 1, "another-group")) + suite.Require().True(suite.k.HasUserGroup(ctx, 1, 1)) + suite.Require().True(suite.k.HasUserGroup(ctx, 1, 2)) }, }, } @@ -614,7 +612,7 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteUserGroup() { name: "subspace not found returns error", msg: types.NewMsgDeleteUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), shouldErr: true, @@ -634,7 +632,7 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteUserGroup() { }, msg: types.NewMsgDeleteUserGroup( 1, - "group", + 1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), shouldErr: true, @@ -651,11 +649,17 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteUserGroup() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) }, msg: types.NewMsgDeleteUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), shouldErr: true, @@ -672,12 +676,21 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteUserGroup() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) - suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionManageGroups) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionManageGroups) }, msg: types.NewMsgDeleteUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), shouldErr: false, @@ -690,11 +703,11 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteUserGroup() { sdk.NewEvent( types.EventTypeDeleteUserGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), - sdk.NewAttribute(types.AttributeKeyUserGroupName, "group"), + sdk.NewAttribute(types.AttributeKeyUserGroupID, "1"), ), }, check: func(ctx sdk.Context) { - hasGroup := suite.k.HasUserGroup(ctx, 1, "group") + hasGroup := suite.k.HasUserGroup(ctx, 1, 2) suite.Require().False(hasGroup) }, }, @@ -739,7 +752,7 @@ func (suite *KeeperTestsuite) TestMsgServer_AddUserToGroup() { name: "subspace not found returns error", msg: types.NewMsgAddUserToUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -760,7 +773,7 @@ func (suite *KeeperTestsuite) TestMsgServer_AddUserToGroup() { }, msg: types.NewMsgAddUserToUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -778,11 +791,17 @@ func (suite *KeeperTestsuite) TestMsgServer_AddUserToGroup() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) }, msg: types.NewMsgAddUserToUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), @@ -800,17 +819,23 @@ func (suite *KeeperTestsuite) TestMsgServer_AddUserToGroup() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", sdkAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, sdkAddr) suite.Require().NoError(err) }, msg: types.NewMsgAddUserToUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), @@ -828,12 +853,21 @@ func (suite *KeeperTestsuite) TestMsgServer_AddUserToGroup() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) - suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionSetPermissions) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionSetPermissions) }, msg: types.NewMsgAddUserToUserGroup( 1, - "group", + 1, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), @@ -847,7 +881,7 @@ func (suite *KeeperTestsuite) TestMsgServer_AddUserToGroup() { sdk.NewEvent( types.EventTypeAddUserToGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), - sdk.NewAttribute(types.AttributeKeyUserGroupName, "group"), + sdk.NewAttribute(types.AttributeKeyUserGroupID, "1"), sdk.NewAttribute(types.AttributeKeyUser, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm"), ), }, @@ -855,7 +889,7 @@ func (suite *KeeperTestsuite) TestMsgServer_AddUserToGroup() { sdkAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - result := suite.k.IsMemberOfGroup(ctx, 1, "group", sdkAddr) + result := suite.k.IsMemberOfGroup(ctx, 1, 1, sdkAddr) suite.Require().True(result) }, }, @@ -900,7 +934,7 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { name: "subspace not found returns error", msg: types.NewMsgRemoveUserFromUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -921,7 +955,7 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { }, msg: types.NewMsgRemoveUserFromUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -939,11 +973,17 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) }, msg: types.NewMsgRemoveUserFromUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), @@ -961,11 +1001,17 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) }, msg: types.NewMsgRemoveUserFromUserGroup( 1, - "group", + 1, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), @@ -983,18 +1029,27 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite) - suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionSetPermissions) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) - sdkAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionSetPermissions) + + sdkAddr, err = sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", sdkAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, sdkAddr) suite.Require().NoError(err) }, msg: types.NewMsgRemoveUserFromUserGroup( 1, - "group", + 1, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), @@ -1008,7 +1063,7 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { sdk.NewEvent( types.EventTypeRemoveUserFromGroup, sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), - sdk.NewAttribute(types.AttributeKeyUserGroupName, "group"), + sdk.NewAttribute(types.AttributeKeyUserGroupID, "1"), sdk.NewAttribute(types.AttributeKeyUser, "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm"), ), }, @@ -1016,7 +1071,7 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { sdkAddr, err := sdk.AccAddressFromBech32("cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm") suite.Require().NoError(err) - result := suite.k.IsMemberOfGroup(ctx, 1, "group", sdkAddr) + result := suite.k.IsMemberOfGroup(ctx, 1, 1, sdkAddr) suite.Require().False(result) }, }, @@ -1048,18 +1103,18 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { } } -func (suite *KeeperTestsuite) TestMsgServer_SetPermissions() { +func (suite *KeeperTestsuite) TestMsgServer_SetUserPermissions() { testCases := []struct { name string store func(ctx sdk.Context) - msg *types.MsgSetPermissions + msg *types.MsgSetUserPermissions shouldErr bool expEvents sdk.Events check func(ctx sdk.Context) }{ { name: "subspace not found returns error", - msg: types.NewMsgSetPermissions( + msg: types.NewMsgSetUserPermissions( 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionWrite, @@ -1080,7 +1135,7 @@ func (suite *KeeperTestsuite) TestMsgServer_SetPermissions() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) }, - msg: types.NewMsgSetPermissions( + msg: types.NewMsgSetUserPermissions( 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionWrite, @@ -1101,11 +1156,13 @@ func (suite *KeeperTestsuite) TestMsgServer_SetPermissions() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SetPermissions(ctx, 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionSetPermissions) + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionSetPermissions) }, - msg: types.NewMsgSetPermissions( + msg: types.NewMsgSetUserPermissions( 1, - "group", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionWrite, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), @@ -1117,13 +1174,15 @@ func (suite *KeeperTestsuite) TestMsgServer_SetPermissions() { sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"), ), sdk.NewEvent( - types.EventTypeSetPermissions, + types.EventTypeSetUserPermissions, sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), - sdk.NewAttribute(types.AttributeKeyTarget, "group"), + sdk.NewAttribute(types.AttributeKeyUser, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"), ), }, check: func(ctx sdk.Context) { - permissions := suite.k.GetPermissions(ctx, 1, "group") + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + permissions := suite.k.GetUserPermissions(ctx, 1, sdkAddr) suite.Require().Equal(types.PermissionWrite, permissions) }, }, @@ -1139,7 +1198,7 @@ func (suite *KeeperTestsuite) TestMsgServer_SetPermissions() { // Run the message service := keeper.NewMsgServerImpl(suite.k) - _, err := service.SetPermissions(sdk.WrapSDKContext(ctx), tc.msg) + _, err := service.SetUserPermissions(sdk.WrapSDKContext(ctx), tc.msg) if tc.shouldErr { suite.Require().Error(err) diff --git a/x/subspaces/keeper/permissions.go b/x/subspaces/keeper/permissions.go index eefde55f70..26d116dfdc 100644 --- a/x/subspaces/keeper/permissions.go +++ b/x/subspaces/keeper/permissions.go @@ -6,20 +6,50 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) -// GetPermissions returns the permissions that are currently set inside -// the subspace with the given id for the given target -func (k Keeper) GetPermissions(ctx sdk.Context, subspaceID uint64, target string) types.Permission { +// SetUserPermissions sets the given permission for the specific user inside a single subspace +func (k Keeper) SetUserPermissions(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress, permissions types.Permission) { store := ctx.KVStore(k.storeKey) - return types.UnmarshalPermission(store.Get(types.PermissionStoreKey(subspaceID, target))) + store.Set(types.UserPermissionStoreKey(subspaceID, user), types.MarshalPermission(permissions)) + + k.AfterUserPermissionSet(ctx, subspaceID, user, permissions) } -// GetGroupsInheritedPermissions returns the permissions that the specified target +// HasPermission checks whether the specific user has the given permission inside a specific subspace +func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress, permission types.Permission) bool { + // Get the subspace to make sure the request is valid + subspace, found := k.GetSubspace(ctx, subspaceID) + if !found { + return false + } + + specificPermissions := k.GetUserPermissions(ctx, subspaceID, user) + + // The owner of the subspaces has all the permissions by default + if subspace.Owner == user.String() { + return true + } + + // Get the group permissions + groupPermissions := k.GetGroupsInheritedPermissions(ctx, subspaceID, user) + + // Check the combination of the permissions + return types.CheckPermission(types.CombinePermissions(specificPermissions, groupPermissions), permission) +} + +// GetUserPermissions returns the permissions that are currently set inside +// the subspace with the given id for the given user +func (k Keeper) GetUserPermissions(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress) types.Permission { + store := ctx.KVStore(k.storeKey) + return types.UnmarshalPermission(store.Get(types.UserPermissionStoreKey(subspaceID, user))) +} + +// GetGroupsInheritedPermissions returns the permissions that the specified user // has inherited from all the groups that they are part of. func (k Keeper) GetGroupsInheritedPermissions(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress) types.Permission { var permissions []types.Permission - k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, groupName string) (stop bool) { - if k.IsMemberOfGroup(ctx, subspaceID, groupName, user) { - permissions = append(permissions, k.GetPermissions(ctx, subspaceID, groupName)) + k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, group types.UserGroup) (stop bool) { + if k.IsMemberOfGroup(ctx, subspaceID, group.ID, user) { + permissions = append(permissions, group.Permissions) } return false }) @@ -40,14 +70,14 @@ func (k Keeper) GetUsersWithPermission(ctx sdk.Context, subspaceID uint64, permi } users := []sdk.AccAddress{ownerAddr} - k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, groupName string) (stop bool) { - if !k.HasPermission(ctx, subspaceID, groupName, permission) { + k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, group types.UserGroup) (stop bool) { + if !types.CheckPermission(group.Permissions, permission) { // Return early if the group does not have the permission. We will check other groups anyway return false } // If the group has the permission, get all the members - k.IterateGroupMembers(ctx, subspaceID, groupName, func(index int64, member sdk.AccAddress) (stop bool) { + k.IterateGroupMembers(ctx, subspaceID, group.ID, func(index int64, member sdk.AccAddress) (stop bool) { users = append(users, member) return false }) @@ -58,45 +88,10 @@ func (k Keeper) GetUsersWithPermission(ctx sdk.Context, subspaceID uint64, permi return users, nil } -// HasPermission checks whether the specific target has the given permission inside a specific subspace -func (k Keeper) HasPermission(ctx sdk.Context, subspaceID uint64, target string, permission types.Permission) bool { - // Get the subspace to make sure the request is valid - subspace, found := k.GetSubspace(ctx, subspaceID) - if !found { - return false - } - - specificPermissions := k.GetPermissions(ctx, subspaceID, target) - - userAddr, err := sdk.AccAddressFromBech32(target) - if err != nil { - return types.CheckPermission(specificPermissions, permission) - } - - // The owner of the subspaces has all the permissions by default - if subspace.Owner == userAddr.String() { - return true - } - - // Get the group permissions - groupPermissions := k.GetGroupsInheritedPermissions(ctx, subspaceID, userAddr) - - // Check the combination of the permissions - return types.CheckPermission(types.CombinePermissions(specificPermissions, groupPermissions), permission) -} - -// SetPermissions sets the given permission for the specific target inside a single subspace -func (k Keeper) SetPermissions(ctx sdk.Context, subspaceID uint64, target string, permissions types.Permission) { - store := ctx.KVStore(k.storeKey) - store.Set(types.PermissionStoreKey(subspaceID, target), types.MarshalPermission(permissions)) - - k.AfterPermissionSet(ctx, subspaceID, target, permissions) -} - -// RemovePermissions removes the permission for the given target inside the provided subspace -func (k Keeper) RemovePermissions(ctx sdk.Context, subspaceID uint64, target string) { +// RemoveUserPermissions removes the permission for the given user inside the provided subspace +func (k Keeper) RemoveUserPermissions(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress) { store := ctx.KVStore(k.storeKey) - store.Delete(types.PermissionStoreKey(subspaceID, target)) + store.Delete(types.UserPermissionStoreKey(subspaceID, user)) - k.AfterPermissionRemoved(ctx, subspaceID, target) + k.AfterUserPermissionRemoved(ctx, subspaceID, user) } diff --git a/x/subspaces/keeper/permissions_test.go b/x/subspaces/keeper/permissions_test.go index 9096f5202d..280e32b4a0 100644 --- a/x/subspaces/keeper/permissions_test.go +++ b/x/subspaces/keeper/permissions_test.go @@ -8,108 +8,46 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) -func (suite *KeeperTestsuite) TestKeeper_GetPermissions() { - testCases := []struct { - name string - store func(ctx sdk.Context) - subspaceID uint64 - target string - expPermissions types.Permission - }{ - { - name: "not found target returns PermissionNothing", - subspaceID: 1, - target: "", - expPermissions: types.PermissionNothing, - }, - { - name: "found user returns the correct permission", - store: func(ctx sdk.Context) { - suite.k.SetPermissions( - ctx, - 1, - "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", - types.PermissionWrite|types.PermissionManageGroups, - ) - }, - subspaceID: 1, - target: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", - expPermissions: types.PermissionWrite | types.PermissionManageGroups, - }, - { - name: "found group returns the correct permission", - store: func(ctx sdk.Context) { - suite.k.SetPermissions( - ctx, 1, "my_group", types.PermissionChangeInfo|types.PermissionSetPermissions) - }, - subspaceID: 1, - target: "my_group", - expPermissions: types.PermissionChangeInfo | types.PermissionSetPermissions, - }, - } - - for _, tc := range testCases { - tc := tc - suite.Run(tc.name, func() { - ctx, _ := suite.ctx.CacheContext() - if tc.store != nil { - tc.store(ctx) - } - - permission := suite.k.GetPermissions(ctx, tc.subspaceID, tc.target) - suite.Require().Equal(tc.expPermissions, permission) - }) - } -} - -func (suite *KeeperTestsuite) TestKeeper_GetGroupsInheritedPermissions() { +func (suite *KeeperTestsuite) TestKeeper_SetPermissions() { testCases := []struct { - name string - store func(ctx sdk.Context) - subspaceID uint64 - user string - expPermissions types.Permission + name string + store func(ctx sdk.Context) + subspaceID uint64 + user string + permission types.Permission + check func(ctx sdk.Context) }{ { - name: "user in no group returns PermissionNothing", - subspaceID: 1, - user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", - expPermissions: types.PermissionNothing, - }, - { - name: "user inside one group returns that group's permission", - store: func(ctx sdk.Context) { - suite.k.SaveUserGroup(ctx, 1, "write-group", types.PermissionWrite) - - userAddr, err := sdk.AccAddressFromBech32("cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm") - suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "write-group", userAddr) + name: "permission is set properly for user", + subspaceID: 1, + user: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", + permission: types.PermissionChangeInfo, + check: func(ctx sdk.Context) { + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") suite.Require().NoError(err) + + permission := suite.k.GetUserPermissions(ctx, 1, sdkAddr) + suite.Require().Equal(types.PermissionChangeInfo, permission) }, - subspaceID: 1, - user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", - expPermissions: types.PermissionWrite, }, { - name: "user inside multiple groups returns the combination of the various permissions", + name: "existing permission is overridden", store: func(ctx sdk.Context) { - suite.k.SaveUserGroup(ctx, 1, - "write-group", types.PermissionWrite) - suite.k.SaveUserGroup(ctx, 1, - "permission-group", types.PermissionSetPermissions|types.PermissionChangeInfo) - - userAddr, err := sdk.AccAddressFromBech32("cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm") + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "write-group", userAddr) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionManageGroups) + }, + subspaceID: 1, + user: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", + permission: types.PermissionWrite, + check: func(ctx sdk.Context) { + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "permission-group", userAddr) - suite.Require().NoError(err) + permission := suite.k.GetUserPermissions(ctx, 1, sdkAddr) + suite.Require().Equal(types.PermissionWrite, permission) }, - subspaceID: 1, - user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", - expPermissions: types.PermissionWrite | types.PermissionChangeInfo | types.PermissionSetPermissions, }, } @@ -121,11 +59,14 @@ func (suite *KeeperTestsuite) TestKeeper_GetGroupsInheritedPermissions() { tc.store(ctx) } - userAddr, err := sdk.AccAddressFromBech32(tc.user) + sdkAddr, err := sdk.AccAddressFromBech32(tc.user) suite.Require().NoError(err) - permissions := suite.k.GetGroupsInheritedPermissions(ctx, tc.subspaceID, userAddr) - suite.Require().Equal(tc.expPermissions, permissions) + suite.k.SetUserPermissions(ctx, tc.subspaceID, sdkAddr, tc.permission) + + if tc.check != nil { + tc.check(ctx) + } }) } } @@ -135,50 +76,14 @@ func (suite *KeeperTestsuite) TestKeeper_HasPermission() { name string store func(ctx sdk.Context) subspaceID uint64 - target string + user string permission types.Permission expResult bool }{ { name: "subspace not found returns false", subspaceID: 1, - expResult: false, - }, - { - name: "group with permission returns true", - store: func(ctx sdk.Context) { - suite.k.SaveSubspace(ctx, types.NewSubspace( - 1, - "Test subspace", - "This is a test subspace", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), - )) - suite.k.SetPermissions(ctx, 1, "group", types.PermissionWrite) - }, - subspaceID: 1, - target: "group", - permission: types.PermissionWrite, - expResult: true, - }, - { - name: "group without permission returns false", - store: func(ctx sdk.Context) { - suite.k.SaveSubspace(ctx, types.NewSubspace( - 1, - "Test subspace", - "This is a test subspace", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), - )) - }, - subspaceID: 1, - target: "group", - permission: types.PermissionWrite, + user: "cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", expResult: false, }, { @@ -195,7 +100,7 @@ func (suite *KeeperTestsuite) TestKeeper_HasPermission() { )) }, subspaceID: 1, - target: "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + user: "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", permission: types.PermissionEverything, expResult: true, }, @@ -212,16 +117,22 @@ func (suite *KeeperTestsuite) TestKeeper_HasPermission() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite|types.PermissionChangeInfo) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite|types.PermissionChangeInfo, + )) userAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) suite.Require().NoError(err) }, subspaceID: 1, - target: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", + user: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", permission: types.PermissionWrite, expResult: true, }, @@ -238,18 +149,24 @@ func (suite *KeeperTestsuite) TestKeeper_HasPermission() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - suite.k.SaveUserGroup(ctx, 1, "group", types.PermissionWrite|types.PermissionChangeInfo) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite|types.PermissionChangeInfo, + )) userAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") suite.Require().NoError(err) - err = suite.k.AddUserToGroup(ctx, 1, "group", userAddr) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) suite.Require().NoError(err) - suite.k.SetPermissions(ctx, 1, userAddr.String(), types.PermissionManageGroups) + suite.k.SetUserPermissions(ctx, 1, userAddr, types.PermissionManageGroups) }, subspaceID: 1, - target: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", + user: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", permission: types.PermissionManageGroups, expResult: true, }, @@ -263,53 +180,123 @@ func (suite *KeeperTestsuite) TestKeeper_HasPermission() { tc.store(ctx) } - result := suite.k.HasPermission(ctx, tc.subspaceID, tc.target, tc.permission) + sdkAddr, err := sdk.AccAddressFromBech32(tc.user) + suite.Require().NoError(err) + + result := suite.k.HasPermission(ctx, tc.subspaceID, sdkAddr, tc.permission) suite.Require().Equal(tc.expResult, result) }) } } -func (suite *KeeperTestsuite) TestKeeper_SetPermissions() { +func (suite *KeeperTestsuite) TestKeeper_GetUserPermissions() { testCases := []struct { - name string - store func(ctx sdk.Context) - subspaceID uint64 - target string - permission types.Permission - check func(ctx sdk.Context) + name string + store func(ctx sdk.Context) + subspaceID uint64 + user string + expPermissions types.Permission }{ { - name: "permission is set properly for group", - subspaceID: 1, - target: "group", - permission: types.PermissionWrite, - check: func(ctx sdk.Context) { - permission := suite.k.GetPermissions(ctx, 1, "group") - suite.Require().Equal(types.PermissionWrite, permission) - }, + name: "not found user returns PermissionNothing", + subspaceID: 1, + user: "cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", + expPermissions: types.PermissionNothing, }, { - name: "permission is set properly for user", - subspaceID: 1, - target: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", - permission: types.PermissionChangeInfo, - check: func(ctx sdk.Context) { - permission := suite.k.GetPermissions(ctx, 1, "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") - suite.Require().Equal(types.PermissionChangeInfo, permission) + name: "found user returns the correct permission", + store: func(ctx sdk.Context) { + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionWrite|types.PermissionManageGroups) }, + subspaceID: 1, + user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + expPermissions: types.PermissionWrite | types.PermissionManageGroups, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + sdkAddr, err := sdk.AccAddressFromBech32(tc.user) + suite.Require().NoError(err) + + permission := suite.k.GetUserPermissions(ctx, tc.subspaceID, sdkAddr) + suite.Require().Equal(tc.expPermissions, permission) + }) + } +} + +func (suite *KeeperTestsuite) TestKeeper_GetGroupsInheritedPermissions() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + user string + expPermissions types.Permission + }{ + { + name: "user in no group returns PermissionNothing", + subspaceID: 1, + user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + expPermissions: types.PermissionNothing, }, { - name: "existing permission is overridden", + name: "user inside one group returns that group's permission", store: func(ctx sdk.Context) { - suite.k.SetPermissions(ctx, 1, "group", types.PermissionManageGroups) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm") + suite.Require().NoError(err) + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) + suite.Require().NoError(err) }, - subspaceID: 1, - target: "group", - permission: types.PermissionWrite, - check: func(ctx sdk.Context) { - permission := suite.k.GetPermissions(ctx, 1, "group") - suite.Require().Equal(types.PermissionWrite, permission) + subspaceID: 1, + user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + expPermissions: types.PermissionWrite, + }, + { + name: "user inside multiple groups returns the combination of the various permissions", + store: func(ctx sdk.Context) { + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 2, + "Permission group", + "This is a permissions group", + types.PermissionSetPermissions|types.PermissionChangeInfo, + )) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, 1, userAddr) + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, 2, userAddr) + suite.Require().NoError(err) }, + subspaceID: 1, + user: "cosmos1fgppppwfjszpts4shpsfv7n2xtchcdwhycuvvm", + expPermissions: types.PermissionWrite | types.PermissionChangeInfo | types.PermissionSetPermissions, }, } @@ -321,41 +308,50 @@ func (suite *KeeperTestsuite) TestKeeper_SetPermissions() { tc.store(ctx) } - suite.k.SetPermissions(ctx, tc.subspaceID, tc.target, tc.permission) + userAddr, err := sdk.AccAddressFromBech32(tc.user) + suite.Require().NoError(err) - if tc.check != nil { - tc.check(ctx) - } + permissions := suite.k.GetGroupsInheritedPermissions(ctx, tc.subspaceID, userAddr) + suite.Require().Equal(tc.expPermissions, permissions) }) } } -func (suite *KeeperTestsuite) TestKeeper_RemovePermissions() { +func (suite *KeeperTestsuite) TestKeeper_RemoveUserPermissions() { testCases := []struct { name string store func(ctx sdk.Context) subspaceID uint64 - target string + user string check func(ctx sdk.Context) }{ { - name: "permission is deleted for non existing target", + name: "permission is deleted for non existing user", subspaceID: 1, - target: "group", + user: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", check: func(ctx sdk.Context) { - permission := suite.k.GetPermissions(ctx, 1, "group") + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") + suite.Require().NoError(err) + + permission := suite.k.GetUserPermissions(ctx, 1, sdkAddr) suite.Require().Equal(types.PermissionNothing, permission) }, }, { - name: "permission is deleted for existing taget", + name: "permission is deleted for existing user", store: func(ctx sdk.Context) { - suite.k.SetPermissions(ctx, 1, "group", types.PermissionManageGroups) + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") + suite.Require().NoError(err) + + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionManageGroups) }, subspaceID: 1, - target: "group", + user: "cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn", check: func(ctx sdk.Context) { - permission := suite.k.GetPermissions(ctx, 1, "group") + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1fz49f2njk28ue8geqm63g4zzsm97lahqa9vmwn") + suite.Require().NoError(err) + + permission := suite.k.GetUserPermissions(ctx, 1, sdkAddr) suite.Require().Equal(types.PermissionNothing, permission) }, }, @@ -369,7 +365,10 @@ func (suite *KeeperTestsuite) TestKeeper_RemovePermissions() { tc.store(ctx) } - suite.k.RemovePermissions(ctx, tc.subspaceID, tc.target) + sdkAddr, err := sdk.AccAddressFromBech32(tc.user) + suite.Require().NoError(err) + + suite.k.RemoveUserPermissions(ctx, tc.subspaceID, sdkAddr) if tc.check != nil { tc.check(ctx) diff --git a/x/subspaces/keeper/subspaces.go b/x/subspaces/keeper/subspaces.go index 582c763492..472e397421 100644 --- a/x/subspaces/keeper/subspaces.go +++ b/x/subspaces/keeper/subspaces.go @@ -7,6 +7,12 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) +// SetSubspaceID sets the new subspace id to the store +func (k Keeper) SetSubspaceID(ctx sdk.Context, subspaceID uint64) { + store := ctx.KVStore(k.storeKey) + store.Set(types.SubspaceIDKey, types.GetSubspaceIDBytes(subspaceID)) +} + // GetSubspaceID gets the highest subspace id func (k Keeper) GetSubspaceID(ctx sdk.Context) (subspaceID uint64, err error) { store := ctx.KVStore(k.storeKey) @@ -19,17 +25,21 @@ func (k Keeper) GetSubspaceID(ctx sdk.Context) (subspaceID uint64, err error) { return subspaceID, nil } -// SetSubspaceID sets the new subspace id to the store -func (k Keeper) SetSubspaceID(ctx sdk.Context, subspaceID uint64) { - store := ctx.KVStore(k.storeKey) - store.Set(types.SubspaceIDKey, types.GetSubspaceIDBytes(subspaceID)) -} +// -------------------------------------------------------------------------------------------------------------------- // SaveSubspace saves the given subspace inside the current context. func (k Keeper) SaveSubspace(ctx sdk.Context, subspace types.Subspace) { store := ctx.KVStore(k.storeKey) + + // Store the subspace store.Set(types.SubspaceKey(subspace.ID), k.cdc.MustMarshal(&subspace)) + // If the initial group id does not exist, create it now + groupIDKey := types.GroupIDStoreKey(subspace.ID) + if !store.Has(groupIDKey) { + store.Set(groupIDKey, types.GetGroupIDBytes(1)) + } + k.Logger(ctx).Info("subspace saved", "id", subspace.ID) k.AfterSubspaceSaved(ctx, subspace.ID) } @@ -56,9 +66,36 @@ func (k Keeper) GetSubspace(ctx sdk.Context, subspaceID uint64) (subspace types. // DeleteSubspace allows to delete the subspace with the given id func (k Keeper) DeleteSubspace(ctx sdk.Context, subspaceID uint64) { + // Delete the subspace store := ctx.KVStore(k.storeKey) store.Delete(types.SubspaceKey(subspaceID)) + // Delete the group id + store.Delete(types.GroupIDStoreKey(subspaceID)) + + // Delete all user groups + var groups []uint32 + k.IterateSubspaceGroups(ctx, subspaceID, func(_ int64, group types.UserGroup) (stop bool) { + groups = append(groups, group.ID) + return false + }) + + for _, groupID := range groups { + k.DeleteUserGroup(ctx, subspaceID, groupID) + } + + // Delete all the permissions for this subspace + var members []sdk.AccAddress + k.IterateSubspacePermissions(ctx, subspaceID, func(_ int64, user sdk.AccAddress, _ types.Permission) (stop bool) { + members = append(members, user) + return false + }) + + for _, member := range members { + k.RemoveUserPermissions(ctx, subspaceID, member) + } + + // Log the subspace deletion k.Logger(ctx).Info("subspace deleted", "id", subspaceID) k.AfterSubspaceDeleted(ctx, subspaceID) } diff --git a/x/subspaces/keeper/subspaces_test.go b/x/subspaces/keeper/subspaces_test.go index b90a1d8ac8..93ef79aa10 100644 --- a/x/subspaces/keeper/subspaces_test.go +++ b/x/subspaces/keeper/subspaces_test.go @@ -8,6 +8,43 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) +func (suite *KeeperTestsuite) TestKeeper_SetSubspaceID() { + testCases := []struct { + name string + id uint64 + check func(ctx sdk.Context) + }{ + { + name: "zero subspace id", + id: 0, + check: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + suite.Require().Equal(uint64(0), types.GetSubspaceIDFromBytes(store.Get(types.SubspaceIDKey))) + }, + }, + { + name: "non-zero subspace id", + id: 5, + check: func(ctx sdk.Context) { + store := ctx.KVStore(suite.storeKey) + suite.Require().Equal(uint64(5), types.GetSubspaceIDFromBytes(store.Get(types.SubspaceIDKey))) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + + suite.k.SetSubspaceID(ctx, tc.id) + if tc.check != nil { + tc.check(ctx) + } + }) + } +} + func (suite *KeeperTestsuite) TestKeeper_GetSubspaceID() { testCases := []struct { name string @@ -16,7 +53,7 @@ func (suite *KeeperTestsuite) TestKeeper_GetSubspaceID() { expID uint64 }{ { - name: "initial subspace not set", + name: "subspace id not set", shouldErr: true, }, { @@ -49,42 +86,7 @@ func (suite *KeeperTestsuite) TestKeeper_GetSubspaceID() { } } -func (suite *KeeperTestsuite) TestKeeper_SetSubspaceID() { - testCases := []struct { - name string - id uint64 - check func(ctx sdk.Context) - }{ - { - name: "zero subspace id", - id: 0, - check: func(ctx sdk.Context) { - store := ctx.KVStore(suite.storeKey) - suite.Require().Equal(uint64(0), types.GetSubspaceIDFromBytes(store.Get(types.SubspaceIDKey))) - }, - }, - { - name: "non-zero subspace id", - id: 5, - check: func(ctx sdk.Context) { - store := ctx.KVStore(suite.storeKey) - suite.Require().Equal(uint64(5), types.GetSubspaceIDFromBytes(store.Get(types.SubspaceIDKey))) - }, - }, - } - - for _, tc := range testCases { - tc := tc - suite.Run(tc.name, func() { - ctx, _ := suite.ctx.CacheContext() - - suite.k.SetSubspaceID(ctx, tc.id) - if tc.check != nil { - tc.check(ctx) - } - }) - } -} +// -------------------------------------------------------------------------------------------------------------------- func (suite *KeeperTestsuite) TestKeeper_SaveSubspace() { testCases := []struct { @@ -173,6 +175,51 @@ func (suite *KeeperTestsuite) TestKeeper_SaveSubspace() { } } +func (suite *KeeperTestsuite) TestKeeper_HasSubspace() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + groupID uint32 + expResult bool + }{ + { + name: "not found subspace returns false", + subspaceID: 1, + groupID: 1, + expResult: false, + }, + { + name: "found subspace returns the correct data", + store: func(ctx sdk.Context) { + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + }, + subspaceID: 1, + groupID: 1, + expResult: true, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + result := suite.k.HasUserGroup(ctx, tc.subspaceID, tc.groupID) + suite.Require().Equal(tc.expResult, result) + }) + } +} + func (suite *KeeperTestsuite) TestKeeper_GetSubspace() { testCases := []struct { name string @@ -229,3 +276,75 @@ func (suite *KeeperTestsuite) TestKeeper_GetSubspace() { }) } } + +func (suite *KeeperTestsuite) TestKeeper_DeleteSubspace() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + check func(ctx sdk.Context) + }{ + { + name: "non existing subspace is deleted properly", + subspaceID: 1, + check: func(ctx sdk.Context) { + found := suite.k.HasSubspace(ctx, 1) + suite.Require().False(found) + }, + }, + { + name: "existing subspace is deleted and all groups and permissions are removed", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionWrite) + }, + subspaceID: 1, + check: func(ctx sdk.Context) { + found := suite.k.HasSubspace(ctx, 1) + suite.Require().False(found) + + groups := suite.k.GetSubspaceGroups(ctx, 1) + suite.Require().Empty(groups) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e") + suite.Require().NoError(err) + permission := suite.k.GetUserPermissions(ctx, 1, sdkAddr) + suite.Require().Equal(types.PermissionNothing, permission) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + suite.k.DeleteSubspace(ctx, tc.subspaceID) + if tc.check != nil { + tc.check(ctx) + } + }) + } +} diff --git a/x/subspaces/simulation/decoder.go b/x/subspaces/simulation/decoder.go index 874fa6c309..792b109598 100644 --- a/x/subspaces/simulation/decoder.go +++ b/x/subspaces/simulation/decoder.go @@ -27,13 +27,22 @@ func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string { cdc.MustUnmarshal(kvB.Value, &subspaceB) return fmt.Sprintf("SubspaceA: %s\nSubspaceB: %s\n", subspaceA.String(), subspaceB.String()) + case bytes.HasPrefix(kvA.Key, types.GroupIDPrefix): + var groupIDA, groupIDB uint32 + groupIDA = types.GetGroupIDFromBytes(kvA.Value) + groupIDB = types.GetGroupIDFromBytes(kvB.Value) + return fmt.Sprintf("GroupIDA: %d\nGroupIDB: %d\n", groupIDA, groupIDB) + case bytes.HasPrefix(kvA.Key, types.GroupsPrefix): - return fmt.Sprintf("GroupKeyA: %s\nGroupKeyB: %s\n", kvA.Key, kvB.Key) + var groupA, groupB types.UserGroup + cdc.MustUnmarshal(kvA.Value, &groupA) + cdc.MustUnmarshal(kvB.Value, &groupB) + return fmt.Sprintf("GroupA: %s\nGroupB: %s\n", &groupA, &groupB) case bytes.HasPrefix(kvA.Key, types.GroupMembersStorePrefix): return fmt.Sprintf("GroupMemberKeyA: %s\nGroupMemberKeyB: %s\n", kvA.Key, kvB.Key) - case bytes.HasPrefix(kvA.Key, types.PermissionsStorePrefix): + case bytes.HasPrefix(kvA.Key, types.UserPermissionsStorePrefix): var permissionA, permissionB uint32 permissionA = types.UnmarshalPermission(kvA.Value) permissionB = types.UnmarshalPermission(kvB.Value) diff --git a/x/subspaces/simulation/decoder_test.go b/x/subspaces/simulation/decoder_test.go index bce18a1b3c..2f5eaccfdd 100644 --- a/x/subspaces/simulation/decoder_test.go +++ b/x/subspaces/simulation/decoder_test.go @@ -32,6 +32,17 @@ func TestDecodeStore(t *testing.T) { "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), ) + group := types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ) + + userAddr, err := sdk.AccAddressFromBech32("cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e") + require.NoError(t, err) + kvPairs := kv.Pairs{Pairs: []kv.Pair{ { Key: types.SubspaceIDKey, @@ -42,15 +53,15 @@ func TestDecodeStore(t *testing.T) { Value: cdc.MustMarshal(&subspace), }, { - Key: types.GroupStoreKey(1, "group"), - Value: []byte{0x01}, + Key: types.GroupStoreKey(1, 1), + Value: cdc.MustMarshal(&group), }, { - Key: types.GroupMemberStoreKey(1, "group", sdkAddr), + Key: types.GroupMemberStoreKey(1, 1, sdkAddr), Value: []byte{0x01}, }, { - Key: types.PermissionStoreKey(1, "group"), + Key: types.UserPermissionStoreKey(1, userAddr), Value: types.MarshalPermission(types.PermissionWrite), }, { @@ -67,10 +78,10 @@ func TestDecodeStore(t *testing.T) { 1, 1)}, {"Subspace", fmt.Sprintf("SubspaceA: %s\nSubspaceB: %s\n", subspace.String(), subspace.String())}, - {"Group", fmt.Sprintf("GroupKeyA: %s\nGroupKeyB: %s\n", - types.GroupStoreKey(1, "group"), types.GroupStoreKey(1, "group"))}, + {"Group", fmt.Sprintf("GroupA: %s\nGroupB: %s\n", + group.String(), group.String())}, {"Group member", fmt.Sprintf("GroupMemberKeyA: %s\nGroupMemberKeyB: %s\n", - types.GroupMemberStoreKey(1, "group", sdkAddr), types.GroupMemberStoreKey(1, "group", sdkAddr))}, + types.GroupMemberStoreKey(1, 1, sdkAddr), types.GroupMemberStoreKey(1, 1, sdkAddr))}, {"Permission", fmt.Sprintf("PermissionKeyA: %d\nPermissionKeyB: %d\n", types.PermissionWrite, types.PermissionWrite)}, {"other", ""}, diff --git a/x/subspaces/simulation/genesis.go b/x/subspaces/simulation/genesis.go index ee8ceae456..aa6d059223 100644 --- a/x/subspaces/simulation/genesis.go +++ b/x/subspaces/simulation/genesis.go @@ -16,11 +16,12 @@ import ( // RandomizeGenState generates a random GenesisState for subspaces func RandomizeGenState(simState *module.SimulationState) { subspaces := randomSubspaces(simState.Rand, simState.Accounts) - groups := randomUserGroups(simState.Rand, simState.Accounts, subspaces) - acl := randomACL(simState.Rand, simState.Accounts, subspaces, groups) + groups, members := randomUserGroups(simState.Rand, simState.Accounts, subspaces) + acl := randomACL(simState.Rand, simState.Accounts, subspaces) + initialSubspaceID, genSubspaces := getInitialIDs(subspaces, groups) // Create the genesis and sanitize it - subspacesGenesis := types.NewGenesisState(1, subspaces, groups, acl) + subspacesGenesis := types.NewGenesisState(initialSubspaceID, genSubspaces, acl, groups, members) subspacesGenesis = sanitizeGenesis(subspacesGenesis) simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(subspacesGenesis) @@ -37,11 +38,28 @@ func randomSubspaces(r *rand.Rand, accs []simtypes.Account) (subspaces []types.S } // randomUserGroups generates random slice of user group details -func randomUserGroups(r *rand.Rand, accounts []simtypes.Account, subspaces []types.Subspace) (groups []types.UserGroup) { +func randomUserGroups( + r *rand.Rand, accounts []simtypes.Account, subspaces []types.Subspace, +) (groups []types.UserGroup, membersEntries []types.UserGroupMembersEntry) { groupsNumber := r.Intn(30) + groups = make([]types.UserGroup, groupsNumber) + membersEntries = make([]types.UserGroupMembersEntry, groupsNumber) + for i := 0; i < groupsNumber; i++ { subspace, _ := RandomSubspace(r, subspaces) + groupID := uint32(i + 1) + + // Get a random permission + permission := RandomPermission(r, []types.Permission{ + types.PermissionNothing, + types.PermissionWrite, + types.PermissionManageGroups, + types.PermissionEverything, + }) + + // Build the group details + groups[i] = types.NewUserGroup(subspace.ID, groupID, RandomName(r), RandomDescription(r), permission) // Get a random number of members membersNumber := r.Intn(5) @@ -51,28 +69,51 @@ func randomUserGroups(r *rand.Rand, accounts []simtypes.Account, subspaces []typ } members = sanitizeStrings(members) - // Build the group details - groups[i] = types.NewUserGroup(subspace.ID, RandomName(r), members) + // Build the members details + membersEntries[i] = types.NewUserGroupMembersEntry(subspace.ID, groupID, members) } - return groups + return groups, membersEntries +} + +// getInitialIDs returns the initial subspace id and various initial group ids given the slice of subspaces and groups +func getInitialIDs( + subspaces []types.Subspace, groups []types.UserGroup, +) (initialSubspaceID uint64, genSubspaces []types.GenesisSubspace) { + initialGroupIDS := map[uint64]uint32{} + for _, subspace := range subspaces { + if subspace.ID > initialSubspaceID { + initialSubspaceID = subspace.ID + } + + // Get the max group id + maxGroupID := uint32(0) + for _, group := range groups { + if group.SubspaceID == subspace.ID && group.ID > maxGroupID { + maxGroupID = group.ID + } + } + + // Get the initial group id for this subspace + initialGroupIDS[subspace.ID] = maxGroupID + 1 + } + + genSubspaces = make([]types.GenesisSubspace, len(subspaces)) + for i, subspace := range subspaces { + genSubspaces[i] = types.NewGenesisSubspace(subspace, initialGroupIDS[subspace.ID]) + } + + return initialSubspaceID, genSubspaces } // randomACL generates a random slice of ACL entries -func randomACL(r *rand.Rand, accounts []simtypes.Account, subspaces []types.Subspace, groups []types.UserGroup) (entries []types.ACLEntry) { +func randomACL(r *rand.Rand, accounts []simtypes.Account, subspaces []types.Subspace) (entries []types.ACLEntry) { aclEntriesNumber := r.Intn(40) entries = make([]types.ACLEntry, aclEntriesNumber) for index := 0; index < aclEntriesNumber; index++ { subspace, _ := RandomSubspace(r, subspaces) target := RandomAccount(r, accounts).Address.String() - // 50% of chance of selecting a group rather than an account - if r.Intn(101) <= 50 { - if len(groups) > 0 { - target = RandomGroup(r, groups).Name - } - } - // Get a random permission permission := RandomPermission(r, []types.Permission{ types.PermissionNothing, @@ -96,23 +137,24 @@ func sanitizeGenesis(genesis *types.GenesisState) *types.GenesisState { return types.NewGenesisState( genesis.InitialSubspaceID, sanitizeSubspaces(genesis.Subspaces), - sanitizeUserGroups(genesis.UserGroups), sanitizeACLEntry(genesis.ACL), + sanitizeUserGroups(genesis.UserGroups), + genesis.UserGroupsMembers, ) } // sanitizeSubspaces sanitizes the given slice by removing all the double subspaces -func sanitizeSubspaces(slice []types.Subspace) []types.Subspace { +func sanitizeSubspaces(slice []types.GenesisSubspace) []types.GenesisSubspace { ids := map[uint64]int{} for _, value := range slice { - ids[value.ID] = 1 + ids[value.Subspace.ID] = 1 } - var unique []types.Subspace + var unique []types.GenesisSubspace for id := range ids { SubspaceLoop: for _, subspace := range slice { - if id == subspace.ID { + if id == subspace.Subspace.ID { unique = append(unique, subspace) break SubspaceLoop } @@ -147,14 +189,14 @@ func sanitizeUserGroups(slice []types.UserGroup) []types.UserGroup { func sanitizeACLEntry(slice []types.ACLEntry) []types.ACLEntry { entries := map[string]int{} for _, value := range slice { - entries[fmt.Sprintf("%d%s", value.SubspaceID, value.Target)] = 1 + entries[fmt.Sprintf("%d%s", value.SubspaceID, value.User)] = 1 } var unique []types.ACLEntry for id := range entries { EntryLoop: for _, entry := range slice { - if id == fmt.Sprintf("%d%s", entry.SubspaceID, entry.Target) { + if id == fmt.Sprintf("%d%s", entry.SubspaceID, entry.User) { unique = append(unique, entry) break EntryLoop } diff --git a/x/subspaces/simulation/operations.go b/x/subspaces/simulation/operations.go index 2b6538b7f0..46f55b902a 100644 --- a/x/subspaces/simulation/operations.go +++ b/x/subspaces/simulation/operations.go @@ -22,10 +22,12 @@ const ( OpWeightMsgEditSubspace = "op_weight_msg_edit_subspace" OpWeightMsgDeleteSubspace = "op_weight_msg_delete_subspace" OpWeightMsgCreateUserGroup = "op_weight_msg_create_user_group" + OpWeightMsgEditUserGroup = "op_weight_msg_edit_user_group" + OpWeightMsgSetUserGroupPermissions = "op_weight_msg_set_user_group_permissions" OpWeightMsgDeleteUserGroup = "op_weight_msg_delete_user_group" OpWeightMsgAddUserToUserGroup = "op_weight_msg_add_user_to_user_group" OpWeightMsgRemoveUserFromUserGroup = "op_weight_msg_remove_user_from_user_group" - OpWeightMsgSetPermissions = "op_weight_msg_set_permissions" + OpWeightMsgSetUserPermissions = "op_weight_msg_set_user_permissions" DefaultGasValue = 200_000 ) @@ -64,6 +66,20 @@ func WeightedOperations( }, ) + var weightMsgEditUserGroup int + appParams.GetOrGenerate(cdc, OpWeightMsgEditUserGroup, &weightMsgEditUserGroup, nil, + func(_ *rand.Rand) { + weightMsgEditUserGroup = params.DefaultWeightMsgEditUserGroup + }, + ) + + var weightMsgSetUserGroupPermissions int + appParams.GetOrGenerate(cdc, OpWeightMsgSetUserGroupPermissions, &weightMsgSetUserGroupPermissions, nil, + func(_ *rand.Rand) { + weightMsgSetUserGroupPermissions = params.DefaultWeightMsgSetUserGroupPermissions + }, + ) + var weightMsgDeleteUserGroup int appParams.GetOrGenerate(cdc, OpWeightMsgDeleteUserGroup, &weightMsgDeleteUserGroup, nil, func(_ *rand.Rand) { @@ -85,10 +101,10 @@ func WeightedOperations( }, ) - var weightMsgSetPermissions int - appParams.GetOrGenerate(cdc, OpWeightMsgSetPermissions, &weightMsgSetPermissions, nil, + var weightMsgSetUserPermissions int + appParams.GetOrGenerate(cdc, OpWeightMsgSetUserPermissions, &weightMsgSetUserPermissions, nil, func(_ *rand.Rand) { - weightMsgSetPermissions = params.DefaultWeightMsgSetPermissions + weightMsgSetUserPermissions = params.DefaultWeightMsgSetUserPermissions }, ) @@ -109,6 +125,14 @@ func WeightedOperations( weightMsgCreateUserGroup, SimulateMsgCreateUserGroup(k, ak, bk), ), + sim.NewWeightedOperation( + weightMsgEditUserGroup, + SimulateMsgEditUserGroup(k, ak, bk), + ), + sim.NewWeightedOperation( + weightMsgSetUserGroupPermissions, + SimulateMsgSetUserGroupPermissions(k, ak, bk), + ), sim.NewWeightedOperation( weightMsgDeleteUserGroup, SimulateMsgDeleteUserGroup(k, ak, bk), @@ -122,8 +146,8 @@ func WeightedOperations( SimulateMsgRemoveUserFromUserGroup(k, ak, bk), ), sim.NewWeightedOperation( - weightMsgSetPermissions, - SimulateMsgSetPermissions(k, ak, bk), + weightMsgSetUserPermissions, + SimulateMsgSetUserPermissions(k, ak, bk), ), } } diff --git a/x/subspaces/simulation/operations_groups.go b/x/subspaces/simulation/operations_groups.go index 26f46a218f..b467b3aaf4 100644 --- a/x/subspaces/simulation/operations_groups.go +++ b/x/subspaces/simulation/operations_groups.go @@ -24,13 +24,19 @@ func SimulateMsgCreateUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { // Get the data - subspaceID, groupName, permissions, creator, skip := randomCreateUserGroupFields(r, ctx, accs, k) + subspaceID, update, permissions, creator, skip := randomCreateUserGroupFields(r, ctx, accs, k) if skip { return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgCreateUserGroup"), nil, nil } // Build the message - msg := types.NewMsgCreateUserGroup(subspaceID, groupName, permissions, creator.Address.String()) + msg := types.NewMsgCreateUserGroup( + subspaceID, + update.Name, + update.Description, + permissions, + creator.Address.String(), + ) // Send the message err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{creator.PrivKey}) @@ -45,7 +51,7 @@ func SimulateMsgCreateUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk // randomCreateUserGroupFields returns the data used to build a random MsgCreateUserGroup func randomCreateUserGroupFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, -) (subspaceID uint64, groupName string, permissions types.Permission, account simtypes.Account, skip bool) { +) (subspaceID uint64, update *types.GroupUpdate, permissions types.Permission, account simtypes.Account, skip bool) { // Get a subspace id subspaces := k.GetAllSubspaces(ctx) if len(subspaces) == 0 { @@ -57,12 +63,8 @@ func randomCreateUserGroupFields( subspaceID = subspace.ID // Get a group name - groupName = RandomName(r) - if k.HasUserGroup(ctx, subspaceID, groupName) { - // Skip if the group already exists - skip = true - return - } + groupName := RandomName(r) + groupDescription := RandomDescription(r) // Get a default permission permissions = RandomPermission(r, []types.Permission{ @@ -81,7 +83,146 @@ func randomCreateUserGroupFields( } account = *acc - return subspaceID, groupName, permissions, account, false + return subspaceID, types.NewGroupUpdate(groupName, groupDescription), permissions, account, false +} + +// -------------------------------------------------------------------------------------------------------------------- + +// SimulateMsgEditUserGroup tests and runs a single MsgEditUserGroup +func SimulateMsgEditUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspaceID, groupID, update, signer, skip := randomEditUserGroupFields(r, ctx, accs, k) + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgEditUserGroup"), nil, nil + } + + // Build the message + msg := types.NewMsgEditUserGroup(subspaceID, groupID, update.Name, update.Description, signer.Address.String()) + + // Send the message + err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{signer.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgEditUserGroup"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgEditUserGroup", nil), nil, nil + } +} + +// randomEditUserGroupFields returns the data used to build a random MsgEditUserGroup +func randomEditUserGroupFields( + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, +) (subspaceID uint64, groupID uint32, update *types.GroupUpdate, account simtypes.Account, skip bool) { + // Get a group + groups := k.GetAllUserGroups(ctx) + if len(groups) == 0 { + // Skip if there are no groups + skip = true + return + } + group := RandomGroup(r, groups) + subspaceID = group.SubspaceID + groupID = group.ID + + // Build the update + update = types.NewGroupUpdate(RandomName(r), RandomDescription(r)) + if r.Intn(101) < 50 { + // 50% of chance of not editing the name + update.Name = types.DoNotModify + } + if r.Intn(101) < 50 { + // 50% of chance of not editing the description + update.Description = types.DoNotModify + } + + // Get a signer + signers, _ := k.GetUsersWithPermission(ctx, subspaceID, types.PermissionManageGroups) + acc := GetAccount(RandomAddress(r, signers), accs) + if acc == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + account = *acc + + return subspaceID, groupID, update, account, false +} + +// -------------------------------------------------------------------------------------------------------------------- + +// SimulateMsgSetUserGroupPermissions tests and runs a single MsgSetUserGroupPermissions +func SimulateMsgSetUserGroupPermissions(k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { + return func( + r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, + accs []simtypes.Account, chainID string, + ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { + + // Get the data + subspaceID, groupID, permissions, signer, skip := randomSetUserGroupPermissionsFields(r, ctx, accs, k) + if skip { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgSetUserGroupPermissions"), nil, nil + } + + // Build the message + msg := types.NewMsgSetUserGroupPermissions(subspaceID, groupID, permissions, signer.Address.String()) + + // Send the message + err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{signer.PrivKey}) + if err != nil { + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgSetUserGroupPermissions"), nil, err + } + + return simtypes.NewOperationMsg(msg, true, "MsgSetUserGroupPermissions", nil), nil, nil + } +} + +// randomSetUserGroupPermissionsFields returns the data used to build a random MsgSetUserGroupPermissions +func randomSetUserGroupPermissionsFields( + r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, +) (subspaceID uint64, groupID uint32, permissions types.Permission, account simtypes.Account, skip bool) { + // Get a subspace id + subspaces := k.GetAllSubspaces(ctx) + if len(subspaces) == 0 { + // Skip because there are no subspaces + skip = true + return + } + subspace, _ := RandomSubspace(r, subspaces) + subspaceID = subspace.ID + + // Get a group + groups := k.GetSubspaceGroups(ctx, subspaceID) + if len(groups) == 0 { + // Skip if there are no groups + skip = true + return + } + groupID = RandomGroup(r, groups).ID + + // Get a permission + permissions = RandomPermission(r, []types.Permission{ + types.PermissionWrite, + types.PermissionModerateContent, + types.PermissionChangeInfo, + types.PermissionManageGroups, + }) + + // Get a signer + signers, _ := k.GetUsersWithPermission(ctx, subspace.ID, types.PermissionSetPermissions) + acc := GetAccount(RandomAddress(r, signers), accs) + if acc == nil { + // Skip the operation without error as the account is not valid + skip = true + return + } + account = *acc + + return subspaceID, groupID, permissions, account, false } // -------------------------------------------------------------------------------------------------------------------- @@ -94,13 +235,13 @@ func SimulateMsgDeleteUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { // Get the data - subspaceID, groupName, signer, skip := randomDeleteUserGroupFields(r, ctx, accs, k) + subspaceID, groupID, signer, skip := randomDeleteUserGroupFields(r, ctx, accs, k) if skip { return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgDeleteUserGroup"), nil, nil } // Build the message - msg := types.NewMsgDeleteUserGroup(subspaceID, groupName, signer.Address.String()) + msg := types.NewMsgDeleteUserGroup(subspaceID, groupID, signer.Address.String()) // Send the message err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{signer.PrivKey}) @@ -115,7 +256,7 @@ func SimulateMsgDeleteUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, bk // randomDeleteUserGroupFields returns the data used to build a random MsgDeleteUserGroup func randomDeleteUserGroupFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, -) (subspaceID uint64, groupName string, account simtypes.Account, skip bool) { +) (subspaceID uint64, groupID uint32, account simtypes.Account, skip bool) { // Get a group groups := k.GetAllUserGroups(ctx) if len(groups) == 0 { @@ -125,7 +266,7 @@ func randomDeleteUserGroupFields( } group := RandomGroup(r, groups) subspaceID = group.SubspaceID - groupName = group.Name + groupID = group.ID // Get a signer signers, _ := k.GetUsersWithPermission(ctx, subspaceID, types.PermissionManageGroups) @@ -137,7 +278,7 @@ func randomDeleteUserGroupFields( } account = *acc - return subspaceID, groupName, account, false + return subspaceID, groupID, account, false } // -------------------------------------------------------------------------------------------------------------------- @@ -150,13 +291,13 @@ func SimulateMsgAddUserToUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { // Get the data - subspaceID, groupName, user, signer, skip := randomAddUserToUserGroupFields(r, ctx, accs, k, ak) + subspaceID, groupID, user, signer, skip := randomAddUserToUserGroupFields(r, ctx, accs, k, ak) if skip { return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgAddUserToUserGroup"), nil, nil } // Build the message - msg := types.NewMsgAddUserToUserGroup(subspaceID, groupName, user, signer.Address.String()) + msg := types.NewMsgAddUserToUserGroup(subspaceID, groupID, user, signer.Address.String()) // Send the message err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{signer.PrivKey}) @@ -171,7 +312,7 @@ func SimulateMsgAddUserToUserGroup(k keeper.Keeper, ak authkeeper.AccountKeeper, // randomAddUserToUserGroupFields returns the data used to build a random MsgAddUserToUserGroup func randomAddUserToUserGroupFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, ak authkeeper.AccountKeeper, -) (subspaceID uint64, groupName string, user string, account simtypes.Account, skip bool) { +) (subspaceID uint64, groupID uint32, user string, account simtypes.Account, skip bool) { // Get a group groups := k.GetAllUserGroups(ctx) if len(groups) == 0 { @@ -181,12 +322,12 @@ func randomAddUserToUserGroupFields( } group := RandomGroup(r, groups) subspaceID = group.SubspaceID - groupName = group.Name + groupID = group.ID // Get a user accounts := ak.GetAllAccounts(ctx) userAccount := RandomAuthAccount(r, accounts) - if k.IsMemberOfGroup(ctx, subspaceID, groupName, userAccount.GetAddress()) { + if k.IsMemberOfGroup(ctx, subspaceID, groupID, userAccount.GetAddress()) { // Skip if the user is already part of group skip = true return @@ -203,7 +344,7 @@ func randomAddUserToUserGroupFields( } account = *acc - return subspaceID, groupName, user, account, false + return subspaceID, groupID, user, account, false } // -------------------------------------------------------------------------------------------------------------------- @@ -216,13 +357,13 @@ func SimulateMsgRemoveUserFromUserGroup(k keeper.Keeper, ak authkeeper.AccountKe ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { // Get the data - subspaceID, groupName, user, signer, skip := randomRemoveUserFromUserGroupFields(r, ctx, accs, k) + subspaceID, groupID, user, signer, skip := randomRemoveUserFromUserGroupFields(r, ctx, accs, k) if skip { return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgRemoveUserFromUserGroup"), nil, nil } // Build the message - msg := types.NewMsgRemoveUserFromUserGroup(subspaceID, groupName, user, signer.Address.String()) + msg := types.NewMsgRemoveUserFromUserGroup(subspaceID, groupID, user, signer.Address.String()) // Send the message err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{signer.PrivKey}) @@ -237,7 +378,7 @@ func SimulateMsgRemoveUserFromUserGroup(k keeper.Keeper, ak authkeeper.AccountKe // randomRemoveUserFromUserGroupFields returns the data used to build a random MsgRemoveUserFromUserGroup func randomRemoveUserFromUserGroupFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, -) (subspaceID uint64, groupName string, user string, account simtypes.Account, skip bool) { +) (subspaceID uint64, groupID uint32, user string, account simtypes.Account, skip bool) { // Get a group groups := k.GetAllUserGroups(ctx) if len(groups) == 0 { @@ -247,10 +388,10 @@ func randomRemoveUserFromUserGroupFields( } group := RandomGroup(r, groups) subspaceID = group.SubspaceID - groupName = group.Name + groupID = group.ID // Get a user - members := k.GetGroupMembers(ctx, subspaceID, groupName) + members := k.GetGroupMembers(ctx, subspaceID, groupID) if len(members) == 0 { // Skip if there are no member groups to remove skip = true @@ -269,5 +410,5 @@ func randomRemoveUserFromUserGroupFields( } account = *acc - return subspaceID, groupName, user, account, false + return subspaceID, groupID, user, account, false } diff --git a/x/subspaces/simulation/operations_permissions.go b/x/subspaces/simulation/operations_permissions.go index f7440fc73c..ad302c68b7 100644 --- a/x/subspaces/simulation/operations_permissions.go +++ b/x/subspaces/simulation/operations_permissions.go @@ -16,34 +16,34 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) -// SimulateMsgSetPermissions tests and runs a single MsgSetPermissions -func SimulateMsgSetPermissions(k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { +// SimulateMsgSetUserPermissions tests and runs a single MsgSetUserPermissions +func SimulateMsgSetUserPermissions(k keeper.Keeper, ak authkeeper.AccountKeeper, bk bankkeeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, ) (simtypes.OperationMsg, []simtypes.FutureOperation, error) { // Get the data - subspaceID, target, permissions, creator, skip := randomSetPermissionsFields(r, ctx, accs, k) + subspaceID, user, permissions, creator, skip := randomSetUserPermissionsFields(r, ctx, accs, k) if skip { - return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgSetPermissions"), nil, nil + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgSetUserPermissions"), nil, nil } // Build the message - msg := types.NewMsgSetPermissions(subspaceID, target, permissions, creator.Address.String()) + msg := types.NewMsgSetUserPermissions(subspaceID, user, permissions, creator.Address.String()) // Send the message err := simtesting.SendMsg(r, app, ak, bk, msg, ctx, chainID, DefaultGasValue, []cryptotypes.PrivKey{creator.PrivKey}) if err != nil { - return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgSetPermissions"), nil, err + return simtypes.NoOpMsg(types.RouterKey, types.ModuleName, "MsgSetUserPermissions"), nil, err } - return simtypes.NewOperationMsg(msg, true, "MsgSetPermissions", nil), nil, nil + return simtypes.NewOperationMsg(msg, true, "MsgSetUserPermissions", nil), nil, nil } } -// randomSetPermissionsFields returns the data used to build a random MsgSetPermissions -func randomSetPermissionsFields( +// randomSetUserPermissionsFields returns the data used to build a random MsgSetUserPermissions +func randomSetUserPermissionsFields( r *rand.Rand, ctx sdk.Context, accs []simtypes.Account, k keeper.Keeper, ) (subspaceID uint64, target string, permissions types.Permission, account simtypes.Account, skip bool) { // Get a subspace id @@ -57,12 +57,11 @@ func randomSetPermissionsFields( subspaceID = subspace.ID // Get a target - targets := make([]string, len(accs)) + users := make([]string, len(accs)) for i, acc := range accs { - targets[i] = acc.Address.String() + users[i] = acc.Address.String() } - targets = append(targets, k.GetSubspaceGroups(ctx, subspace.ID)...) - target = RandomString(r, targets) + target = RandomString(r, users) // Get a permission permissions = RandomPermission(r, []types.Permission{ diff --git a/x/subspaces/simulation/operations_subspaces.go b/x/subspaces/simulation/operations_subspaces.go index a26448cf61..5bc0eb988e 100644 --- a/x/subspaces/simulation/operations_subspaces.go +++ b/x/subspaces/simulation/operations_subspaces.go @@ -145,6 +145,22 @@ func randomEditSubspaceFields( account.Address.String(), account.Address.String(), ) + if r.Intn(101) < 50 { + // 50% of chance of not editing the name + update.Name = types.DoNotModify + } + if r.Intn(101) < 50 { + // 50% of chance of not editing the description + update.Description = types.DoNotModify + } + if r.Intn(101) < 50 { + // 50% of chance of not editing the treasury + update.Treasury = types.DoNotModify + } + if r.Intn(101) < 50 { + // 50% of chance of not editing the owner + update.Owner = types.DoNotModify + } return subspaceID, update, account, false } diff --git a/x/subspaces/simulation/utils.go b/x/subspaces/simulation/utils.go index 47bcb427fc..898b34a794 100644 --- a/x/subspaces/simulation/utils.go +++ b/x/subspaces/simulation/utils.go @@ -14,6 +14,11 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) +// RandomGenesisSubspace picks a random genesis subspace from the given slice +func RandomGenesisSubspace(r *rand.Rand, subspaces []types.GenesisSubspace) types.GenesisSubspace { + return subspaces[r.Intn(len(subspaces))] +} + // RandomSubspace picks a random subspace from an array and returns its position as well as value. func RandomSubspace(r *rand.Rand, subspaces []types.Subspace) (types.Subspace, int) { idx := r.Intn(len(subspaces)) diff --git a/x/subspaces/types/codec.go b/x/subspaces/types/codec.go index 894b3ecf19..8807c40ffa 100644 --- a/x/subspaces/types/codec.go +++ b/x/subspaces/types/codec.go @@ -11,10 +11,12 @@ func RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { cdc.RegisterConcrete(MsgCreateSubspace{}, "desmos/MsgCreateSubspace", nil) cdc.RegisterConcrete(MsgEditSubspace{}, "desmos/MsgEditSubspace", nil) cdc.RegisterConcrete(MsgCreateUserGroup{}, "desmos/MsgCreateUserGroup", nil) + cdc.RegisterConcrete(MsgEditUserGroup{}, "desmos/MsgEditUserGroup", nil) + cdc.RegisterConcrete(MsgSetUserGroupPermissions{}, "desmos/MsgSetUserGroupPermissions", nil) cdc.RegisterConcrete(MsgDeleteUserGroup{}, "desmos/MsgDeleteUserGroup", nil) cdc.RegisterConcrete(MsgAddUserToUserGroup{}, "desmos/MsgAddUserToUserGroup", nil) cdc.RegisterConcrete(MsgRemoveUserFromUserGroup{}, "desmos/MsgRemoveUserFromUserGroup", nil) - cdc.RegisterConcrete(MsgSetPermissions{}, "desmos/MsgSetPermissions", nil) + cdc.RegisterConcrete(MsgSetUserPermissions{}, "desmos/MsgSetUserPermissions", nil) } func RegisterInterfaces(registry types.InterfaceRegistry) { @@ -22,10 +24,12 @@ func RegisterInterfaces(registry types.InterfaceRegistry) { &MsgCreateSubspace{}, &MsgEditSubspace{}, &MsgCreateUserGroup{}, + &MsgEditUserGroup{}, + &MsgSetUserGroupPermissions{}, &MsgDeleteUserGroup{}, &MsgAddUserToUserGroup{}, &MsgRemoveUserFromUserGroup{}, - &MsgSetPermissions{}, + &MsgSetUserPermissions{}, ) msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) diff --git a/x/subspaces/types/events.go b/x/subspaces/types/events.go index 1c9ce65ca4..cb0df1d9cd 100644 --- a/x/subspaces/types/events.go +++ b/x/subspaces/types/events.go @@ -2,21 +2,22 @@ package types // Subspaces module event types const ( - EventTypeCreateSubspace = "create_subspace" - EventTypeEditSubspace = "edit_subspace" - EventTypeDeleteSubspace = "delete_subspace" - EventTypeCreateUserGroup = "create_user_group" - EventTypeDeleteUserGroup = "delete_user_group" - EventTypeAddUserToGroup = "add_group_member" - EventTypeRemoveUserFromGroup = "delete_group_member" - EventTypeSetPermissions = "set_permissions" + EventTypeCreateSubspace = "create_subspace" + EventTypeEditSubspace = "edit_subspace" + EventTypeDeleteSubspace = "delete_subspace" + EventTypeCreateUserGroup = "create_user_group" + EventTypeEditUserGroup = "edit_user_group" + EventTypeSetUserGroupPermissions = "set_user_group_permissions" + EventTypeDeleteUserGroup = "delete_user_group" + EventTypeAddUserToGroup = "add_group_member" + EventTypeRemoveUserFromGroup = "remove_group_member" + EventTypeSetUserPermissions = "set_user_permissions" AttributeValueCategory = ModuleName AttributeKeySubspaceID = "subspace_id" AttributeKeySubspaceName = "subspace_name" AttributeKeySubspaceCreator = "subspace_creator" AttributeKeyCreationTime = "creation_date" - AttributeKeyUserGroupName = "user_group_name" + AttributeKeyUserGroupID = "user_group_id" AttributeKeyUser = "user" - AttributeKeyTarget = "target" ) diff --git a/x/subspaces/types/genesis.go b/x/subspaces/types/genesis.go index cfa2e1314d..8dfea38fcd 100644 --- a/x/subspaces/types/genesis.go +++ b/x/subspaces/types/genesis.go @@ -2,16 +2,34 @@ package types import ( "fmt" - "strings" sdk "github.com/cosmos/cosmos-sdk/types" ) +// NewGenesisSubspace returns a new GenesisSubspace instance +func NewGenesisSubspace(subspace Subspace, initialGroupID uint32) GenesisSubspace { + return GenesisSubspace{ + Subspace: subspace, + InitialGroupID: initialGroupID, + } +} + +// Validate returns an error if something is wrong within the subspace data +func (subspace GenesisSubspace) Validate() error { + if subspace.InitialGroupID == 0 { + return fmt.Errorf("invalid initial group id: %d", subspace.InitialGroupID) + } + + return subspace.Subspace.Validate() +} + +// ------------------------------------------------------------------------------------------------------------------- + // NewACLEntry returns a new ACLEntry instance -func NewACLEntry(subspaceID uint64, target string, permissions Permission) ACLEntry { +func NewACLEntry(subspaceID uint64, user string, permissions Permission) ACLEntry { return ACLEntry{ SubspaceID: subspaceID, - Target: target, + User: user, Permissions: permissions, } } @@ -22,32 +40,39 @@ func (entry ACLEntry) Validate() error { return fmt.Errorf("invalid subspace id: %d", entry.SubspaceID) } + _, err := sdk.AccAddressFromBech32(entry.User) + if err != nil { + return fmt.Errorf("invalid user address: %s", entry.User) + } + return nil } -// NewUserGroup returns a new UserGroup instance -func NewUserGroup(subspaceID uint64, groupName string, members []string) UserGroup { - return UserGroup{ +// ------------------------------------------------------------------------------------------------------------------- + +// NewUserGroupMembersEntry returns a new UserGroupMembersEntry instance +func NewUserGroupMembersEntry(subspaceID uint64, groupID uint32, members []string) UserGroupMembersEntry { + return UserGroupMembersEntry{ SubspaceID: subspaceID, - Name: groupName, + GroupID: groupID, Members: members, } } -// Validate returns an error if something is wrong within the group data -func (group UserGroup) Validate() error { - if group.SubspaceID == 0 { - return fmt.Errorf("invalid subspace id: %d", group.SubspaceID) +// Validate returns an error if something is wrong within the entry data +func (entry UserGroupMembersEntry) Validate() error { + if entry.SubspaceID == 0 { + return fmt.Errorf("invalid subspace id: %d", entry.SubspaceID) } - if strings.TrimSpace(group.Name) == "" { - return fmt.Errorf("invalid group name: %s", group.Name) + if entry.GroupID == 0 { + return fmt.Errorf("invalid group id: %d", entry.GroupID) } - for _, member := range group.Members { - _, err := sdk.AccAddressFromBech32(member) + for _, user := range entry.Members { + _, err := sdk.AccAddressFromBech32(user) if err != nil { - return fmt.Errorf("invalid group member address: %s", member) + return fmt.Errorf("invalid user address: %s", user) } } @@ -57,26 +82,34 @@ func (group UserGroup) Validate() error { // ------------------------------------------------------------------------------------------------------------------- // NewGenesisState creates a new genesis state -func NewGenesisState(initialSubspaceID uint64, subspaces []Subspace, userGroups []UserGroup, acl []ACLEntry) *GenesisState { +func NewGenesisState( + initialSubspaceID uint64, subspaces []GenesisSubspace, acl []ACLEntry, + userGroups []UserGroup, userGroupMembers []UserGroupMembersEntry, +) *GenesisState { return &GenesisState{ InitialSubspaceID: initialSubspaceID, Subspaces: subspaces, - UserGroups: userGroups, ACL: acl, + UserGroups: userGroups, + UserGroupsMembers: userGroupMembers, } } // DefaultGenesisState returns a default GenesisState func DefaultGenesisState() *GenesisState { - return NewGenesisState(1, nil, nil, nil) + return NewGenesisState(1, nil, nil, nil, nil) } +// ------------------------------------------------------------------------------------------------------------------- + // ValidateGenesis validates the given genesis state and returns an error if something is invalid func ValidateGenesis(data *GenesisState) error { - if data.InitialSubspaceID == 0 { - return fmt.Errorf("initial subspace id must be greter than 0") + // Make sure the initial subspace id is valid + if data.InitialSubspaceID <= uint64(len(data.Subspaces)) { + return fmt.Errorf("invalid initial subspace id: %d", data.InitialSubspaceID) } + // Validate the subspace for _, subspace := range data.Subspaces { err := subspace.Validate() if err != nil { @@ -84,14 +117,11 @@ func ValidateGenesis(data *GenesisState) error { } if containsDuplicatedSubspace(data.Subspaces, subspace) { - return fmt.Errorf("duplicated subspace: %d", subspace.ID) + return fmt.Errorf("duplicated subspace: %d", subspace.Subspace.ID) } } - if data.InitialSubspaceID < uint64(len(data.Subspaces)) { - return fmt.Errorf("initial subspace id must be equals or greter than subspaces count") - } - + // Validate the ACL entries for _, entry := range data.ACL { err := entry.Validate() if err != nil { @@ -99,10 +129,18 @@ func ValidateGenesis(data *GenesisState) error { } if containsDuplicatedACLEntry(data.ACL, entry) { - return fmt.Errorf("duplicated ACL entry for subspace %d: %s", entry.SubspaceID, entry.Target) + return fmt.Errorf("duplicated ACL entry for subspace %d and user %s", entry.SubspaceID, entry.User) + } + + // Make sure the associated subspace exists + subspace, found := findSubspace(data.Subspaces, entry.SubspaceID) + if !found { + return fmt.Errorf("invalid ACL entry: subspace %d not found", subspace.Subspace.ID) } } + // Validate the user groups + groupsCount := map[uint64]int{} for _, group := range data.UserGroups { err := group.Validate() if err != nil { @@ -110,19 +148,72 @@ func ValidateGenesis(data *GenesisState) error { } if containsDuplicatedGroups(data.UserGroups, group) { - return fmt.Errorf("duplicated group for subspace %d: %s", group.SubspaceID, group.Name) + return fmt.Errorf("duplicated group for subspace %d and group %d", group.SubspaceID, group.ID) + } + + groupsCount[group.SubspaceID] = groupsCount[group.SubspaceID] + 1 + } + + // Make sure each subspace has a correct initial group id based on the number of groups inside that subspace + for subspaceID, count := range groupsCount { + genSub, found := findSubspace(data.Subspaces, subspaceID) + if !found { + return fmt.Errorf("invalid group id: subspace %d not found", subspaceID) + } + + if genSub.InitialGroupID <= uint32(count) { + return fmt.Errorf("invalid initial group id for subspace %d: %d", genSub.Subspace.ID, genSub.InitialGroupID) + } + } + + // Validate the group members + for _, entry := range data.UserGroupsMembers { + err := entry.Validate() + if err != nil { + return err + } + + if containsDuplicatedMembersEntries(data.UserGroupsMembers, entry) { + return fmt.Errorf("duplicated user group members entry for group %d within subspace %d", entry.GroupID, entry.SubspaceID) + } + + // Make sure the associated subspace exists + _, found := findGroup(data.UserGroups, entry.SubspaceID, entry.GroupID) + if !found { + return fmt.Errorf("invalid group members entry: group %d for subspace %d not found", + entry.GroupID, entry.SubspaceID) } } return nil } +// findSubspace searches the subspace with the given id inside the provided slice +func findSubspace(subspaces []GenesisSubspace, subspaceID uint64) (genSub GenesisSubspace, found bool) { + for _, subspace := range subspaces { + if subspace.Subspace.ID == subspaceID { + return subspace, true + } + } + return GenesisSubspace{}, false +} + +// findGroup searches the group for the group having the given id and subspace id inside the given slice +func findGroup(groups []UserGroup, subspaceID uint64, groupID uint32) (group UserGroup, found bool) { + for _, group := range groups { + if group.SubspaceID == subspaceID && group.ID == groupID { + return group, true + } + } + return UserGroup{}, false +} + // containsDuplicatedSubspace tells whether the given subspaces slice contains two or more // subspaces with the same id of the given subspace -func containsDuplicatedSubspace(subspaces []Subspace, subspace Subspace) bool { +func containsDuplicatedSubspace(subspaces []GenesisSubspace, subspace GenesisSubspace) bool { var count = 0 for _, s := range subspaces { - if s.ID == subspace.ID { + if s.Subspace.ID == subspace.Subspace.ID { count++ } } @@ -130,11 +221,11 @@ func containsDuplicatedSubspace(subspaces []Subspace, subspace Subspace) bool { } // containsDuplicatedACLEntry tells whether the given entries slice contains two or more -// entries for the same target and subspace +// entries for the same user and subspace func containsDuplicatedACLEntry(entries []ACLEntry, entry ACLEntry) bool { var count = 0 for _, e := range entries { - if e.SubspaceID == entry.SubspaceID && e.Target == entry.Target { + if e.SubspaceID == entry.SubspaceID && e.User == entry.User { count++ } } @@ -146,7 +237,19 @@ func containsDuplicatedACLEntry(entries []ACLEntry, entry ACLEntry) bool { func containsDuplicatedGroups(groups []UserGroup, group UserGroup) bool { var count = 0 for _, g := range groups { - if g.SubspaceID == group.SubspaceID && g.Name == group.Name { + if g.SubspaceID == group.SubspaceID && g.ID == group.ID { + count++ + } + } + return count > 1 +} + +// containsDuplicatedMembersEntries tells whether the given entries slice contains two or more +// entries for the same subspace and group id +func containsDuplicatedMembersEntries(entries []UserGroupMembersEntry, entry UserGroupMembersEntry) bool { + var count = 0 + for _, e := range entries { + if e.SubspaceID == entry.SubspaceID && e.GroupID == entry.GroupID { count++ } } diff --git a/x/subspaces/types/genesis.pb.go b/x/subspaces/types/genesis.pb.go index 2bc69d64be..9d4aeb2357 100644 --- a/x/subspaces/types/genesis.pb.go +++ b/x/subspaces/types/genesis.pb.go @@ -25,10 +25,11 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState contains the data of the genesis state for the subspaces module type GenesisState struct { - InitialSubspaceID uint64 `protobuf:"varint,1,opt,name=initial_subspace_id,json=initialSubspaceId,proto3" json:"initial_subspace_id,omitempty"` - Subspaces []Subspace `protobuf:"bytes,2,rep,name=subspaces,proto3" json:"subspaces"` - ACL []ACLEntry `protobuf:"bytes,3,rep,name=acl,proto3" json:"acl"` - UserGroups []UserGroup `protobuf:"bytes,4,rep,name=user_groups,json=userGroups,proto3" json:"user_groups"` + InitialSubspaceID uint64 `protobuf:"varint,1,opt,name=initial_subspace_id,json=initialSubspaceId,proto3" json:"initial_subspace_id,omitempty"` + Subspaces []GenesisSubspace `protobuf:"bytes,2,rep,name=subspaces,proto3" json:"subspaces"` + ACL []ACLEntry `protobuf:"bytes,3,rep,name=acl,proto3" json:"acl"` + UserGroups []UserGroup `protobuf:"bytes,4,rep,name=user_groups,json=userGroups,proto3" json:"user_groups"` + UserGroupsMembers []UserGroupMembersEntry `protobuf:"bytes,5,rep,name=user_groups_members,json=userGroupsMembers,proto3" json:"user_groups_members"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -71,7 +72,7 @@ func (m *GenesisState) GetInitialSubspaceID() uint64 { return 0 } -func (m *GenesisState) GetSubspaces() []Subspace { +func (m *GenesisState) GetSubspaces() []GenesisSubspace { if m != nil { return m.Subspaces } @@ -92,11 +93,70 @@ func (m *GenesisState) GetUserGroups() []UserGroup { return nil } +func (m *GenesisState) GetUserGroupsMembers() []UserGroupMembersEntry { + if m != nil { + return m.UserGroupsMembers + } + return nil +} + +// GenesisSubspace contains the genesis data for a single subspace +type GenesisSubspace struct { + Subspace Subspace `protobuf:"bytes,1,opt,name=subspace,proto3" json:"subspace"` + InitialGroupID uint32 `protobuf:"varint,2,opt,name=initial_group_id,json=initialGroupId,proto3" json:"initial_group_id,omitempty"` +} + +func (m *GenesisSubspace) Reset() { *m = GenesisSubspace{} } +func (m *GenesisSubspace) String() string { return proto.CompactTextString(m) } +func (*GenesisSubspace) ProtoMessage() {} +func (*GenesisSubspace) Descriptor() ([]byte, []int) { + return fileDescriptor_bce8af665337782b, []int{1} +} +func (m *GenesisSubspace) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisSubspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisSubspace.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *GenesisSubspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisSubspace.Merge(m, src) +} +func (m *GenesisSubspace) XXX_Size() int { + return m.Size() +} +func (m *GenesisSubspace) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisSubspace.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisSubspace proto.InternalMessageInfo + +func (m *GenesisSubspace) GetSubspace() Subspace { + if m != nil { + return m.Subspace + } + return Subspace{} +} + +func (m *GenesisSubspace) GetInitialGroupID() uint32 { + if m != nil { + return m.InitialGroupID + } + return 0 +} + // ACLEntry represents a single Access Control List entry type ACLEntry struct { - SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` - // Either a group name or user address - Target string `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty"` + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` + User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty"` Permissions uint32 `protobuf:"varint,3,opt,name=permissions,proto3" json:"permissions,omitempty"` } @@ -104,7 +164,7 @@ func (m *ACLEntry) Reset() { *m = ACLEntry{} } func (m *ACLEntry) String() string { return proto.CompactTextString(m) } func (*ACLEntry) ProtoMessage() {} func (*ACLEntry) Descriptor() ([]byte, []int) { - return fileDescriptor_bce8af665337782b, []int{1} + return fileDescriptor_bce8af665337782b, []int{2} } func (m *ACLEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -140,9 +200,9 @@ func (m *ACLEntry) GetSubspaceID() uint64 { return 0 } -func (m *ACLEntry) GetTarget() string { +func (m *ACLEntry) GetUser() string { if m != nil { - return m.Target + return m.User } return "" } @@ -154,25 +214,25 @@ func (m *ACLEntry) GetPermissions() uint32 { return 0 } -// UserGroup contains the data of a single user group present inside a subspace -type UserGroup struct { +// UserGroupMembersEntry contains all the members of a specific user group +type UserGroupMembersEntry struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty"` - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + GroupID uint32 `protobuf:"varint,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` Members []string `protobuf:"bytes,3,rep,name=members,proto3" json:"members,omitempty"` } -func (m *UserGroup) Reset() { *m = UserGroup{} } -func (m *UserGroup) String() string { return proto.CompactTextString(m) } -func (*UserGroup) ProtoMessage() {} -func (*UserGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_bce8af665337782b, []int{2} +func (m *UserGroupMembersEntry) Reset() { *m = UserGroupMembersEntry{} } +func (m *UserGroupMembersEntry) String() string { return proto.CompactTextString(m) } +func (*UserGroupMembersEntry) ProtoMessage() {} +func (*UserGroupMembersEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_bce8af665337782b, []int{3} } -func (m *UserGroup) XXX_Unmarshal(b []byte) error { +func (m *UserGroupMembersEntry) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *UserGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *UserGroupMembersEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_UserGroup.Marshal(b, m, deterministic) + return xxx_messageInfo_UserGroupMembersEntry.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -182,33 +242,33 @@ func (m *UserGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { return b[:n], nil } } -func (m *UserGroup) XXX_Merge(src proto.Message) { - xxx_messageInfo_UserGroup.Merge(m, src) +func (m *UserGroupMembersEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_UserGroupMembersEntry.Merge(m, src) } -func (m *UserGroup) XXX_Size() int { +func (m *UserGroupMembersEntry) XXX_Size() int { return m.Size() } -func (m *UserGroup) XXX_DiscardUnknown() { - xxx_messageInfo_UserGroup.DiscardUnknown(m) +func (m *UserGroupMembersEntry) XXX_DiscardUnknown() { + xxx_messageInfo_UserGroupMembersEntry.DiscardUnknown(m) } -var xxx_messageInfo_UserGroup proto.InternalMessageInfo +var xxx_messageInfo_UserGroupMembersEntry proto.InternalMessageInfo -func (m *UserGroup) GetSubspaceID() uint64 { +func (m *UserGroupMembersEntry) GetSubspaceID() uint64 { if m != nil { return m.SubspaceID } return 0 } -func (m *UserGroup) GetName() string { +func (m *UserGroupMembersEntry) GetGroupID() uint32 { if m != nil { - return m.Name + return m.GroupID } - return "" + return 0 } -func (m *UserGroup) GetMembers() []string { +func (m *UserGroupMembersEntry) GetMembers() []string { if m != nil { return m.Members } @@ -217,41 +277,48 @@ func (m *UserGroup) GetMembers() []string { func init() { proto.RegisterType((*GenesisState)(nil), "desmos.subspaces.v1.GenesisState") + proto.RegisterType((*GenesisSubspace)(nil), "desmos.subspaces.v1.GenesisSubspace") proto.RegisterType((*ACLEntry)(nil), "desmos.subspaces.v1.ACLEntry") - proto.RegisterType((*UserGroup)(nil), "desmos.subspaces.v1.UserGroup") + proto.RegisterType((*UserGroupMembersEntry)(nil), "desmos.subspaces.v1.UserGroupMembersEntry") } func init() { proto.RegisterFile("desmos/subspaces/v1/genesis.proto", fileDescriptor_bce8af665337782b) } var fileDescriptor_bce8af665337782b = []byte{ - // 420 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x4d, 0x8b, 0xd3, 0x50, - 0x14, 0xed, 0x6b, 0xca, 0x38, 0xbd, 0x51, 0x61, 0xde, 0xa8, 0x84, 0x01, 0x93, 0xd8, 0x55, 0x37, - 0xe6, 0x31, 0x75, 0x27, 0x6e, 0xda, 0xb1, 0x0c, 0x03, 0x5d, 0x65, 0x70, 0xe3, 0xa6, 0x24, 0xed, - 0x23, 0x3e, 0x68, 0xf2, 0xc2, 0xbb, 0x2f, 0xc5, 0x59, 0xf9, 0x17, 0x5c, 0xba, 0x9c, 0x9d, 0x7f, - 0x65, 0x96, 0x5d, 0xba, 0x2a, 0x92, 0x6e, 0xfc, 0x19, 0x92, 0xaf, 0x36, 0x68, 0x11, 0xdc, 0xdd, - 0x8f, 0x73, 0xee, 0x39, 0x1c, 0x2e, 0xbc, 0x5a, 0x72, 0x8c, 0x25, 0x32, 0xcc, 0x42, 0x4c, 0x83, - 0x05, 0x47, 0xb6, 0xbe, 0x64, 0x11, 0x4f, 0x38, 0x0a, 0xf4, 0x52, 0x25, 0xb5, 0xa4, 0xe7, 0x15, - 0xc4, 0xdb, 0x43, 0xbc, 0xf5, 0xe5, 0xc5, 0xb3, 0x48, 0x46, 0xb2, 0xdc, 0xb3, 0xa2, 0xaa, 0xa0, - 0x17, 0x83, 0x63, 0xd7, 0x9a, 0xa6, 0xc2, 0x0c, 0xbe, 0x77, 0xe1, 0xf1, 0x75, 0x25, 0x70, 0xab, - 0x03, 0xcd, 0xe9, 0x14, 0xce, 0x45, 0x22, 0xb4, 0x08, 0x56, 0xf3, 0x06, 0x3a, 0x17, 0x4b, 0x8b, - 0xb8, 0x64, 0xd8, 0x9b, 0x3c, 0xcf, 0xb7, 0xce, 0xd9, 0x4d, 0xb5, 0xbe, 0xad, 0xb7, 0x37, 0xef, - 0xfd, 0x33, 0xf1, 0xc7, 0x68, 0x49, 0xc7, 0xd0, 0xdf, 0xcb, 0x5a, 0x5d, 0xd7, 0x18, 0x9a, 0xa3, - 0x97, 0xde, 0x11, 0xeb, 0x5e, 0xc3, 0x99, 0xf4, 0x1e, 0xb6, 0x4e, 0xc7, 0x3f, 0xb0, 0xe8, 0x3b, - 0x30, 0x82, 0xc5, 0xca, 0x32, 0xfe, 0x41, 0x1e, 0x5f, 0xcd, 0xa6, 0x89, 0x56, 0x77, 0x13, 0xb3, - 0x20, 0xe7, 0x5b, 0xc7, 0x18, 0x5f, 0xcd, 0xfc, 0x82, 0x46, 0xa7, 0x60, 0x66, 0xc8, 0xd5, 0x3c, - 0x52, 0x32, 0x4b, 0xd1, 0xea, 0x95, 0x57, 0xec, 0xa3, 0x57, 0x3e, 0x20, 0x57, 0xd7, 0x05, 0xac, - 0xf6, 0x00, 0x59, 0x33, 0xc0, 0xb7, 0xa7, 0xdf, 0xee, 0x1d, 0xf2, 0xeb, 0xde, 0x21, 0x83, 0x2f, - 0x70, 0xda, 0xc8, 0x51, 0x06, 0xe6, 0xdf, 0xe1, 0x3c, 0xcd, 0xb7, 0x0e, 0xb4, 0x52, 0x01, 0x3c, - 0xc4, 0xf1, 0x02, 0x4e, 0x74, 0xa0, 0x22, 0xae, 0xad, 0xae, 0x4b, 0x86, 0x7d, 0xbf, 0xee, 0xa8, - 0x0b, 0x66, 0xca, 0x55, 0x2c, 0x10, 0x85, 0x4c, 0xd0, 0x32, 0x5c, 0x32, 0x7c, 0xe2, 0xb7, 0x47, - 0x2d, 0x03, 0x1a, 0xfa, 0x7b, 0xa7, 0xff, 0xef, 0x80, 0x42, 0x2f, 0x09, 0x62, 0x5e, 0xeb, 0x97, - 0x35, 0xb5, 0xe0, 0x51, 0xcc, 0xe3, 0x90, 0x2b, 0x2c, 0x53, 0xee, 0xfb, 0x4d, 0x7b, 0x50, 0x9d, - 0xcc, 0x1e, 0x72, 0x9b, 0x6c, 0x72, 0x9b, 0xfc, 0xcc, 0x6d, 0xf2, 0x75, 0x67, 0x77, 0x36, 0x3b, - 0xbb, 0xf3, 0x63, 0x67, 0x77, 0x3e, 0x8e, 0x22, 0xa1, 0x3f, 0x65, 0xa1, 0xb7, 0x90, 0x31, 0xab, - 0x62, 0x7d, 0xbd, 0x0a, 0x42, 0xac, 0x6b, 0xb6, 0x1e, 0xb1, 0xcf, 0xad, 0xd7, 0xd3, 0x77, 0x29, - 0xc7, 0xf0, 0xa4, 0xfc, 0xba, 0x37, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x14, 0x3f, 0x01, 0x14, - 0xe9, 0x02, 0x00, 0x00, + // 513 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0xcf, 0x8b, 0xd3, 0x40, + 0x14, 0xc7, 0x3b, 0x9b, 0x6a, 0xdb, 0x17, 0xad, 0x76, 0xea, 0x42, 0x58, 0x30, 0xa9, 0x8b, 0x48, + 0x11, 0x4c, 0xd8, 0x7a, 0x93, 0x05, 0xd9, 0xec, 0x96, 0xb5, 0x50, 0x2f, 0x59, 0xbc, 0x78, 0xa9, + 0x49, 0x33, 0xc4, 0x81, 0xa6, 0x09, 0x99, 0xa4, 0xb8, 0xf8, 0x4f, 0xec, 0xc1, 0x83, 0x78, 0xda, + 0x3f, 0x67, 0x8f, 0x7b, 0xf4, 0x14, 0x24, 0xbd, 0xf8, 0x67, 0x48, 0x26, 0x99, 0x36, 0xd4, 0x28, + 0xec, 0x6d, 0xe6, 0xfd, 0xf8, 0xbc, 0xef, 0xbc, 0xf7, 0x06, 0x9e, 0xb9, 0x84, 0xf9, 0x01, 0x33, + 0x58, 0xe2, 0xb0, 0xd0, 0x9e, 0x13, 0x66, 0xac, 0x8e, 0x0c, 0x8f, 0x2c, 0x09, 0xa3, 0x4c, 0x0f, + 0xa3, 0x20, 0x0e, 0x70, 0xbf, 0x08, 0xd1, 0x37, 0x21, 0xfa, 0xea, 0xe8, 0xe0, 0x89, 0x17, 0x78, + 0x01, 0xf7, 0x1b, 0xf9, 0xa9, 0x08, 0x3d, 0x18, 0xd4, 0xd1, 0xfc, 0xc0, 0x25, 0x8b, 0x12, 0x76, + 0x78, 0x25, 0xc1, 0x83, 0xf3, 0x02, 0x7f, 0x11, 0xdb, 0x31, 0xc1, 0x63, 0xe8, 0xd3, 0x25, 0x8d, + 0xa9, 0xbd, 0x98, 0x89, 0xac, 0x19, 0x75, 0x15, 0x34, 0x40, 0xc3, 0xa6, 0xb9, 0x9f, 0xa5, 0x5a, + 0x6f, 0x52, 0xb8, 0x2f, 0x4a, 0xef, 0xe4, 0xcc, 0xea, 0xd1, 0x1d, 0x93, 0x8b, 0xdf, 0x41, 0x67, + 0x53, 0x54, 0xd9, 0x1b, 0x48, 0x43, 0x79, 0xf4, 0x5c, 0xaf, 0x11, 0xae, 0x8b, 0xe2, 0xa5, 0xcd, + 0x6c, 0xde, 0xa4, 0x5a, 0xc3, 0xda, 0x26, 0xe3, 0x63, 0x90, 0xec, 0xf9, 0x42, 0x91, 0x38, 0xe3, + 0x69, 0x2d, 0xe3, 0xe4, 0x74, 0x3a, 0x5e, 0xc6, 0xd1, 0xa5, 0x29, 0xe7, 0xc9, 0x59, 0xaa, 0x49, + 0x27, 0xa7, 0x53, 0x2b, 0x4f, 0xc3, 0x63, 0x90, 0x13, 0x46, 0xa2, 0x99, 0x17, 0x05, 0x49, 0xc8, + 0x94, 0x26, 0xa7, 0xa8, 0xb5, 0x94, 0x0f, 0x8c, 0x44, 0xe7, 0x79, 0x58, 0xa9, 0x01, 0x12, 0x61, + 0x60, 0xf8, 0x13, 0xf4, 0x2b, 0x98, 0x99, 0x4f, 0x7c, 0x87, 0x44, 0x4c, 0xb9, 0xc7, 0x71, 0x2f, + 0xff, 0x8f, 0x7b, 0x5f, 0x04, 0x17, 0x0a, 0x0b, 0x74, 0x6f, 0x8b, 0x2e, 0xbd, 0x6f, 0xda, 0xdf, + 0xaf, 0x35, 0xf4, 0xfb, 0x5a, 0x43, 0x87, 0x3f, 0x10, 0x3c, 0xda, 0xe9, 0x0a, 0x7e, 0x0b, 0x6d, + 0x01, 0xe7, 0xa3, 0xf8, 0x57, 0x27, 0x76, 0xda, 0xb8, 0x49, 0xc2, 0xc7, 0xf0, 0x58, 0x8c, 0x95, + 0xbf, 0x21, 0x9f, 0xe9, 0xde, 0x00, 0x0d, 0x1f, 0x9a, 0x38, 0x4b, 0xb5, 0x6e, 0x39, 0x53, 0x2e, + 0x69, 0x72, 0x66, 0x75, 0x69, 0xf5, 0xee, 0x56, 0xc4, 0x7d, 0x85, 0xb6, 0xe8, 0x36, 0x36, 0x40, + 0xfe, 0x7b, 0x45, 0xba, 0x59, 0xaa, 0x41, 0x65, 0x37, 0x80, 0x6d, 0x97, 0x02, 0x43, 0x33, 0x7f, + 0x38, 0x2f, 0xdc, 0xb1, 0xf8, 0x19, 0x0f, 0x40, 0x0e, 0x49, 0xe4, 0x53, 0xc6, 0x68, 0xb0, 0x64, + 0x8a, 0x94, 0x6b, 0xb2, 0xaa, 0xa6, 0x4a, 0xf1, 0x6f, 0x08, 0xf6, 0x6b, 0xdb, 0x7a, 0x77, 0x29, + 0x2f, 0xa0, 0xbd, 0xd3, 0x07, 0x39, 0x4b, 0xb5, 0x96, 0x68, 0x40, 0xcb, 0x2b, 0x5e, 0x8e, 0x15, + 0x68, 0x89, 0x61, 0xe7, 0x1b, 0xd8, 0xb1, 0xc4, 0x75, 0x2b, 0xcb, 0x9c, 0xde, 0x64, 0x2a, 0xba, + 0xcd, 0x54, 0xf4, 0x2b, 0x53, 0xd1, 0xd5, 0x5a, 0x6d, 0xdc, 0xae, 0xd5, 0xc6, 0xcf, 0xb5, 0xda, + 0xf8, 0x38, 0xf2, 0x68, 0xfc, 0x39, 0x71, 0xf4, 0x79, 0xe0, 0x1b, 0xc5, 0xb8, 0x5e, 0x2d, 0x6c, + 0x87, 0x95, 0x67, 0x63, 0x35, 0x32, 0xbe, 0x54, 0xfe, 0x66, 0x7c, 0x19, 0x12, 0xe6, 0xdc, 0xe7, + 0x1f, 0xf3, 0xf5, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x21, 0xfd, 0x5d, 0x3a, 0x0a, 0x04, 0x00, + 0x00, } func (this *GenesisState) Equal(that interface{}) bool { @@ -300,6 +367,41 @@ func (this *GenesisState) Equal(that interface{}) bool { return false } } + if len(this.UserGroupsMembers) != len(that1.UserGroupsMembers) { + return false + } + for i := range this.UserGroupsMembers { + if !this.UserGroupsMembers[i].Equal(&that1.UserGroupsMembers[i]) { + return false + } + } + return true +} +func (this *GenesisSubspace) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*GenesisSubspace) + if !ok { + that2, ok := that.(GenesisSubspace) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.Subspace.Equal(&that1.Subspace) { + return false + } + if this.InitialGroupID != that1.InitialGroupID { + return false + } return true } func (this *ACLEntry) Equal(that interface{}) bool { @@ -324,7 +426,7 @@ func (this *ACLEntry) Equal(that interface{}) bool { if this.SubspaceID != that1.SubspaceID { return false } - if this.Target != that1.Target { + if this.User != that1.User { return false } if this.Permissions != that1.Permissions { @@ -332,14 +434,14 @@ func (this *ACLEntry) Equal(that interface{}) bool { } return true } -func (this *UserGroup) Equal(that interface{}) bool { +func (this *UserGroupMembersEntry) Equal(that interface{}) bool { if that == nil { return this == nil } - that1, ok := that.(*UserGroup) + that1, ok := that.(*UserGroupMembersEntry) if !ok { - that2, ok := that.(UserGroup) + that2, ok := that.(UserGroupMembersEntry) if ok { that1 = &that2 } else { @@ -354,7 +456,7 @@ func (this *UserGroup) Equal(that interface{}) bool { if this.SubspaceID != that1.SubspaceID { return false } - if this.Name != that1.Name { + if this.GroupID != that1.GroupID { return false } if len(this.Members) != len(that1.Members) { @@ -387,6 +489,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.UserGroupsMembers) > 0 { + for iNdEx := len(m.UserGroupsMembers) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.UserGroupsMembers[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } if len(m.UserGroups) > 0 { for iNdEx := len(m.UserGroups) - 1; iNdEx >= 0; iNdEx-- { { @@ -437,6 +553,44 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *GenesisSubspace) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *GenesisSubspace) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisSubspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.InitialGroupID != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.InitialGroupID)) + i-- + dAtA[i] = 0x10 + } + { + size, err := m.Subspace.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *ACLEntry) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -462,10 +616,10 @@ func (m *ACLEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x18 } - if len(m.Target) > 0 { - i -= len(m.Target) - copy(dAtA[i:], m.Target) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Target))) + if len(m.User) > 0 { + i -= len(m.User) + copy(dAtA[i:], m.User) + i = encodeVarintGenesis(dAtA, i, uint64(len(m.User))) i-- dAtA[i] = 0x12 } @@ -477,7 +631,7 @@ func (m *ACLEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *UserGroup) Marshal() (dAtA []byte, err error) { +func (m *UserGroupMembersEntry) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -487,12 +641,12 @@ func (m *UserGroup) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *UserGroup) MarshalTo(dAtA []byte) (int, error) { +func (m *UserGroupMembersEntry) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *UserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *UserGroupMembersEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -506,12 +660,10 @@ func (m *UserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0x1a } } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintGenesis(dAtA, i, uint64(len(m.Name))) + if m.GroupID != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.GroupID)) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x10 } if m.SubspaceID != 0 { i = encodeVarintGenesis(dAtA, i, uint64(m.SubspaceID)) @@ -559,6 +711,26 @@ func (m *GenesisState) Size() (n int) { n += 1 + l + sovGenesis(uint64(l)) } } + if len(m.UserGroupsMembers) > 0 { + for _, e := range m.UserGroupsMembers { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func (m *GenesisSubspace) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Subspace.Size() + n += 1 + l + sovGenesis(uint64(l)) + if m.InitialGroupID != 0 { + n += 1 + sovGenesis(uint64(m.InitialGroupID)) + } return n } @@ -571,7 +743,7 @@ func (m *ACLEntry) Size() (n int) { if m.SubspaceID != 0 { n += 1 + sovGenesis(uint64(m.SubspaceID)) } - l = len(m.Target) + l = len(m.User) if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } @@ -581,7 +753,7 @@ func (m *ACLEntry) Size() (n int) { return n } -func (m *UserGroup) Size() (n int) { +func (m *UserGroupMembersEntry) Size() (n int) { if m == nil { return 0 } @@ -590,9 +762,8 @@ func (m *UserGroup) Size() (n int) { if m.SubspaceID != 0 { n += 1 + sovGenesis(uint64(m.SubspaceID)) } - l = len(m.Name) - if l > 0 { - n += 1 + l + sovGenesis(uint64(l)) + if m.GroupID != 0 { + n += 1 + sovGenesis(uint64(m.GroupID)) } if len(m.Members) > 0 { for _, s := range m.Members { @@ -686,7 +857,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Subspaces = append(m.Subspaces, Subspace{}) + m.Subspaces = append(m.Subspaces, GenesisSubspace{}) if err := m.Subspaces[len(m.Subspaces)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } @@ -759,6 +930,142 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field UserGroupsMembers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.UserGroupsMembers = append(m.UserGroupsMembers, UserGroupMembersEntry{}) + if err := m.UserGroupsMembers[len(m.UserGroupsMembers)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *GenesisSubspace) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: GenesisSubspace: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisSubspace: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subspace", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Subspace.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InitialGroupID", wireType) + } + m.InitialGroupID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.InitialGroupID |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) @@ -830,7 +1137,7 @@ func (m *ACLEntry) Unmarshal(dAtA []byte) error { } case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -858,7 +1165,7 @@ func (m *ACLEntry) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Target = string(dAtA[iNdEx:postIndex]) + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 0 { @@ -900,7 +1207,7 @@ func (m *ACLEntry) Unmarshal(dAtA []byte) error { } return nil } -func (m *UserGroup) Unmarshal(dAtA []byte) error { +func (m *UserGroupMembersEntry) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -923,10 +1230,10 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserGroup: wiretype end group for non-group") + return fmt.Errorf("proto: UserGroupMembersEntry: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: UserGroupMembersEntry: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -949,10 +1256,10 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupID", wireType) } - var stringLen uint64 + m.GroupID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenesis @@ -962,24 +1269,11 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.GroupID |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthGenesis - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthGenesis - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Members", wireType) diff --git a/x/subspaces/types/genesis_test.go b/x/subspaces/types/genesis_test.go index 4e319f306f..b30ea808a1 100644 --- a/x/subspaces/types/genesis_test.go +++ b/x/subspaces/types/genesis_test.go @@ -19,19 +19,19 @@ func TestACLEntry_Validate(t *testing.T) { name: "invalid subspace id returns error", entry: types.NewACLEntry( 0, - "group", + "cosmos19gz9jn5pl6ke6qg5s4gt9ga9my7w8a0x3ar0qy", types.PermissionWrite, ), shouldErr: true, }, { - name: "valid group entry returns no error", + name: "invalid user returns no error", entry: types.NewACLEntry( 1, - "group", + "cosmos19gz9jn5pl6ke6", types.PermissionWrite, ), - shouldErr: false, + shouldErr: true, }, { name: "valid user entry returns no error", @@ -57,33 +57,36 @@ func TestACLEntry_Validate(t *testing.T) { } } -func TestUserGroup_Validate(t *testing.T) { +// ------------------------------------------------------------------------------------------------------------------- + +func TestUserGroupMembersEntry_Validate(t *testing.T) { testCases := []struct { name string - group types.UserGroup + entry types.UserGroupMembersEntry shouldErr bool }{ { name: "invalid subspace id returns error", - group: types.NewUserGroup(0, "group", nil), + entry: types.NewUserGroupMembersEntry(0, 1, nil), shouldErr: true, }, { - name: "invalid group name returns error", - group: types.NewUserGroup(1, "", nil), + name: "invalid group id returns error", + entry: types.NewUserGroupMembersEntry(1, 0, nil), shouldErr: true, }, { name: "invalid member returns error", - group: types.NewUserGroup(1, "group", []string{ - "another-group", + entry: types.NewUserGroupMembersEntry(1, 1, []string{ + "invalid-user", }), shouldErr: true, }, { - name: "valid group returns no error", - group: types.NewUserGroup(1, "group", []string{ - "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + name: "valid entry returns no error", + entry: types.NewUserGroupMembersEntry(1, 1, []string{ + "cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", + "cosmos19gz9jn5pl6ke6qg5s4gt9ga9my7w8a0x3ar0qy", }), shouldErr: false, }, @@ -92,7 +95,7 @@ func TestUserGroup_Validate(t *testing.T) { for _, tc := range testCases { tc := tc t.Run(tc.name, func(t *testing.T) { - err := tc.group.Validate() + err := tc.entry.Validate() if tc.shouldErr { require.Error(t, err) } else { @@ -102,6 +105,8 @@ func TestUserGroup_Validate(t *testing.T) { } } +// ------------------------------------------------------------------------------------------------------------------- + func TestValidateGenesis(t *testing.T) { testCases := []struct { name string @@ -109,85 +114,98 @@ func TestValidateGenesis(t *testing.T) { shouldErr bool }{ { - name: "invalid subspace id returns error (zero)", - genesis: types.NewGenesisState(0, nil, nil, nil), - shouldErr: true, - }, - { - name: "invalid subspace id returns error (too low)", + name: "invalid initial subspace id returns error", genesis: types.NewGenesisState( - 1, - []types.Subspace{ - types.NewSubspace( - 1, - "", - "This is a test subspace", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, ), - types.NewSubspace( - 1, - "Another test subspace", - "This is another test subspace", - "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", - "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", - "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + types.NewGenesisSubspace( + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, ), }, nil, nil, + nil, ), shouldErr: true, }, { name: "invalid subspace returns error", genesis: types.NewGenesisState( - 1, - []types.Subspace{ - types.NewSubspace( - 1, - "", - "This is a test subspace", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 0, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, ), }, nil, nil, + nil, ), shouldErr: true, }, { name: "duplicated subspace returns error", genesis: types.NewGenesisState( - 3, - []types.Subspace{ - types.NewSubspace( - 1, - "This is a test subspace", - "This is a test subspace", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, ), - types.NewSubspace( - 1, - "Another test subspace", - "This is another test subspace", - "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", - "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", - "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "Another test subspace", + "This is another test subspace", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + "cosmos1vkuuth0rak58x36m7wuzj7ztttxh26fhqcfxm0", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, ), }, nil, nil, + nil, ), shouldErr: true, }, @@ -196,33 +214,95 @@ func TestValidateGenesis(t *testing.T) { genesis: types.NewGenesisState( 1, nil, - nil, []types.ACLEntry{ types.NewACLEntry(0, "group", types.PermissionWrite), }, + nil, + nil, ), shouldErr: true, }, { name: "duplicated ACL entry returns error", genesis: types.NewGenesisState( - 1, + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, + []types.ACLEntry{ + types.NewACLEntry(1, "cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd", types.PermissionWrite), + types.NewACLEntry(1, "cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd", types.PermissionSetPermissions), + }, nil, nil, + ), + shouldErr: true, + }, + { + name: "ACL entry without subspace returns error", + genesis: types.NewGenesisState( + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, []types.ACLEntry{ - types.NewACLEntry(1, "group", types.PermissionWrite), - types.NewACLEntry(1, "group", types.PermissionSetPermissions), + types.NewACLEntry(1, "cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd", types.PermissionWrite), + types.NewACLEntry(2, "cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd", types.PermissionSetPermissions), }, + nil, + nil, ), shouldErr: true, }, { name: "invalid group returns error", genesis: types.NewGenesisState( - 1, + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, nil, []types.UserGroup{ - types.NewUserGroup(0, "group", nil), + types.NewUserGroup( + 1, + 0, + "Test group", + "This is a test group", + types.PermissionWrite, + ), }, nil, ), @@ -230,17 +310,218 @@ func TestValidateGenesis(t *testing.T) { }, { name: "duplicated group returns error", + genesis: types.NewGenesisState( + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, + nil, + []types.UserGroup{ + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + }, + nil, + ), + shouldErr: true, + }, + { + name: "group without subspace returns error", + genesis: types.NewGenesisState( + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, + nil, + []types.UserGroup{ + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + types.NewUserGroup( + 1, + 2, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + }, + nil, + ), + shouldErr: true, + }, + { + name: "invalid initial group id returns error", genesis: types.NewGenesisState( 1, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, nil, []types.UserGroup{ - types.NewUserGroup(1, "group", nil), - types.NewUserGroup(1, "group", nil), + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), }, nil, ), shouldErr: true, }, + { + name: "invalid group members entry returns error", + genesis: types.NewGenesisState( + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, + nil, + []types.UserGroup{ + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + }, + []types.UserGroupMembersEntry{ + types.NewUserGroupMembersEntry(1, 0, nil), + }, + ), + shouldErr: true, + }, + { + name: "duplicated group members entry returns error", + genesis: types.NewGenesisState( + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, + nil, + []types.UserGroup{ + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + }, + []types.UserGroupMembersEntry{ + types.NewUserGroupMembersEntry(1, 1, nil), + types.NewUserGroupMembersEntry(1, 1, nil), + }, + ), + shouldErr: true, + }, + { + name: "group members entry without group returns error", + genesis: types.NewGenesisState( + 2, + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "This is a test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 1, + ), + }, + nil, + []types.UserGroup{ + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + }, + []types.UserGroupMembersEntry{ + types.NewUserGroupMembersEntry(1, 1, nil), + types.NewUserGroupMembersEntry(1, 2, nil), + }, + ), + shouldErr: true, + }, { name: "default genesis returns no error", genesis: types.DefaultGenesisState(), @@ -250,39 +531,61 @@ func TestValidateGenesis(t *testing.T) { name: "valid genesis state returns no error", genesis: types.NewGenesisState( 3, - []types.Subspace{ - types.NewSubspace( - 1, - "Test subspace", - "This is a test subspace", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", - time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + []types.GenesisSubspace{ + types.NewGenesisSubspace( + types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + ), + 2, ), - types.NewSubspace( + types.NewGenesisSubspace( + types.NewSubspace( + 2, + "Another test subspace", + "This is another test subspace", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", + time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), + ), 2, - "Another test subspace", - "This is another test subspace", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", - time.Date(2020, 1, 2, 12, 00, 00, 000, time.UTC), ), }, + []types.ACLEntry{ + types.NewACLEntry(1, "cosmos19gz9jn5pl6ke6qg5s4gt9ga9my7w8a0x3ar0qy", types.PermissionWrite), + types.NewACLEntry(2, "cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", types.PermissionManageGroups), + }, []types.UserGroup{ - types.NewUserGroup(1, "group", []string{ + types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + types.NewUserGroup( + 2, + 1, + "Another test group", + "This is another test group", + types.PermissionWrite, + ), + }, + []types.UserGroupMembersEntry{ + types.NewUserGroupMembersEntry(1, 1, []string{ "cosmos1a0cj0j6ujn2xap8p40y6648d0w2npytw3xvenm", }), - types.NewUserGroup(2, "another-group", []string{ + types.NewUserGroupMembersEntry(2, 1, []string{ "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", }), }, - []types.ACLEntry{ - types.NewACLEntry(1, "group", types.PermissionWrite), - types.NewACLEntry(2, "another-group", types.PermissionManageGroups), - }, ), shouldErr: false, }, diff --git a/x/subspaces/types/hooks.go b/x/subspaces/types/hooks.go index 5c4fb3557c..b4fafe3efe 100644 --- a/x/subspaces/types/hooks.go +++ b/x/subspaces/types/hooks.go @@ -15,13 +15,13 @@ type SubspacesHooks interface { AfterSubspaceSaved(ctx sdk.Context, subspaceID uint64) // Must be called when a subspace is saved AfterSubspaceDeleted(ctx sdk.Context, subspaceID uint64) // Must be called when a subspace is deleted - AfterSubspaceGroupSaved(ctx sdk.Context, subspaceID uint64, groupName string) // Must be called when a subspace group is created - AfterSubspaceGroupMemberAdded(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) // Must be called when a user is added to a group - AfterSubspaceGroupMemberRemoved(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) // Must be called when a user is removed from a group - AfterSubspaceGroupDeleted(ctx sdk.Context, subspaceID uint64, groupName string) // Must be called when a subspace group is deleted + AfterSubspaceGroupSaved(ctx sdk.Context, subspaceID uint64, groupID uint32) // Must be called when a subspace group is created + AfterSubspaceGroupMemberAdded(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) // Must be called when a user is added to a group + AfterSubspaceGroupMemberRemoved(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) // Must be called when a user is removed from a group + AfterSubspaceGroupDeleted(ctx sdk.Context, subspaceID uint64, groupID uint32) // Must be called when a subspace group is deleted - AfterPermissionSet(ctx sdk.Context, subspaceID uint64, target string, permissions Permission) // Must be called when a permission is set - AfterPermissionRemoved(ctx sdk.Context, subspaceID uint64, target string) // Must be called when a permission is removed + AfterUserPermissionSet(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress, permissions Permission) // Must be called when a permission is set for a user + AfterUserPermissionRemoved(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress) // Must be called when a permission is removed for a user } // -------------------------------------------------------------------------------------------------------------------- @@ -48,43 +48,43 @@ func (h MultiSubspacesHooks) AfterSubspaceDeleted(ctx sdk.Context, subspaceID ui } // AfterSubspaceGroupSaved implements SubspacesHook -func (h MultiSubspacesHooks) AfterSubspaceGroupSaved(ctx sdk.Context, subspaceID uint64, groupName string) { +func (h MultiSubspacesHooks) AfterSubspaceGroupSaved(ctx sdk.Context, subspaceID uint64, groupID uint32) { for _, hook := range h { - hook.AfterSubspaceGroupSaved(ctx, subspaceID, groupName) + hook.AfterSubspaceGroupSaved(ctx, subspaceID, groupID) } } // AfterSubspaceGroupMemberAdded implements SubspacesHook -func (h MultiSubspacesHooks) AfterSubspaceGroupMemberAdded(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { +func (h MultiSubspacesHooks) AfterSubspaceGroupMemberAdded(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) { for _, hook := range h { - hook.AfterSubspaceGroupMemberAdded(ctx, subspaceID, groupName, user) + hook.AfterSubspaceGroupMemberAdded(ctx, subspaceID, groupID, user) } } // AfterSubspaceGroupMemberRemoved implements SubspacesHook -func (h MultiSubspacesHooks) AfterSubspaceGroupMemberRemoved(ctx sdk.Context, subspaceID uint64, groupName string, user sdk.AccAddress) { +func (h MultiSubspacesHooks) AfterSubspaceGroupMemberRemoved(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) { for _, hook := range h { - hook.AfterSubspaceGroupMemberRemoved(ctx, subspaceID, groupName, user) + hook.AfterSubspaceGroupMemberRemoved(ctx, subspaceID, groupID, user) } } // AfterSubspaceGroupDeleted implements SubspacesHook -func (h MultiSubspacesHooks) AfterSubspaceGroupDeleted(ctx sdk.Context, subspaceID uint64, groupName string) { +func (h MultiSubspacesHooks) AfterSubspaceGroupDeleted(ctx sdk.Context, subspaceID uint64, groupID uint32) { for _, hook := range h { - hook.AfterSubspaceGroupDeleted(ctx, subspaceID, groupName) + hook.AfterSubspaceGroupDeleted(ctx, subspaceID, groupID) } } -// AfterPermissionSet implements SubspacesHook -func (h MultiSubspacesHooks) AfterPermissionSet(ctx sdk.Context, subspaceID uint64, target string, permissions Permission) { +// AfterUserPermissionSet implements SubspacesHook +func (h MultiSubspacesHooks) AfterUserPermissionSet(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress, permissions Permission) { for _, hook := range h { - hook.AfterPermissionSet(ctx, subspaceID, target, permissions) + hook.AfterUserPermissionSet(ctx, subspaceID, user, permissions) } } -// AfterPermissionRemoved implements SubspacesHook -func (h MultiSubspacesHooks) AfterPermissionRemoved(ctx sdk.Context, subspaceID uint64, target string) { +// AfterUserPermissionRemoved implements SubspacesHook +func (h MultiSubspacesHooks) AfterUserPermissionRemoved(ctx sdk.Context, subspaceID uint64, user sdk.AccAddress) { for _, hook := range h { - hook.AfterPermissionRemoved(ctx, subspaceID, target) + hook.AfterUserPermissionRemoved(ctx, subspaceID, user) } } diff --git a/x/subspaces/types/keys.go b/x/subspaces/types/keys.go index e9930a0009..851c31ba4b 100644 --- a/x/subspaces/types/keys.go +++ b/x/subspaces/types/keys.go @@ -17,10 +17,12 @@ const ( ActionEditSubspace = "edit_subspace" ActionDeleteSubspace = "delete_subspace" ActionCreateUserGroup = "create_user_group" + ActionEditUserGroup = "edit_user_group" + ActionSetUserGroupPermissions = "set_group_permissions" ActionDeleteUserGroup = "delete_user_group" ActionAddUserToUserGroup = "add_user_to_user_group" ActionRemoveUserFromUserGroup = "remove_user_from_user_group" - ActionSetPermissions = "set_permissions" + ActionSetUserPermissions = "set_user_permissions" QuerierRoute = ModuleName @@ -28,11 +30,14 @@ const ( ) var ( - SubspacePrefix = []byte{0x00} - SubspaceIDKey = []byte{0x01} - PermissionsStorePrefix = []byte{0x02} + SubspacePrefix = []byte{0x00} + SubspaceIDKey = []byte{0x01} + + GroupIDPrefix = []byte{0x02} GroupsPrefix = []byte{0x03} GroupMembersStorePrefix = []byte{0x04} + + UserPermissionsStorePrefix = []byte{0x05} ) // GetSubspaceIDBytes returns the byte representation of the subspaceID @@ -54,30 +59,34 @@ func SubspaceKey(subspaceID uint64) []byte { // PermissionsStoreKey returns the key used to store the entire ACL for a given subspace func PermissionsStoreKey(subspaceID uint64) []byte { - return append(PermissionsStorePrefix, GetSubspaceIDBytes(subspaceID)...) + return append(UserPermissionsStorePrefix, GetSubspaceIDBytes(subspaceID)...) } -func GetTargetBytes(target string) []byte { - return []byte(target) +func GetAddressBytes(user sdk.AccAddress) []byte { + return user } -func GetTargetFromBytes(bz []byte) string { - return string(bz) +func GetAddressFromBytes(bz []byte) sdk.AccAddress { + return bz } -// PermissionStoreKey returns the key used to store the permission for the given target inside the given subspace -func PermissionStoreKey(subspaceID uint64, target string) []byte { - return append(PermissionsStoreKey(subspaceID), GetTargetBytes(target)...) +// -------------------------------------------------------------------------------------------------------------------- + +// GroupIDStoreKey returns the store key that is used to store the group id to be used next for the given subspace +func GroupIDStoreKey(subspaceID uint64) []byte { + return append(GroupIDPrefix, GetSubspaceIDBytes(subspaceID)...) } -// GetGroupNameBytes returns the key byte representation of the groupName -func GetGroupNameBytes(groupName string) []byte { - return []byte(groupName) +// GetGroupIDBytes returns the byte representation of the groupID +func GetGroupIDBytes(groupID uint32) (groupIDBz []byte) { + groupIDBz = make([]byte, 4) + binary.BigEndian.PutUint32(groupIDBz, groupID) + return } -// GetGroupNameFromBytes returns groupName in string format from a byte array -func GetGroupNameFromBytes(bz []byte) string { - return string(bz) +// GetGroupIDFromBytes returns groupID in uint32 format from a byte array +func GetGroupIDFromBytes(bz []byte) (subspaceID uint32) { + return binary.BigEndian.Uint32(bz) } // GroupsStoreKey returns the key used to store all the groups of a given subspace @@ -86,27 +95,24 @@ func GroupsStoreKey(subspaceID uint64) []byte { } // GroupStoreKey returns the key used to store a group for a subspace -func GroupStoreKey(subspaceID uint64, groupName string) []byte { - return append(GroupsStoreKey(subspaceID), GetGroupNameBytes(groupName)...) -} - -// GetGroupMemberBytes returns the key byte representation of the member -func GetGroupMemberBytes(member sdk.AccAddress) []byte { - return member -} - -// GetGroupMemberFromBytes returns member in string format from a byte array -func GetGroupMemberFromBytes(bz []byte) sdk.AccAddress { - return bz +func GroupStoreKey(subspaceID uint64, groupID uint32) []byte { + return append(GroupsStoreKey(subspaceID), GetGroupIDBytes(groupID)...) } // GroupMembersStoreKey returns the key used to store all the members of the given group inside the given subspace -func GroupMembersStoreKey(subspaceID uint64, groupName string) []byte { - return append(append(GroupMembersStorePrefix, GetSubspaceIDBytes(subspaceID)...), GetGroupNameBytes(groupName)...) +func GroupMembersStoreKey(subspaceID uint64, groupID uint32) []byte { + return append(append(GroupMembersStorePrefix, GetSubspaceIDBytes(subspaceID)...), GetGroupIDBytes(groupID)...) } // GroupMemberStoreKey returns the key used to store the membership of the given user to the // specified group inside the provided subspace -func GroupMemberStoreKey(subspaceID uint64, groupName string, user sdk.AccAddress) []byte { - return append(GroupMembersStoreKey(subspaceID, groupName), GetGroupMemberBytes(user)...) +func GroupMemberStoreKey(subspaceID uint64, groupID uint32, user sdk.AccAddress) []byte { + return append(GroupMembersStoreKey(subspaceID, groupID), GetAddressBytes(user)...) +} + +// -------------------------------------------------------------------------------------------------------------------- + +// UserPermissionStoreKey returns the key used to store the permission for the given user inside the given subspace +func UserPermissionStoreKey(subspaceID uint64, user sdk.AccAddress) []byte { + return append(PermissionsStoreKey(subspaceID), GetAddressBytes(user)...) } diff --git a/x/subspaces/types/subspace.go b/x/subspaces/types/models.go similarity index 57% rename from x/subspaces/types/subspace.go rename to x/subspaces/types/models.go index f8e70ddf74..f2aac5ae2a 100644 --- a/x/subspaces/types/subspace.go +++ b/x/subspaces/types/models.go @@ -120,3 +120,84 @@ func (sub Subspace) Update(update *SubspaceUpdate) Subspace { sub.CreationTime, ) } + +// -------------------------------------------------------------------------------------------------------------------- + +// ParseGroupID parses the given value as a group id, returning an error if it's invalid +func ParseGroupID(value string) (uint32, error) { + if value == "" { + return 0, nil + } + + groupID, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return 0, fmt.Errorf("invalid group id: %s", err) + } + return uint32(groupID), nil +} + +// NewUserGroup returns a new UserGroup instance +func NewUserGroup(subspaceID uint64, id uint32, name, description string, permissions Permission) UserGroup { + return UserGroup{ + SubspaceID: subspaceID, + ID: id, + Name: name, + Description: description, + Permissions: permissions, + } +} + +// Validate returns an error if something is wrong within the group data +func (group UserGroup) Validate() error { + if group.SubspaceID == 0 { + return fmt.Errorf("invalid subspace id: %d", group.SubspaceID) + } + + if group.ID == 0 { + return fmt.Errorf("invalid group id: %d", group.ID) + } + + if strings.TrimSpace(group.Name) == "" { + return fmt.Errorf("invalid group name: %s", group.Name) + } + + return nil +} + +// -------------------------------------------------------------------------------------------------------------------- + +// GroupUpdate contains all the data that can be updated about a group. +// When performing an update, if a field should not be edited then it must be set to types.DoNotModify +type GroupUpdate struct { + Name string + Description string +} + +// NewGroupUpdate builds a new SubspaceUpdate instance containing the given data +func NewGroupUpdate(name, description string) *GroupUpdate { + return &GroupUpdate{ + Name: name, + Description: description, + } +} + +// Update updates the fields of a given group without validating it. +// Before storing the updated group, a validation with Validate() should +// be performed. +func (group UserGroup) Update(update *GroupUpdate) UserGroup { + if update.Name == DoNotModify { + update.Name = group.Name + } + + if update.Description == DoNotModify { + update.Description = group.Description + } + + return NewUserGroup( + group.SubspaceID, + group.ID, + update.Name, + update.Description, + group.Permissions, + ) +} diff --git a/x/subspaces/types/models.pb.go b/x/subspaces/types/models.pb.go new file mode 100644 index 0000000000..81ced48fea --- /dev/null +++ b/x/subspaces/types/models.pb.go @@ -0,0 +1,1046 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: desmos/subspaces/v1/models.proto + +package types + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" + _ "google.golang.org/protobuf/types/known/timestamppb" + io "io" + math "math" + math_bits "math/bits" + time "time" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf +var _ = time.Kitchen + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Subspace contains all the data of a Desmos subspace +type Subspace struct { + // Unique id that identifies the subspace + ID uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` + // Human-readable name of the subspace + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` + // Optional description of this subspace + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` + // Represents the account that is associated with the subspace and + // should be used to connect external applications to verify this subspace + Treasury string `protobuf:"bytes,4,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` + // Address of the user that owns the subspace + Owner string `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` + // Address of the subspace creator + Creator string `protobuf:"bytes,6,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` + // the creation time of the subspace + CreationTime time.Time `protobuf:"bytes,7,opt,name=creation_time,json=creationTime,proto3,stdtime" json:"creation_time" yaml:"creation_time"` +} + +func (m *Subspace) Reset() { *m = Subspace{} } +func (m *Subspace) String() string { return proto.CompactTextString(m) } +func (*Subspace) ProtoMessage() {} +func (*Subspace) Descriptor() ([]byte, []int) { + return fileDescriptor_58f218b6c9069791, []int{0} +} +func (m *Subspace) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Subspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Subspace.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Subspace) XXX_Merge(src proto.Message) { + xxx_messageInfo_Subspace.Merge(m, src) +} +func (m *Subspace) XXX_Size() int { + return m.Size() +} +func (m *Subspace) XXX_DiscardUnknown() { + xxx_messageInfo_Subspace.DiscardUnknown(m) +} + +var xxx_messageInfo_Subspace proto.InternalMessageInfo + +func (m *Subspace) GetID() uint64 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *Subspace) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Subspace) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *Subspace) GetTreasury() string { + if m != nil { + return m.Treasury + } + return "" +} + +func (m *Subspace) GetOwner() string { + if m != nil { + return m.Owner + } + return "" +} + +func (m *Subspace) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *Subspace) GetCreationTime() time.Time { + if m != nil { + return m.CreationTime + } + return time.Time{} +} + +// UserGroup represents a group of users +type UserGroup struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + // Unique id that identifies the group + ID uint32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` + // Human-readable name of the user group + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` + Permissions uint32 `protobuf:"varint,5,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` +} + +func (m *UserGroup) Reset() { *m = UserGroup{} } +func (m *UserGroup) String() string { return proto.CompactTextString(m) } +func (*UserGroup) ProtoMessage() {} +func (*UserGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_58f218b6c9069791, []int{1} +} +func (m *UserGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *UserGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_UserGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *UserGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_UserGroup.Merge(m, src) +} +func (m *UserGroup) XXX_Size() int { + return m.Size() +} +func (m *UserGroup) XXX_DiscardUnknown() { + xxx_messageInfo_UserGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_UserGroup proto.InternalMessageInfo + +func (m *UserGroup) GetSubspaceID() uint64 { + if m != nil { + return m.SubspaceID + } + return 0 +} + +func (m *UserGroup) GetID() uint32 { + if m != nil { + return m.ID + } + return 0 +} + +func (m *UserGroup) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *UserGroup) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *UserGroup) GetPermissions() uint32 { + if m != nil { + return m.Permissions + } + return 0 +} + +func init() { + proto.RegisterType((*Subspace)(nil), "desmos.subspaces.v1.Subspace") + proto.RegisterType((*UserGroup)(nil), "desmos.subspaces.v1.UserGroup") +} + +func init() { proto.RegisterFile("desmos/subspaces/v1/models.proto", fileDescriptor_58f218b6c9069791) } + +var fileDescriptor_58f218b6c9069791 = []byte{ + // 487 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0x31, 0x8f, 0xd3, 0x30, + 0x18, 0x86, 0xeb, 0xb6, 0x77, 0xd7, 0xba, 0x57, 0x0e, 0xb9, 0x27, 0x14, 0x75, 0x88, 0x2b, 0x1f, + 0x42, 0x1d, 0x20, 0xd6, 0x95, 0xe5, 0x74, 0x63, 0x05, 0x42, 0x27, 0x31, 0x05, 0x58, 0x58, 0x4e, + 0x69, 0x63, 0x8a, 0xa5, 0x26, 0x8e, 0xec, 0xa4, 0xd0, 0x95, 0x5f, 0x70, 0x23, 0x62, 0xba, 0x9f, + 0x73, 0xe3, 0x8d, 0x4c, 0x06, 0xa5, 0x0b, 0x73, 0x7e, 0x01, 0x8a, 0x9d, 0x94, 0x6c, 0xc0, 0x66, + 0x7f, 0xef, 0xf3, 0x79, 0x78, 0x1f, 0x19, 0x4e, 0x42, 0xa6, 0x22, 0xa1, 0xa8, 0xca, 0x16, 0x2a, + 0x09, 0x96, 0x4c, 0xd1, 0xcd, 0x39, 0x8d, 0x44, 0xc8, 0xd6, 0xca, 0x4b, 0xa4, 0x48, 0x05, 0x1a, + 0x59, 0xc2, 0xdb, 0x13, 0xde, 0xe6, 0x7c, 0x7c, 0xba, 0x12, 0x2b, 0x61, 0x72, 0x5a, 0x9e, 0x2c, + 0x3a, 0xc6, 0x2b, 0x21, 0x56, 0x6b, 0x46, 0xcd, 0x6d, 0x91, 0x7d, 0xa0, 0x29, 0x8f, 0x98, 0x4a, + 0x83, 0x28, 0xb1, 0x00, 0xf9, 0xd2, 0x81, 0xbd, 0x37, 0xd5, 0x3b, 0xe8, 0x0c, 0xb6, 0x79, 0xe8, + 0x80, 0x09, 0x98, 0x76, 0xe7, 0xa3, 0x5c, 0xe3, 0xf6, 0xd5, 0x8b, 0x42, 0xe3, 0xfe, 0x36, 0x88, + 0xd6, 0x97, 0x84, 0x87, 0xc4, 0x6f, 0xf3, 0x10, 0x9d, 0xc1, 0x6e, 0x1c, 0x44, 0xcc, 0x69, 0x4f, + 0xc0, 0xb4, 0x3f, 0x3f, 0x29, 0x34, 0x1e, 0x58, 0xa0, 0x9c, 0x12, 0xdf, 0x84, 0xe8, 0x02, 0x0e, + 0x42, 0xa6, 0x96, 0x92, 0x27, 0x29, 0x17, 0xb1, 0xd3, 0x31, 0xec, 0xa3, 0x42, 0x63, 0x64, 0xd9, + 0x46, 0x48, 0xfc, 0x26, 0x8a, 0x28, 0xec, 0xa5, 0x92, 0x05, 0x2a, 0x93, 0x5b, 0xa7, 0x6b, 0xd6, + 0x46, 0x85, 0xc6, 0x27, 0x76, 0xad, 0x4e, 0x88, 0xbf, 0x87, 0xd0, 0x13, 0x78, 0x20, 0x3e, 0xc5, + 0x4c, 0x3a, 0x07, 0x86, 0x7e, 0x58, 0x68, 0x7c, 0x6c, 0x69, 0x33, 0x26, 0xbe, 0x8d, 0xd1, 0x53, + 0x78, 0xb4, 0x94, 0x2c, 0x48, 0x85, 0x74, 0x0e, 0x0d, 0x89, 0x0a, 0x8d, 0x1f, 0x58, 0xb2, 0x0a, + 0x88, 0x5f, 0x23, 0x28, 0x80, 0x43, 0x73, 0xe4, 0x22, 0xbe, 0x2e, 0x3b, 0x73, 0x8e, 0x26, 0x60, + 0x3a, 0x98, 0x8d, 0x3d, 0x5b, 0xa8, 0x57, 0x17, 0xea, 0xbd, 0xad, 0x0b, 0x9d, 0x4f, 0xee, 0x34, + 0x6e, 0x15, 0x1a, 0x9f, 0x36, 0xde, 0xac, 0xd7, 0xc9, 0xcd, 0x0f, 0x0c, 0xfc, 0xe3, 0x7a, 0x56, + 0x2e, 0x5d, 0xf6, 0xbe, 0xde, 0x62, 0xf0, 0xeb, 0x16, 0x03, 0xf2, 0xad, 0x0d, 0xfb, 0xef, 0x14, + 0x93, 0xaf, 0xa4, 0xc8, 0x12, 0xf4, 0x12, 0x0e, 0x6a, 0xb3, 0xd7, 0x7b, 0x1d, 0x8f, 0x73, 0x8d, + 0x61, 0x2d, 0xca, 0x68, 0xa9, 0x9a, 0x6c, 0xa0, 0xc4, 0x87, 0xf5, 0xed, 0x2a, 0xac, 0x64, 0x96, + 0x96, 0x86, 0x7f, 0x97, 0xd9, 0xf9, 0x0f, 0x99, 0xdd, 0x7f, 0x97, 0x79, 0x01, 0x07, 0x09, 0x93, + 0x11, 0x57, 0x8a, 0x8b, 0x58, 0x19, 0x43, 0xc3, 0xe6, 0x66, 0x23, 0x24, 0x7e, 0x13, 0xfd, 0x53, + 0xce, 0xfc, 0xf5, 0x5d, 0xee, 0x82, 0xfb, 0xdc, 0x05, 0x3f, 0x73, 0x17, 0xdc, 0xec, 0xdc, 0xd6, + 0xfd, 0xce, 0x6d, 0x7d, 0xdf, 0xb9, 0xad, 0xf7, 0xb3, 0x15, 0x4f, 0x3f, 0x66, 0x0b, 0x6f, 0x29, + 0x22, 0x6a, 0xbf, 0xc4, 0xb3, 0x75, 0xb0, 0x50, 0xd5, 0x99, 0x6e, 0x66, 0xf4, 0x73, 0xe3, 0x17, + 0xa5, 0xdb, 0x84, 0xa9, 0xc5, 0xa1, 0x11, 0xf7, 0xfc, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x76, + 0x19, 0x66, 0xe6, 0x66, 0x03, 0x00, 0x00, +} + +func (this *Subspace) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Subspace) + if !ok { + that2, ok := that.(Subspace) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.ID != that1.ID { + return false + } + if this.Name != that1.Name { + return false + } + if this.Description != that1.Description { + return false + } + if this.Treasury != that1.Treasury { + return false + } + if this.Owner != that1.Owner { + return false + } + if this.Creator != that1.Creator { + return false + } + if !this.CreationTime.Equal(that1.CreationTime) { + return false + } + return true +} +func (this *UserGroup) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*UserGroup) + if !ok { + that2, ok := that.(UserGroup) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.SubspaceID != that1.SubspaceID { + return false + } + if this.ID != that1.ID { + return false + } + if this.Name != that1.Name { + return false + } + if this.Description != that1.Description { + return false + } + if this.Permissions != that1.Permissions { + return false + } + return true +} +func (m *Subspace) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Subspace) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Subspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreationTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreationTime):]) + if err1 != nil { + return 0, err1 + } + i -= n1 + i = encodeVarintModels(dAtA, i, uint64(n1)) + i-- + dAtA[i] = 0x3a + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintModels(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0x32 + } + if len(m.Owner) > 0 { + i -= len(m.Owner) + copy(dAtA[i:], m.Owner) + i = encodeVarintModels(dAtA, i, uint64(len(m.Owner))) + i-- + dAtA[i] = 0x2a + } + if len(m.Treasury) > 0 { + i -= len(m.Treasury) + copy(dAtA[i:], m.Treasury) + i = encodeVarintModels(dAtA, i, uint64(len(m.Treasury))) + i-- + dAtA[i] = 0x22 + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintModels(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x1a + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintModels(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x12 + } + if m.ID != 0 { + i = encodeVarintModels(dAtA, i, uint64(m.ID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *UserGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UserGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *UserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Permissions != 0 { + i = encodeVarintModels(dAtA, i, uint64(m.Permissions)) + i-- + dAtA[i] = 0x28 + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintModels(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x22 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintModels(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x1a + } + if m.ID != 0 { + i = encodeVarintModels(dAtA, i, uint64(m.ID)) + i-- + dAtA[i] = 0x10 + } + if m.SubspaceID != 0 { + i = encodeVarintModels(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintModels(dAtA []byte, offset int, v uint64) int { + offset -= sovModels(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Subspace) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ID != 0 { + n += 1 + sovModels(uint64(m.ID)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = len(m.Treasury) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.CreationTime) + n += 1 + l + sovModels(uint64(l)) + return n +} + +func (m *UserGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovModels(uint64(m.SubspaceID)) + } + if m.ID != 0 { + n += 1 + sovModels(uint64(m.ID)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + if m.Permissions != 0 { + n += 1 + sovModels(uint64(m.Permissions)) + } + return n +} + +func sovModels(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozModels(x uint64) (n int) { + return sovModels(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Subspace) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Subspace: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Subspace: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Treasury = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreationTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.CreationTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipModels(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthModels + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UserGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UserGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + } + m.Permissions = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Permissions |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipModels(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthModels + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipModels(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModels + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModels + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowModels + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthModels + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupModels + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthModels + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthModels = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowModels = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupModels = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/subspaces/types/subspace_test.go b/x/subspaces/types/models_test.go similarity index 56% rename from x/subspaces/types/subspace_test.go rename to x/subspaces/types/models_test.go index 118632cce3..34af79b913 100644 --- a/x/subspaces/types/subspace_test.go +++ b/x/subspaces/types/models_test.go @@ -9,6 +9,46 @@ import ( "github.com/stretchr/testify/require" ) +func TestParseSubspaceID(t *testing.T) { + testCases := []struct { + name string + value string + shouldErr bool + expID uint64 + }{ + { + name: "invalid id returns error", + value: "id", + shouldErr: true, + }, + { + name: "empty value returns zero", + value: "", + shouldErr: false, + expID: 0, + }, + { + name: "valid id returns correct value", + value: "2", + shouldErr: false, + expID: 2, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + id, err := types.ParseSubspaceID(tc.value) + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tc.expID, id) + } + }) + } +} + func TestSubspace_Validate(t *testing.T) { testCases := []struct { name string @@ -121,6 +161,8 @@ func TestSubspace_Validate(t *testing.T) { } } +// -------------------------------------------------------------------------------------------------------------------- + func TestSubspace_Update(t *testing.T) { testCases := []struct { name string @@ -192,3 +234,161 @@ func TestSubspace_Update(t *testing.T) { }) } } + +// -------------------------------------------------------------------------------------------------------------------- + +func TestParseUserGroupID(t *testing.T) { + testCases := []struct { + name string + value string + shouldErr bool + expID uint32 + }{ + { + name: "invalid id returns error", + value: "id", + shouldErr: true, + }, + { + name: "empty value returns zero", + value: "", + shouldErr: false, + expID: 0, + }, + { + name: "valid id returns correct value", + value: "2", + shouldErr: false, + expID: 2, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + id, err := types.ParseGroupID(tc.value) + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tc.expID, id) + } + }) + } +} + +func TestUserGroup_Validate(t *testing.T) { + testCases := []struct { + name string + group types.UserGroup + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + group: types.NewUserGroup( + 0, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + shouldErr: true, + }, + { + name: "invalid group name returns error - empty", + group: types.NewUserGroup( + 1, + 1, + "", + "This is a test group", + types.PermissionWrite, + ), + shouldErr: true, + }, + { + name: "invalid group name returns error - blank", + group: types.NewUserGroup( + 1, + 1, + " ", + "This is a test group", + types.PermissionWrite, + ), + shouldErr: true, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.group.Validate() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +// -------------------------------------------------------------------------------------------------------------------- + +func TestUserGroup_Update(t *testing.T) { + testCases := []struct { + name string + subspace types.UserGroup + update *types.GroupUpdate + expResult types.UserGroup + }{ + { + name: "nothing is updated when using DoNotModify", + subspace: types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + update: types.NewGroupUpdate( + types.DoNotModify, + types.DoNotModify, + ), + expResult: types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + }, + { + name: "each field is updated when edited", + subspace: types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + ), + update: types.NewGroupUpdate( + "New group name", + "New group description", + ), + expResult: types.NewUserGroup( + 1, + 1, + "New group name", + "New group description", + types.PermissionWrite, + ), + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + result := tc.subspace.Update(tc.update) + require.Equal(t, tc.expResult, result) + }) + } +} diff --git a/x/subspaces/types/msgs.go b/x/subspaces/types/msgs.go index e17a8587cc..2233decfe6 100644 --- a/x/subspaces/types/msgs.go +++ b/x/subspaces/types/msgs.go @@ -155,10 +155,11 @@ func (msg MsgDeleteSubspace) GetSigners() []sdk.AccAddress { // -------------------------------------------------------------------------------------------------------------------- // NewMsgCreateUserGroup creates a new MsgCreateUserGroup instance -func NewMsgCreateUserGroup(subspaceID uint64, name string, permissions uint32, creator string) *MsgCreateUserGroup { +func NewMsgCreateUserGroup(subspaceID uint64, name, description string, permissions uint32, creator string) *MsgCreateUserGroup { return &MsgCreateUserGroup{ SubspaceID: subspaceID, - GroupName: name, + Name: name, + Description: description, DefaultPermissions: permissions, Creator: creator, } @@ -176,8 +177,8 @@ func (msg MsgCreateUserGroup) ValidateBasic() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) } - if strings.TrimSpace(msg.GroupName) == "" { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group name: %s", msg.GroupName) + if strings.TrimSpace(msg.Name) == "" { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group name: %s", msg.Name) } _, err := sdk.AccAddressFromBech32(msg.Creator) @@ -201,11 +202,106 @@ func (msg MsgCreateUserGroup) GetSigners() []sdk.AccAddress { // -------------------------------------------------------------------------------------------------------------------- +// NewMsgEditUserGroup returns a new NewMsgEditUserGroup instance +func NewMsgEditUserGroup(subspaceID uint64, groupID uint32, name, description string, signer string) *MsgEditUserGroup { + return &MsgEditUserGroup{ + SubspaceID: subspaceID, + GroupID: groupID, + Name: name, + Description: description, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgEditUserGroup) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgEditUserGroup) Type() string { return ActionEditUserGroup } + +// ValidateBasic implements sdk.Msg +func (msg MsgEditUserGroup) ValidateBasic() error { + if msg.SubspaceID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) + } + + if msg.GroupID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group id: %d", msg.GroupID) + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgEditUserGroup) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgEditUserGroup) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Signer) + return []sdk.AccAddress{addr} +} + +// -------------------------------------------------------------------------------------------------------------------- + +// NewMsgSetUserGroupPermissions returns a new MsgSetUserGroupPermissions instance +func NewMsgSetUserGroupPermissions(subspaceID uint64, groupID uint32, permissions Permission, signer string) *MsgSetUserGroupPermissions { + return &MsgSetUserGroupPermissions{ + SubspaceID: subspaceID, + GroupID: groupID, + Permissions: permissions, + Signer: signer, + } +} + +// Route implements sdk.Msg +func (msg MsgSetUserGroupPermissions) Route() string { return RouterKey } + +// Type implements sdk.Msg +func (msg MsgSetUserGroupPermissions) Type() string { return ActionSetUserGroupPermissions } + +// ValidateBasic implements sdk.Msg +func (msg MsgSetUserGroupPermissions) ValidateBasic() error { + if msg.SubspaceID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) + } + + if msg.GroupID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group id: %d", msg.GroupID) + } + + _, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") + } + + return nil +} + +// GetSignBytes implements sdk.Msg +func (msg MsgSetUserGroupPermissions) GetSignBytes() []byte { + return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) +} + +// GetSigners implements sdk.Msg +func (msg MsgSetUserGroupPermissions) GetSigners() []sdk.AccAddress { + addr, _ := sdk.AccAddressFromBech32(msg.Signer) + return []sdk.AccAddress{addr} +} + +// -------------------------------------------------------------------------------------------------------------------- + // NewMsgDeleteUserGroup creates a new MsgDeleteUserGroup instance -func NewMsgDeleteUserGroup(subspaceID uint64, group string, signer string) *MsgDeleteUserGroup { +func NewMsgDeleteUserGroup(subspaceID uint64, groupID uint32, signer string) *MsgDeleteUserGroup { return &MsgDeleteUserGroup{ SubspaceID: subspaceID, - GroupName: group, + GroupID: groupID, Signer: signer, } } @@ -222,8 +318,8 @@ func (msg MsgDeleteUserGroup) ValidateBasic() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) } - if strings.TrimSpace(msg.GroupName) == "" { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group name: %s", msg.GroupName) + if msg.GroupID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group id: %d", msg.GroupID) } _, err := sdk.AccAddressFromBech32(msg.Signer) @@ -248,10 +344,10 @@ func (msg MsgDeleteUserGroup) GetSigners() []sdk.AccAddress { // -------------------------------------------------------------------------------------------------------------------- // NewMsgAddUserToUserGroup creates a new MsgAddUserToUserGroup instance -func NewMsgAddUserToUserGroup(subspaceID uint64, group string, user string, signer string) *MsgAddUserToUserGroup { +func NewMsgAddUserToUserGroup(subspaceID uint64, groupID uint32, user string, signer string) *MsgAddUserToUserGroup { return &MsgAddUserToUserGroup{ SubspaceID: subspaceID, - GroupName: group, + GroupID: groupID, User: user, Signer: signer, } @@ -269,8 +365,8 @@ func (msg MsgAddUserToUserGroup) ValidateBasic() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) } - if strings.TrimSpace(msg.GroupName) == "" { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group name: %s", msg.GroupName) + if msg.GroupID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group id: %d", msg.GroupID) } _, err := sdk.AccAddressFromBech32(msg.User) @@ -300,10 +396,10 @@ func (msg MsgAddUserToUserGroup) GetSigners() []sdk.AccAddress { // -------------------------------------------------------------------------------------------------------------------- // NewMsgRemoveUserFromUserGroup creates a new MsgRemoveUserFromUserGroup instance -func NewMsgRemoveUserFromUserGroup(subspaceID uint64, group string, user string, signer string) *MsgRemoveUserFromUserGroup { +func NewMsgRemoveUserFromUserGroup(subspaceID uint64, groupID uint32, user string, signer string) *MsgRemoveUserFromUserGroup { return &MsgRemoveUserFromUserGroup{ SubspaceID: subspaceID, - GroupName: group, + GroupID: groupID, User: user, Signer: signer, } @@ -321,8 +417,8 @@ func (msg MsgRemoveUserFromUserGroup) ValidateBasic() error { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) } - if strings.TrimSpace(msg.GroupName) == "" { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group name: %s", msg.GroupName) + if msg.GroupID == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid group id: %d", msg.GroupID) } _, err := sdk.AccAddressFromBech32(msg.User) @@ -351,33 +447,34 @@ func (msg MsgRemoveUserFromUserGroup) GetSigners() []sdk.AccAddress { // -------------------------------------------------------------------------------------------------------------------- -// NewMsgSetPermissions creates a new MsgSetPermissions instance -func NewMsgSetPermissions(subspaceID uint64, target string, permissions uint32, signer string) *MsgSetPermissions { - return &MsgSetPermissions{ +// NewMsgSetUserPermissions creates a new MsgSetUserPermissions instance +func NewMsgSetUserPermissions(subspaceID uint64, user string, permissions uint32, signer string) *MsgSetUserPermissions { + return &MsgSetUserPermissions{ SubspaceID: subspaceID, - Target: target, + User: user, Permissions: permissions, Signer: signer, } } // Route implements sdk.Msg -func (msg MsgSetPermissions) Route() string { return RouterKey } +func (msg MsgSetUserPermissions) Route() string { return RouterKey } // Type implements sdk.Msg -func (msg MsgSetPermissions) Type() string { return ActionSetPermissions } +func (msg MsgSetUserPermissions) Type() string { return ActionSetUserPermissions } // ValidateBasic implements sdk.Msg -func (msg MsgSetPermissions) ValidateBasic() error { +func (msg MsgSetUserPermissions) ValidateBasic() error { if msg.SubspaceID == 0 { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid subspace id: %d", msg.SubspaceID) } - if strings.TrimSpace(msg.Target) == "" { - return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid target: %s", msg.Target) + _, err := sdk.AccAddressFromBech32(msg.User) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address") } - _, err := sdk.AccAddressFromBech32(msg.Signer) + _, err = sdk.AccAddressFromBech32(msg.Signer) if err != nil { return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid signer address") } @@ -386,12 +483,12 @@ func (msg MsgSetPermissions) ValidateBasic() error { } // GetSignBytes implements sdk.Msg -func (msg MsgSetPermissions) GetSignBytes() []byte { +func (msg MsgSetUserPermissions) GetSignBytes() []byte { return sdk.MustSortJSON(AminoCodec.MustMarshalJSON(&msg)) } // GetSigners implements sdk.Msg -func (msg MsgSetPermissions) GetSigners() []sdk.AccAddress { +func (msg MsgSetUserPermissions) GetSigners() []sdk.AccAddress { addr, _ := sdk.AccAddressFromBech32(msg.Signer) return []sdk.AccAddress{addr} } diff --git a/x/subspaces/types/msgs.pb.go b/x/subspaces/types/msgs.pb.go index e67ee90f36..80d4b2c816 100644 --- a/x/subspaces/types/msgs.pb.go +++ b/x/subspaces/types/msgs.pb.go @@ -273,10 +273,15 @@ var xxx_messageInfo_MsgDeleteSubspaceResponse proto.InternalMessageInfo // MsgCreateUserGroup represents the message used to create a user group type MsgCreateUserGroup struct { - SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` - GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` - DefaultPermissions uint32 `protobuf:"varint,3,opt,name=default_permissions,json=defaultPermissions,proto3" json:"default_permissions,omitempty" yaml:"default_permissions"` - Creator string `protobuf:"bytes,4,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + // Name of the group + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` + // Optional description of the group + Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` + // Default permissions to be applied to the group + DefaultPermissions uint32 `protobuf:"varint,4,opt,name=default_permissions,json=defaultPermissions,proto3" json:"default_permissions,omitempty" yaml:"default_permissions"` + // Creator of the group + Creator string `protobuf:"bytes,5,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` } func (m *MsgCreateUserGroup) Reset() { *m = MsgCreateUserGroup{} } @@ -319,9 +324,16 @@ func (m *MsgCreateUserGroup) GetSubspaceID() uint64 { return 0 } -func (m *MsgCreateUserGroup) GetGroupName() string { +func (m *MsgCreateUserGroup) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *MsgCreateUserGroup) GetDescription() string { if m != nil { - return m.GroupName + return m.Description } return "" } @@ -342,6 +354,7 @@ func (m *MsgCreateUserGroup) GetCreator() string { // MsgCreateUserGroupResponse defines the Msg/CreateUserGroup response type type MsgCreateUserGroupResponse struct { + GroupID uint32 `protobuf:"varint,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty" yaml:"group_id"` } func (m *MsgCreateUserGroupResponse) Reset() { *m = MsgCreateUserGroupResponse{} } @@ -377,10 +390,239 @@ func (m *MsgCreateUserGroupResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgCreateUserGroupResponse proto.InternalMessageInfo +func (m *MsgCreateUserGroupResponse) GetGroupID() uint32 { + if m != nil { + return m.GroupID + } + return 0 +} + +// MsgEditUserGroup represents the message used to edit a user group +type MsgEditUserGroup struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + GroupID uint32 `protobuf:"varint,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty" yaml:"group_id"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` + Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` + Signer string `protobuf:"bytes,5,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` +} + +func (m *MsgEditUserGroup) Reset() { *m = MsgEditUserGroup{} } +func (m *MsgEditUserGroup) String() string { return proto.CompactTextString(m) } +func (*MsgEditUserGroup) ProtoMessage() {} +func (*MsgEditUserGroup) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{8} +} +func (m *MsgEditUserGroup) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgEditUserGroup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgEditUserGroup.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgEditUserGroup) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgEditUserGroup.Merge(m, src) +} +func (m *MsgEditUserGroup) XXX_Size() int { + return m.Size() +} +func (m *MsgEditUserGroup) XXX_DiscardUnknown() { + xxx_messageInfo_MsgEditUserGroup.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgEditUserGroup proto.InternalMessageInfo + +func (m *MsgEditUserGroup) GetSubspaceID() uint64 { + if m != nil { + return m.SubspaceID + } + return 0 +} + +func (m *MsgEditUserGroup) GetGroupID() uint32 { + if m != nil { + return m.GroupID + } + return 0 +} + +func (m *MsgEditUserGroup) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *MsgEditUserGroup) GetDescription() string { + if m != nil { + return m.Description + } + return "" +} + +func (m *MsgEditUserGroup) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +// MsgEditUserGroupResponse defines the Msg/EditUserGroup response type +type MsgEditUserGroupResponse struct { +} + +func (m *MsgEditUserGroupResponse) Reset() { *m = MsgEditUserGroupResponse{} } +func (m *MsgEditUserGroupResponse) String() string { return proto.CompactTextString(m) } +func (*MsgEditUserGroupResponse) ProtoMessage() {} +func (*MsgEditUserGroupResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{9} +} +func (m *MsgEditUserGroupResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgEditUserGroupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgEditUserGroupResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgEditUserGroupResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgEditUserGroupResponse.Merge(m, src) +} +func (m *MsgEditUserGroupResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgEditUserGroupResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgEditUserGroupResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgEditUserGroupResponse proto.InternalMessageInfo + +// MsgSetUserGroupPermissions represents the message used to set the permissions +// of a user group +type MsgSetUserGroupPermissions struct { + SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + GroupID uint32 `protobuf:"varint,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty" yaml:"group_id"` + Permissions uint32 `protobuf:"varint,3,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` + Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` +} + +func (m *MsgSetUserGroupPermissions) Reset() { *m = MsgSetUserGroupPermissions{} } +func (m *MsgSetUserGroupPermissions) String() string { return proto.CompactTextString(m) } +func (*MsgSetUserGroupPermissions) ProtoMessage() {} +func (*MsgSetUserGroupPermissions) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{10} +} +func (m *MsgSetUserGroupPermissions) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetUserGroupPermissions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetUserGroupPermissions.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetUserGroupPermissions) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetUserGroupPermissions.Merge(m, src) +} +func (m *MsgSetUserGroupPermissions) XXX_Size() int { + return m.Size() +} +func (m *MsgSetUserGroupPermissions) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetUserGroupPermissions.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetUserGroupPermissions proto.InternalMessageInfo + +func (m *MsgSetUserGroupPermissions) GetSubspaceID() uint64 { + if m != nil { + return m.SubspaceID + } + return 0 +} + +func (m *MsgSetUserGroupPermissions) GetGroupID() uint32 { + if m != nil { + return m.GroupID + } + return 0 +} + +func (m *MsgSetUserGroupPermissions) GetPermissions() uint32 { + if m != nil { + return m.Permissions + } + return 0 +} + +func (m *MsgSetUserGroupPermissions) GetSigner() string { + if m != nil { + return m.Signer + } + return "" +} + +// MsgSetUserGroupPermissionsResponse defines the +// Msg/SetUserGroupPermissionsResponse response type +type MsgSetUserGroupPermissionsResponse struct { +} + +func (m *MsgSetUserGroupPermissionsResponse) Reset() { *m = MsgSetUserGroupPermissionsResponse{} } +func (m *MsgSetUserGroupPermissionsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSetUserGroupPermissionsResponse) ProtoMessage() {} +func (*MsgSetUserGroupPermissionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{11} +} +func (m *MsgSetUserGroupPermissionsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgSetUserGroupPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgSetUserGroupPermissionsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MsgSetUserGroupPermissionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetUserGroupPermissionsResponse.Merge(m, src) +} +func (m *MsgSetUserGroupPermissionsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgSetUserGroupPermissionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetUserGroupPermissionsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgSetUserGroupPermissionsResponse proto.InternalMessageInfo + // MsgDeleteUserGroup represents the message used to delete a user group type MsgDeleteUserGroup struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` - GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` + GroupID uint32 `protobuf:"varint,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty" yaml:"group_id"` Signer string `protobuf:"bytes,3,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` } @@ -388,7 +630,7 @@ func (m *MsgDeleteUserGroup) Reset() { *m = MsgDeleteUserGroup{} } func (m *MsgDeleteUserGroup) String() string { return proto.CompactTextString(m) } func (*MsgDeleteUserGroup) ProtoMessage() {} func (*MsgDeleteUserGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{8} + return fileDescriptor_c16a431ff9a3b35b, []int{12} } func (m *MsgDeleteUserGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -424,11 +666,11 @@ func (m *MsgDeleteUserGroup) GetSubspaceID() uint64 { return 0 } -func (m *MsgDeleteUserGroup) GetGroupName() string { +func (m *MsgDeleteUserGroup) GetGroupID() uint32 { if m != nil { - return m.GroupName + return m.GroupID } - return "" + return 0 } func (m *MsgDeleteUserGroup) GetSigner() string { @@ -446,7 +688,7 @@ func (m *MsgDeleteUserGroupResponse) Reset() { *m = MsgDeleteUserGroupRe func (m *MsgDeleteUserGroupResponse) String() string { return proto.CompactTextString(m) } func (*MsgDeleteUserGroupResponse) ProtoMessage() {} func (*MsgDeleteUserGroupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{9} + return fileDescriptor_c16a431ff9a3b35b, []int{13} } func (m *MsgDeleteUserGroupResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -479,8 +721,8 @@ var xxx_messageInfo_MsgDeleteUserGroupResponse proto.InternalMessageInfo // group type MsgAddUserToUserGroup struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` - User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` - GroupName string `protobuf:"bytes,3,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` + GroupID uint32 `protobuf:"varint,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty" yaml:"group_id"` + User string `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` } @@ -488,7 +730,7 @@ func (m *MsgAddUserToUserGroup) Reset() { *m = MsgAddUserToUserGroup{} } func (m *MsgAddUserToUserGroup) String() string { return proto.CompactTextString(m) } func (*MsgAddUserToUserGroup) ProtoMessage() {} func (*MsgAddUserToUserGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{10} + return fileDescriptor_c16a431ff9a3b35b, []int{14} } func (m *MsgAddUserToUserGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -524,16 +766,16 @@ func (m *MsgAddUserToUserGroup) GetSubspaceID() uint64 { return 0 } -func (m *MsgAddUserToUserGroup) GetUser() string { +func (m *MsgAddUserToUserGroup) GetGroupID() uint32 { if m != nil { - return m.User + return m.GroupID } - return "" + return 0 } -func (m *MsgAddUserToUserGroup) GetGroupName() string { +func (m *MsgAddUserToUserGroup) GetUser() string { if m != nil { - return m.GroupName + return m.User } return "" } @@ -554,7 +796,7 @@ func (m *MsgAddUserToUserGroupResponse) Reset() { *m = MsgAddUserToUserG func (m *MsgAddUserToUserGroupResponse) String() string { return proto.CompactTextString(m) } func (*MsgAddUserToUserGroupResponse) ProtoMessage() {} func (*MsgAddUserToUserGroupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{11} + return fileDescriptor_c16a431ff9a3b35b, []int{15} } func (m *MsgAddUserToUserGroupResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -587,8 +829,8 @@ var xxx_messageInfo_MsgAddUserToUserGroupResponse proto.InternalMessageInfo // a user group type MsgRemoveUserFromUserGroup struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` - User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` - GroupName string `protobuf:"bytes,3,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` + GroupID uint32 `protobuf:"varint,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty" yaml:"group_id"` + User string `protobuf:"bytes,3,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` } @@ -596,7 +838,7 @@ func (m *MsgRemoveUserFromUserGroup) Reset() { *m = MsgRemoveUserFromUse func (m *MsgRemoveUserFromUserGroup) String() string { return proto.CompactTextString(m) } func (*MsgRemoveUserFromUserGroup) ProtoMessage() {} func (*MsgRemoveUserFromUserGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{12} + return fileDescriptor_c16a431ff9a3b35b, []int{16} } func (m *MsgRemoveUserFromUserGroup) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -632,16 +874,16 @@ func (m *MsgRemoveUserFromUserGroup) GetSubspaceID() uint64 { return 0 } -func (m *MsgRemoveUserFromUserGroup) GetUser() string { +func (m *MsgRemoveUserFromUserGroup) GetGroupID() uint32 { if m != nil { - return m.User + return m.GroupID } - return "" + return 0 } -func (m *MsgRemoveUserFromUserGroup) GetGroupName() string { +func (m *MsgRemoveUserFromUserGroup) GetUser() string { if m != nil { - return m.GroupName + return m.User } return "" } @@ -662,7 +904,7 @@ func (m *MsgRemoveUserFromUserGroupResponse) Reset() { *m = MsgRemoveUse func (m *MsgRemoveUserFromUserGroupResponse) String() string { return proto.CompactTextString(m) } func (*MsgRemoveUserFromUserGroupResponse) ProtoMessage() {} func (*MsgRemoveUserFromUserGroupResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{13} + return fileDescriptor_c16a431ff9a3b35b, []int{17} } func (m *MsgRemoveUserFromUserGroupResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -691,27 +933,27 @@ func (m *MsgRemoveUserFromUserGroupResponse) XXX_DiscardUnknown() { var xxx_messageInfo_MsgRemoveUserFromUserGroupResponse proto.InternalMessageInfo -// MsgSetPermissions represents the message used to set the permissions of a -// user or user group -type MsgSetPermissions struct { +// MsgSetUserPermissions represents the message used to set the permissions of a +// specific user +type MsgSetUserPermissions struct { SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` - Target string `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty" yaml:"target"` + User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` Permissions uint32 `protobuf:"varint,3,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` Signer string `protobuf:"bytes,4,opt,name=signer,proto3" json:"signer,omitempty" yaml:"signer"` } -func (m *MsgSetPermissions) Reset() { *m = MsgSetPermissions{} } -func (m *MsgSetPermissions) String() string { return proto.CompactTextString(m) } -func (*MsgSetPermissions) ProtoMessage() {} -func (*MsgSetPermissions) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{14} +func (m *MsgSetUserPermissions) Reset() { *m = MsgSetUserPermissions{} } +func (m *MsgSetUserPermissions) String() string { return proto.CompactTextString(m) } +func (*MsgSetUserPermissions) ProtoMessage() {} +func (*MsgSetUserPermissions) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{18} } -func (m *MsgSetPermissions) XXX_Unmarshal(b []byte) error { +func (m *MsgSetUserPermissions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MsgSetPermissions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *MsgSetUserPermissions) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MsgSetPermissions.Marshal(b, m, deterministic) + return xxx_messageInfo_MsgSetUserPermissions.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -721,63 +963,63 @@ func (m *MsgSetPermissions) XXX_Marshal(b []byte, deterministic bool) ([]byte, e return b[:n], nil } } -func (m *MsgSetPermissions) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgSetPermissions.Merge(m, src) +func (m *MsgSetUserPermissions) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetUserPermissions.Merge(m, src) } -func (m *MsgSetPermissions) XXX_Size() int { +func (m *MsgSetUserPermissions) XXX_Size() int { return m.Size() } -func (m *MsgSetPermissions) XXX_DiscardUnknown() { - xxx_messageInfo_MsgSetPermissions.DiscardUnknown(m) +func (m *MsgSetUserPermissions) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetUserPermissions.DiscardUnknown(m) } -var xxx_messageInfo_MsgSetPermissions proto.InternalMessageInfo +var xxx_messageInfo_MsgSetUserPermissions proto.InternalMessageInfo -func (m *MsgSetPermissions) GetSubspaceID() uint64 { +func (m *MsgSetUserPermissions) GetSubspaceID() uint64 { if m != nil { return m.SubspaceID } return 0 } -func (m *MsgSetPermissions) GetTarget() string { +func (m *MsgSetUserPermissions) GetUser() string { if m != nil { - return m.Target + return m.User } return "" } -func (m *MsgSetPermissions) GetPermissions() uint32 { +func (m *MsgSetUserPermissions) GetPermissions() uint32 { if m != nil { return m.Permissions } return 0 } -func (m *MsgSetPermissions) GetSigner() string { +func (m *MsgSetUserPermissions) GetSigner() string { if m != nil { return m.Signer } return "" } -// MsgSetPermissionsResponse defines the Msg/SetPermissionsResponse +// MsgSetUserPermissionsResponse defines the Msg/SetPermissionsResponse // response type -type MsgSetPermissionsResponse struct { +type MsgSetUserPermissionsResponse struct { } -func (m *MsgSetPermissionsResponse) Reset() { *m = MsgSetPermissionsResponse{} } -func (m *MsgSetPermissionsResponse) String() string { return proto.CompactTextString(m) } -func (*MsgSetPermissionsResponse) ProtoMessage() {} -func (*MsgSetPermissionsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_c16a431ff9a3b35b, []int{15} +func (m *MsgSetUserPermissionsResponse) Reset() { *m = MsgSetUserPermissionsResponse{} } +func (m *MsgSetUserPermissionsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgSetUserPermissionsResponse) ProtoMessage() {} +func (*MsgSetUserPermissionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_c16a431ff9a3b35b, []int{19} } -func (m *MsgSetPermissionsResponse) XXX_Unmarshal(b []byte) error { +func (m *MsgSetUserPermissionsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *MsgSetPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *MsgSetUserPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_MsgSetPermissionsResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_MsgSetUserPermissionsResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -787,17 +1029,17 @@ func (m *MsgSetPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([ return b[:n], nil } } -func (m *MsgSetPermissionsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_MsgSetPermissionsResponse.Merge(m, src) +func (m *MsgSetUserPermissionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgSetUserPermissionsResponse.Merge(m, src) } -func (m *MsgSetPermissionsResponse) XXX_Size() int { +func (m *MsgSetUserPermissionsResponse) XXX_Size() int { return m.Size() } -func (m *MsgSetPermissionsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_MsgSetPermissionsResponse.DiscardUnknown(m) +func (m *MsgSetUserPermissionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgSetUserPermissionsResponse.DiscardUnknown(m) } -var xxx_messageInfo_MsgSetPermissionsResponse proto.InternalMessageInfo +var xxx_messageInfo_MsgSetUserPermissionsResponse proto.InternalMessageInfo func init() { proto.RegisterType((*MsgCreateSubspace)(nil), "desmos.subspaces.v1.MsgCreateSubspace") @@ -808,72 +1050,82 @@ func init() { proto.RegisterType((*MsgDeleteSubspaceResponse)(nil), "desmos.subspaces.v1.MsgDeleteSubspaceResponse") proto.RegisterType((*MsgCreateUserGroup)(nil), "desmos.subspaces.v1.MsgCreateUserGroup") proto.RegisterType((*MsgCreateUserGroupResponse)(nil), "desmos.subspaces.v1.MsgCreateUserGroupResponse") + proto.RegisterType((*MsgEditUserGroup)(nil), "desmos.subspaces.v1.MsgEditUserGroup") + proto.RegisterType((*MsgEditUserGroupResponse)(nil), "desmos.subspaces.v1.MsgEditUserGroupResponse") + proto.RegisterType((*MsgSetUserGroupPermissions)(nil), "desmos.subspaces.v1.MsgSetUserGroupPermissions") + proto.RegisterType((*MsgSetUserGroupPermissionsResponse)(nil), "desmos.subspaces.v1.MsgSetUserGroupPermissionsResponse") proto.RegisterType((*MsgDeleteUserGroup)(nil), "desmos.subspaces.v1.MsgDeleteUserGroup") proto.RegisterType((*MsgDeleteUserGroupResponse)(nil), "desmos.subspaces.v1.MsgDeleteUserGroupResponse") proto.RegisterType((*MsgAddUserToUserGroup)(nil), "desmos.subspaces.v1.MsgAddUserToUserGroup") proto.RegisterType((*MsgAddUserToUserGroupResponse)(nil), "desmos.subspaces.v1.MsgAddUserToUserGroupResponse") proto.RegisterType((*MsgRemoveUserFromUserGroup)(nil), "desmos.subspaces.v1.MsgRemoveUserFromUserGroup") proto.RegisterType((*MsgRemoveUserFromUserGroupResponse)(nil), "desmos.subspaces.v1.MsgRemoveUserFromUserGroupResponse") - proto.RegisterType((*MsgSetPermissions)(nil), "desmos.subspaces.v1.MsgSetPermissions") - proto.RegisterType((*MsgSetPermissionsResponse)(nil), "desmos.subspaces.v1.MsgSetPermissionsResponse") + proto.RegisterType((*MsgSetUserPermissions)(nil), "desmos.subspaces.v1.MsgSetUserPermissions") + proto.RegisterType((*MsgSetUserPermissionsResponse)(nil), "desmos.subspaces.v1.MsgSetUserPermissionsResponse") } func init() { proto.RegisterFile("desmos/subspaces/v1/msgs.proto", fileDescriptor_c16a431ff9a3b35b) } var fileDescriptor_c16a431ff9a3b35b = []byte{ - // 832 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x97, 0x3d, 0x6f, 0xd3, 0x5c, - 0x14, 0xc7, 0xe3, 0x24, 0xcd, 0xd3, 0x9e, 0xbe, 0xe4, 0xa9, 0x4b, 0x69, 0x6a, 0xc0, 0x46, 0xb7, - 0x55, 0x0b, 0xa8, 0xc4, 0x6a, 0x40, 0x02, 0x75, 0x23, 0xb4, 0xa0, 0x4a, 0x04, 0x90, 0x0b, 0x0b, - 0x4b, 0xe5, 0xc4, 0x17, 0xd7, 0x22, 0x8e, 0x23, 0x5f, 0x27, 0xd0, 0xb9, 0x0b, 0x1b, 0xfd, 0x08, - 0xfd, 0x20, 0xac, 0x48, 0x8c, 0x1d, 0x99, 0x2c, 0x94, 0x32, 0x00, 0xa3, 0x77, 0x24, 0xe4, 0xeb, - 0x97, 0x38, 0x4e, 0xdc, 0x26, 0x28, 0x03, 0x62, 0xb3, 0xef, 0xf9, 0xdd, 0x97, 0xf3, 0x3f, 0xe7, - 0x9e, 0x63, 0x03, 0xaf, 0x60, 0xa2, 0x1b, 0x44, 0x24, 0xad, 0x2a, 0x69, 0xca, 0x35, 0x4c, 0xc4, - 0xf6, 0xa6, 0xa8, 0x13, 0x95, 0x14, 0x9b, 0xa6, 0x61, 0x19, 0xec, 0x82, 0x67, 0x2f, 0x86, 0xf6, - 0x62, 0x7b, 0x93, 0xbb, 0xa4, 0x1a, 0xaa, 0x41, 0xed, 0xa2, 0xfb, 0xe4, 0xa1, 0x1c, 0x1a, 0xb4, - 0x54, 0xf0, 0xe2, 0x31, 0xe8, 0x28, 0x0d, 0xf3, 0x15, 0xa2, 0x3e, 0x34, 0xb1, 0x6c, 0xe1, 0x3d, - 0xdf, 0xc6, 0xae, 0x40, 0xb6, 0x21, 0xeb, 0xb8, 0xc0, 0x5c, 0x67, 0x6e, 0x4c, 0x95, 0xf3, 0x8e, - 0x2d, 0x4c, 0x1f, 0xca, 0x7a, 0x7d, 0x0b, 0xb9, 0xa3, 0x48, 0xa2, 0x46, 0xf6, 0x3e, 0x4c, 0x2b, - 0x98, 0xd4, 0x4c, 0xad, 0x69, 0x69, 0x46, 0xa3, 0x90, 0xa6, 0xec, 0x65, 0xc7, 0x16, 0x58, 0x8f, - 0x8d, 0x18, 0x91, 0x14, 0x45, 0x59, 0x11, 0x26, 0x2d, 0x13, 0xcb, 0xa4, 0x65, 0x1e, 0x16, 0x32, - 0x74, 0xda, 0x82, 0x63, 0x0b, 0x79, 0x6f, 0x5a, 0x60, 0x41, 0x52, 0x08, 0xb1, 0x6b, 0x30, 0x61, - 0xbc, 0x6d, 0x60, 0xb3, 0x90, 0xa5, 0xf4, 0xff, 0x8e, 0x2d, 0xcc, 0x78, 0x34, 0x1d, 0x46, 0x92, - 0x67, 0x66, 0x37, 0xe0, 0xbf, 0x9a, 0xeb, 0x89, 0x61, 0x16, 0x26, 0x28, 0xc9, 0x3a, 0xb6, 0x30, - 0xe7, 0x91, 0xbe, 0x01, 0x49, 0x01, 0xb2, 0x35, 0xf9, 0xfe, 0x44, 0x48, 0x7d, 0x3f, 0x11, 0x52, - 0xa8, 0x0a, 0xcb, 0x7d, 0x22, 0x48, 0x98, 0x34, 0x8d, 0x06, 0xc1, 0xec, 0x0e, 0x4c, 0x07, 0xa2, - 0xed, 0x6b, 0x0a, 0xd5, 0x24, 0x5b, 0x5e, 0xed, 0xd8, 0x02, 0x04, 0xe8, 0xee, 0x76, 0xd7, 0xeb, - 0x08, 0x8a, 0x24, 0x08, 0xde, 0x76, 0x15, 0xf4, 0x29, 0x0d, 0xf9, 0x0a, 0x51, 0x77, 0x14, 0xcd, - 0x0a, 0x75, 0x1e, 0xcf, 0xd2, 0x61, 0xb8, 0xd2, 0x23, 0x84, 0x2b, 0xf3, 0x67, 0xe1, 0xca, 0x8e, - 0x14, 0xae, 0x89, 0xf3, 0xc3, 0x75, 0x13, 0x72, 0x44, 0x53, 0x5d, 0x30, 0x47, 0xc1, 0x79, 0xc7, - 0x16, 0x66, 0x7d, 0x5f, 0xe9, 0x38, 0x92, 0x7c, 0x20, 0x12, 0xab, 0x65, 0x58, 0x8a, 0xc9, 0x18, - 0x44, 0x0a, 0x7d, 0x60, 0x68, 0x32, 0x6f, 0xe3, 0x3a, 0x8e, 0x24, 0xf3, 0x98, 0x44, 0xee, 0x1e, - 0x36, 0x3d, 0xfc, 0x61, 0xaf, 0xd0, 0xc4, 0xea, 0x3d, 0x50, 0x78, 0xdc, 0xe3, 0x34, 0xb0, 0x61, - 0xda, 0xbd, 0x24, 0xd8, 0x7c, 0x6c, 0x1a, 0xad, 0xe6, 0xb8, 0xce, 0x7b, 0x17, 0x40, 0x75, 0xd7, - 0xdb, 0x8f, 0xa4, 0xc6, 0xa2, 0x63, 0x0b, 0xf3, 0xde, 0xbc, 0xae, 0x0d, 0x49, 0x53, 0xf4, 0xe5, - 0xa9, 0x9b, 0x25, 0xcf, 0x60, 0x41, 0xc1, 0xaf, 0xe5, 0x56, 0xdd, 0xda, 0x6f, 0x62, 0x53, 0xd7, - 0x08, 0xd1, 0x8c, 0x06, 0xa1, 0xd9, 0x32, 0x5b, 0xe6, 0x1d, 0x5b, 0xe0, 0x82, 0x6c, 0xe9, 0x83, - 0x90, 0xc4, 0xfa, 0xa3, 0xcf, 0xbb, 0x83, 0xd1, 0x2b, 0x99, 0xbd, 0xf0, 0x4a, 0xa2, 0xab, 0xc0, - 0xf5, 0x2b, 0x12, 0x0a, 0xf6, 0x91, 0xa1, 0x82, 0x79, 0x72, 0xfe, 0x25, 0x82, 0x75, 0xd3, 0x22, - 0x73, 0x41, 0x5a, 0xf8, 0xce, 0xc5, 0x4e, 0x1f, 0x3a, 0xf7, 0x8d, 0x81, 0xc5, 0x0a, 0x51, 0x1f, - 0x28, 0x8a, 0x6b, 0x7b, 0x61, 0x8c, 0xdd, 0xbf, 0x15, 0xc8, 0xb6, 0x48, 0x98, 0xbe, 0x91, 0x2a, - 0xe1, 0x8e, 0x22, 0x89, 0x1a, 0x63, 0x22, 0x64, 0x46, 0x16, 0x21, 0x7b, 0x91, 0x08, 0x02, 0x5c, - 0x1b, 0xe8, 0x65, 0xa8, 0xc3, 0x0f, 0x86, 0xca, 0x24, 0x61, 0xdd, 0x68, 0x53, 0x99, 0x1e, 0x99, - 0x86, 0xfe, 0x8f, 0x8a, 0xb1, 0x0a, 0x28, 0xd9, 0xd5, 0x50, 0x91, 0x9f, 0x5e, 0x59, 0xdb, 0xc3, - 0x3d, 0x17, 0x6b, 0x7c, 0x65, 0xcd, 0x92, 0x4d, 0x15, 0x5b, 0xfd, 0x65, 0xcd, 0x1b, 0x47, 0x92, - 0x0f, 0xb8, 0x1d, 0xa4, 0xbf, 0x26, 0x44, 0x3a, 0x48, 0x4f, 0x2d, 0x88, 0xa2, 0xa3, 0x48, 0xe2, - 0x55, 0xcc, 0x5e, 0x5f, 0x03, 0x25, 0x4a, 0xbf, 0x72, 0x90, 0xa9, 0x10, 0x95, 0x3d, 0x80, 0xb9, - 0xd8, 0x17, 0xcb, 0x5a, 0x71, 0xc0, 0x77, 0x51, 0xb1, 0xaf, 0xa9, 0x73, 0xc5, 0xe1, 0xb8, 0xb0, - 0xf9, 0x57, 0x61, 0xa6, 0xa7, 0x63, 0xaf, 0x26, 0xcd, 0x8f, 0x52, 0xdc, 0xc6, 0x30, 0x54, 0xb8, - 0xc7, 0x01, 0xcc, 0xc5, 0x5a, 0x56, 0xa2, 0x37, 0xbd, 0x5c, 0xb2, 0x37, 0x83, 0x3b, 0x0e, 0xfb, - 0x06, 0xf2, 0xf1, 0x6e, 0xb3, 0x7e, 0xbe, 0x20, 0x21, 0xc8, 0x89, 0x43, 0x82, 0xd1, 0xcd, 0xe2, - 0x95, 0x7a, 0xfd, 0xfc, 0xf3, 0x0e, 0xb1, 0x59, 0x42, 0xf5, 0x64, 0x2d, 0x60, 0x07, 0x54, 0xce, - 0x5b, 0x49, 0xcb, 0xf4, 0xb3, 0x5c, 0x69, 0x78, 0x36, 0xdc, 0xf5, 0x88, 0x81, 0xa5, 0xa4, 0x42, - 0x95, 0xe8, 0x42, 0xc2, 0x04, 0xee, 0xde, 0x88, 0x13, 0xa2, 0xf9, 0x13, 0xab, 0x0d, 0x89, 0xf9, - 0xd3, 0xcb, 0x25, 0xe7, 0xcf, 0xe0, 0xfb, 0x57, 0x7e, 0xf2, 0xb9, 0xc3, 0x33, 0xa7, 0x1d, 0x9e, - 0xf9, 0xda, 0xe1, 0x99, 0xe3, 0x33, 0x3e, 0x75, 0x7a, 0xc6, 0xa7, 0xbe, 0x9c, 0xf1, 0xa9, 0x57, - 0x25, 0x55, 0xb3, 0x0e, 0x5a, 0xd5, 0x62, 0xcd, 0xd0, 0x45, 0x6f, 0xcd, 0xdb, 0x75, 0xb9, 0x4a, - 0xfc, 0x67, 0xb1, 0x5d, 0x12, 0xdf, 0x45, 0xfe, 0x43, 0xac, 0xc3, 0x26, 0x26, 0xd5, 0x1c, 0xfd, - 0x05, 0xb9, 0xf3, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xd7, 0xa0, 0x24, 0x14, 0xf3, 0x0c, 0x00, 0x00, + // 920 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x4b, 0x6f, 0xe3, 0x44, + 0x1c, 0x8f, 0x9d, 0xa4, 0x0d, 0xff, 0x6c, 0x9a, 0x5d, 0x17, 0xd8, 0xac, 0x01, 0x7b, 0x35, 0x94, + 0x5d, 0x58, 0xed, 0xc6, 0xda, 0x70, 0x60, 0xd9, 0x1b, 0x61, 0x0b, 0xaa, 0x44, 0x04, 0x72, 0x41, + 0x48, 0x5c, 0xaa, 0x24, 0x1e, 0x5c, 0x8b, 0x38, 0x13, 0x79, 0x9c, 0x40, 0xcf, 0xbd, 0x70, 0x83, + 0x4f, 0x80, 0xfa, 0x35, 0x38, 0x72, 0x40, 0xe2, 0xd8, 0x23, 0x27, 0x0b, 0xa5, 0x97, 0x72, 0xe1, + 0x90, 0x03, 0x67, 0xe4, 0xb1, 0x3d, 0x99, 0x3c, 0x9c, 0x38, 0xa8, 0x40, 0xd9, 0x9b, 0x33, 0xff, + 0xdf, 0x3c, 0x7e, 0x8f, 0x79, 0x28, 0xa0, 0x59, 0x98, 0xba, 0x84, 0x1a, 0x74, 0xd8, 0xa1, 0x83, + 0x76, 0x17, 0x53, 0x63, 0xf4, 0xd8, 0x70, 0xa9, 0x4d, 0xeb, 0x03, 0x8f, 0xf8, 0x44, 0xd9, 0x8d, + 0xea, 0x75, 0x5e, 0xaf, 0x8f, 0x1e, 0xab, 0x2f, 0xda, 0xc4, 0x26, 0xac, 0x6e, 0x84, 0x5f, 0x11, + 0x54, 0xbd, 0xbb, 0x74, 0x28, 0x62, 0xe1, 0x5e, 0x3c, 0x18, 0x3a, 0x95, 0xe1, 0x56, 0x8b, 0xda, + 0xef, 0x7b, 0xb8, 0xed, 0xe3, 0xc3, 0x18, 0xa6, 0xbc, 0x0e, 0x85, 0x7e, 0xdb, 0xc5, 0x35, 0xe9, + 0xae, 0xf4, 0xe6, 0x0b, 0xcd, 0xea, 0x24, 0xd0, 0xcb, 0x27, 0x6d, 0xb7, 0xf7, 0x14, 0x85, 0xad, + 0xc8, 0x64, 0x45, 0xe5, 0x09, 0x94, 0x2d, 0x4c, 0xbb, 0x9e, 0x33, 0xf0, 0x1d, 0xd2, 0xaf, 0xc9, + 0x0c, 0xfb, 0xf2, 0x24, 0xd0, 0x95, 0x08, 0x2b, 0x14, 0x91, 0x29, 0x42, 0x15, 0x03, 0x4a, 0xbe, + 0x87, 0xdb, 0x74, 0xe8, 0x9d, 0xd4, 0xf2, 0xac, 0xdb, 0xee, 0x24, 0xd0, 0xab, 0x51, 0xb7, 0xa4, + 0x82, 0x4c, 0x0e, 0x52, 0xee, 0x41, 0x91, 0x7c, 0xdd, 0xc7, 0x5e, 0xad, 0xc0, 0xd0, 0x37, 0x27, + 0x81, 0x7e, 0x23, 0x42, 0xb3, 0x66, 0x64, 0x46, 0x65, 0xe5, 0x21, 0x6c, 0x77, 0x43, 0x26, 0xc4, + 0xab, 0x15, 0x19, 0x52, 0x99, 0x04, 0xfa, 0x4e, 0x84, 0x8c, 0x0b, 0xc8, 0x4c, 0x20, 0x4f, 0x4b, + 0xdf, 0x9e, 0xe9, 0xb9, 0xcb, 0x33, 0x3d, 0x87, 0x3a, 0x70, 0x67, 0x41, 0x04, 0x13, 0xd3, 0x01, + 0xe9, 0x53, 0xac, 0xec, 0x43, 0x39, 0xd1, 0xef, 0xc8, 0xb1, 0x98, 0x26, 0x85, 0xe6, 0xde, 0x38, + 0xd0, 0x21, 0x81, 0x1e, 0x3c, 0x9b, 0xb2, 0x16, 0xa0, 0xc8, 0x84, 0xe4, 0xd7, 0x81, 0x85, 0x7e, + 0x96, 0xa1, 0xda, 0xa2, 0xf6, 0xbe, 0xe5, 0xf8, 0x5c, 0xe7, 0xab, 0x19, 0x9a, 0xdb, 0x25, 0x6f, + 0x60, 0x57, 0xfe, 0xef, 0xd9, 0x55, 0xd8, 0xc8, 0xae, 0xe2, 0x6a, 0xbb, 0xde, 0x82, 0x2d, 0xea, + 0xd8, 0x21, 0x70, 0x8b, 0x01, 0x6f, 0x4d, 0x02, 0xbd, 0x12, 0x73, 0x65, 0xed, 0xc8, 0x8c, 0x01, + 0x82, 0x57, 0x77, 0xe0, 0xf6, 0x9c, 0x8c, 0x89, 0x53, 0xe8, 0x3b, 0x89, 0x85, 0xf9, 0x19, 0xee, + 0x61, 0x21, 0xcc, 0x57, 0x24, 0xf2, 0x74, 0xb1, 0x72, 0xf6, 0xc5, 0xbe, 0xc2, 0x82, 0x35, 0xbb, + 0x20, 0xbe, 0xdc, 0x1f, 0x65, 0x50, 0x78, 0xec, 0x3e, 0xa3, 0xd8, 0xfb, 0xd0, 0x23, 0xc3, 0xc1, + 0xff, 0x24, 0x14, 0x1f, 0xc3, 0xae, 0x85, 0xbf, 0x6c, 0x0f, 0x7b, 0xfe, 0xd1, 0x00, 0x7b, 0xae, + 0x43, 0xa9, 0x43, 0xfa, 0x94, 0xe5, 0xa3, 0xd2, 0xd4, 0x26, 0x81, 0xae, 0x26, 0x23, 0x2c, 0x80, + 0x90, 0xa9, 0xc4, 0xad, 0x9f, 0x4c, 0x1b, 0x37, 0xdb, 0xbb, 0xe8, 0x73, 0x50, 0x17, 0xa5, 0xe3, + 0x5b, 0xf6, 0x5d, 0x28, 0xd9, 0x61, 0x43, 0xa2, 0x5f, 0xa5, 0xa9, 0x8d, 0x03, 0x7d, 0x9b, 0x81, + 0x98, 0x78, 0x71, 0x78, 0x13, 0x10, 0x32, 0xb7, 0xd9, 0xe7, 0x81, 0x85, 0x7e, 0x90, 0xe1, 0x66, + 0x9c, 0xaf, 0x2b, 0xb7, 0x44, 0x5c, 0x96, 0xbc, 0xd1, 0xb2, 0xb8, 0x9b, 0xf9, 0x0d, 0xdc, 0x2c, + 0x64, 0x77, 0x73, 0x1a, 0xee, 0xe2, 0x9a, 0x70, 0x23, 0x15, 0x6a, 0xf3, 0xfa, 0xf0, 0x44, 0x9f, + 0xca, 0xcc, 0x96, 0x43, 0x3c, 0xad, 0x89, 0x16, 0xff, 0xf7, 0x32, 0x3e, 0x81, 0xb2, 0x98, 0xd6, + 0x3c, 0xeb, 0x2d, 0x28, 0x34, 0x93, 0x52, 0x11, 0x2a, 0x28, 0x54, 0x58, 0xa7, 0xd0, 0x1e, 0xa0, + 0x74, 0x11, 0xb8, 0x56, 0x3f, 0x49, 0x6c, 0xf7, 0x47, 0x67, 0xc3, 0x75, 0x8a, 0xda, 0x94, 0x69, + 0x7e, 0x1d, 0xd3, 0x57, 0x99, 0xdd, 0x73, 0x14, 0x38, 0xc3, 0xdf, 0x25, 0x78, 0xa9, 0x45, 0xed, + 0xf7, 0x2c, 0x2b, 0xac, 0x7d, 0x4a, 0xae, 0xd9, 0x7e, 0x1a, 0x52, 0x4e, 0x51, 0xd8, 0x4f, 0x61, + 0x2b, 0x32, 0x59, 0x71, 0x13, 0xcf, 0x75, 0x78, 0x6d, 0x29, 0x55, 0x2e, 0xc6, 0x1f, 0x12, 0xd3, + 0xca, 0xc4, 0x2e, 0x19, 0x31, 0xad, 0x3e, 0xf0, 0x88, 0xfb, 0x3c, 0x2b, 0x12, 0xed, 0x82, 0x14, + 0xbe, 0x5c, 0x96, 0xcb, 0x28, 0x23, 0xf1, 0x66, 0xf9, 0x07, 0x0e, 0x8b, 0x84, 0x96, 0xbc, 0x8a, + 0xd6, 0xbf, 0x72, 0x2c, 0x44, 0x11, 0x59, 0x64, 0x9a, 0x68, 0xd1, 0xf8, 0xb3, 0x04, 0xf9, 0x16, + 0xb5, 0x95, 0x63, 0xd8, 0x99, 0x7b, 0x8f, 0xdf, 0xab, 0x2f, 0x79, 0xf3, 0xd7, 0x17, 0x9e, 0xac, + 0x6a, 0x3d, 0x1b, 0x8e, 0xdf, 0x93, 0x1d, 0xb8, 0x31, 0xf3, 0x1e, 0xdd, 0x4b, 0xeb, 0x2f, 0xa2, + 0xd4, 0x87, 0x59, 0x50, 0x7c, 0x8e, 0x63, 0xd8, 0x99, 0x7b, 0x90, 0xa5, 0xb2, 0x99, 0xc5, 0xa5, + 0xb3, 0x59, 0xfe, 0x9e, 0x52, 0xbe, 0x82, 0xea, 0xfc, 0x5b, 0xea, 0xfe, 0x6a, 0x41, 0x38, 0x50, + 0x35, 0x32, 0x02, 0xf9, 0x64, 0x18, 0x2a, 0xb3, 0x6f, 0x84, 0x37, 0x56, 0xa9, 0x32, 0x9d, 0xe8, + 0x51, 0x26, 0x18, 0x9f, 0xe6, 0x54, 0x82, 0xdb, 0x69, 0xd7, 0x69, 0xea, 0x9a, 0x53, 0x3a, 0xa8, + 0xef, 0x6c, 0xd8, 0x41, 0x54, 0x76, 0xfe, 0x9e, 0xba, 0xbf, 0xda, 0x9c, 0x0c, 0xca, 0xa6, 0x5c, + 0x1b, 0x8a, 0x0f, 0xca, 0x92, 0x2b, 0xe3, 0x41, 0xda, 0x30, 0x8b, 0x58, 0xb5, 0x91, 0x1d, 0x3b, + 0x23, 0x74, 0xda, 0xe1, 0x9c, 0x4a, 0x21, 0xa5, 0x43, 0xba, 0xd0, 0x6b, 0x8e, 0xc3, 0x90, 0xfb, + 0x92, 0xa3, 0xf0, 0xc1, 0x1a, 0xdf, 0x44, 0x8f, 0x1b, 0xd9, 0xb1, 0xc9, 0xac, 0xcd, 0x8f, 0x7e, + 0x19, 0x6b, 0xd2, 0xf9, 0x58, 0x93, 0x7e, 0x1b, 0x6b, 0xd2, 0xf7, 0x17, 0x5a, 0xee, 0xfc, 0x42, + 0xcb, 0xfd, 0x7a, 0xa1, 0xe5, 0xbe, 0x68, 0xd8, 0x8e, 0x7f, 0x3c, 0xec, 0xd4, 0xbb, 0xc4, 0x35, + 0xa2, 0x71, 0x1f, 0xf5, 0xda, 0x1d, 0x1a, 0x7f, 0x1b, 0xa3, 0x86, 0xf1, 0x8d, 0xf0, 0xe7, 0x82, + 0x7f, 0x32, 0xc0, 0xb4, 0xb3, 0xc5, 0xfe, 0x59, 0x78, 0xfb, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x46, 0x65, 0xcc, 0x53, 0xc8, 0x10, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -896,6 +1148,10 @@ type MsgClient interface { DeleteSubspace(ctx context.Context, in *MsgDeleteSubspace, opts ...grpc.CallOption) (*MsgDeleteSubspaceResponse, error) // CreateUserGroup allows to create a user group CreateUserGroup(ctx context.Context, in *MsgCreateUserGroup, opts ...grpc.CallOption) (*MsgCreateUserGroupResponse, error) + // EditUserGroup allows to edit a user group + EditUserGroup(ctx context.Context, in *MsgEditUserGroup, opts ...grpc.CallOption) (*MsgEditUserGroupResponse, error) + // SetUserGroupPermissions allows to set the permissions for a specific group + SetUserGroupPermissions(ctx context.Context, in *MsgSetUserGroupPermissions, opts ...grpc.CallOption) (*MsgSetUserGroupPermissionsResponse, error) // DeleteUserGroup allows to delete an existing user group DeleteUserGroup(ctx context.Context, in *MsgDeleteUserGroup, opts ...grpc.CallOption) (*MsgDeleteUserGroupResponse, error) // AddUserToUserGroup allows to add a specific user to a specific user group @@ -903,8 +1159,8 @@ type MsgClient interface { // RemoveUserFromUserGroup allows to remove a specific user from a specific // user group RemoveUserFromUserGroup(ctx context.Context, in *MsgRemoveUserFromUserGroup, opts ...grpc.CallOption) (*MsgRemoveUserFromUserGroupResponse, error) - // SetPermissions allows to set another user's permissions - SetPermissions(ctx context.Context, in *MsgSetPermissions, opts ...grpc.CallOption) (*MsgSetPermissionsResponse, error) + // SetUserPermissions allows to set the permissions for a specific user + SetUserPermissions(ctx context.Context, in *MsgSetUserPermissions, opts ...grpc.CallOption) (*MsgSetUserPermissionsResponse, error) } type msgClient struct { @@ -951,6 +1207,24 @@ func (c *msgClient) CreateUserGroup(ctx context.Context, in *MsgCreateUserGroup, return out, nil } +func (c *msgClient) EditUserGroup(ctx context.Context, in *MsgEditUserGroup, opts ...grpc.CallOption) (*MsgEditUserGroupResponse, error) { + out := new(MsgEditUserGroupResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/EditUserGroup", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) SetUserGroupPermissions(ctx context.Context, in *MsgSetUserGroupPermissions, opts ...grpc.CallOption) (*MsgSetUserGroupPermissionsResponse, error) { + out := new(MsgSetUserGroupPermissionsResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/SetUserGroupPermissions", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *msgClient) DeleteUserGroup(ctx context.Context, in *MsgDeleteUserGroup, opts ...grpc.CallOption) (*MsgDeleteUserGroupResponse, error) { out := new(MsgDeleteUserGroupResponse) err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/DeleteUserGroup", in, out, opts...) @@ -978,9 +1252,9 @@ func (c *msgClient) RemoveUserFromUserGroup(ctx context.Context, in *MsgRemoveUs return out, nil } -func (c *msgClient) SetPermissions(ctx context.Context, in *MsgSetPermissions, opts ...grpc.CallOption) (*MsgSetPermissionsResponse, error) { - out := new(MsgSetPermissionsResponse) - err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/SetPermissions", in, out, opts...) +func (c *msgClient) SetUserPermissions(ctx context.Context, in *MsgSetUserPermissions, opts ...grpc.CallOption) (*MsgSetUserPermissionsResponse, error) { + out := new(MsgSetUserPermissionsResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Msg/SetUserPermissions", in, out, opts...) if err != nil { return nil, err } @@ -997,6 +1271,10 @@ type MsgServer interface { DeleteSubspace(context.Context, *MsgDeleteSubspace) (*MsgDeleteSubspaceResponse, error) // CreateUserGroup allows to create a user group CreateUserGroup(context.Context, *MsgCreateUserGroup) (*MsgCreateUserGroupResponse, error) + // EditUserGroup allows to edit a user group + EditUserGroup(context.Context, *MsgEditUserGroup) (*MsgEditUserGroupResponse, error) + // SetUserGroupPermissions allows to set the permissions for a specific group + SetUserGroupPermissions(context.Context, *MsgSetUserGroupPermissions) (*MsgSetUserGroupPermissionsResponse, error) // DeleteUserGroup allows to delete an existing user group DeleteUserGroup(context.Context, *MsgDeleteUserGroup) (*MsgDeleteUserGroupResponse, error) // AddUserToUserGroup allows to add a specific user to a specific user group @@ -1004,8 +1282,8 @@ type MsgServer interface { // RemoveUserFromUserGroup allows to remove a specific user from a specific // user group RemoveUserFromUserGroup(context.Context, *MsgRemoveUserFromUserGroup) (*MsgRemoveUserFromUserGroupResponse, error) - // SetPermissions allows to set another user's permissions - SetPermissions(context.Context, *MsgSetPermissions) (*MsgSetPermissionsResponse, error) + // SetUserPermissions allows to set the permissions for a specific user + SetUserPermissions(context.Context, *MsgSetUserPermissions) (*MsgSetUserPermissionsResponse, error) } // UnimplementedMsgServer can be embedded to have forward compatible implementations. @@ -1024,6 +1302,12 @@ func (*UnimplementedMsgServer) DeleteSubspace(ctx context.Context, req *MsgDelet func (*UnimplementedMsgServer) CreateUserGroup(ctx context.Context, req *MsgCreateUserGroup) (*MsgCreateUserGroupResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateUserGroup not implemented") } +func (*UnimplementedMsgServer) EditUserGroup(ctx context.Context, req *MsgEditUserGroup) (*MsgEditUserGroupResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method EditUserGroup not implemented") +} +func (*UnimplementedMsgServer) SetUserGroupPermissions(ctx context.Context, req *MsgSetUserGroupPermissions) (*MsgSetUserGroupPermissionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetUserGroupPermissions not implemented") +} func (*UnimplementedMsgServer) DeleteUserGroup(ctx context.Context, req *MsgDeleteUserGroup) (*MsgDeleteUserGroupResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteUserGroup not implemented") } @@ -1033,8 +1317,8 @@ func (*UnimplementedMsgServer) AddUserToUserGroup(ctx context.Context, req *MsgA func (*UnimplementedMsgServer) RemoveUserFromUserGroup(ctx context.Context, req *MsgRemoveUserFromUserGroup) (*MsgRemoveUserFromUserGroupResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method RemoveUserFromUserGroup not implemented") } -func (*UnimplementedMsgServer) SetPermissions(ctx context.Context, req *MsgSetPermissions) (*MsgSetPermissionsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method SetPermissions not implemented") +func (*UnimplementedMsgServer) SetUserPermissions(ctx context.Context, req *MsgSetUserPermissions) (*MsgSetUserPermissionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetUserPermissions not implemented") } func RegisterMsgServer(s grpc1.Server, srv MsgServer) { @@ -1113,6 +1397,42 @@ func _Msg_CreateUserGroup_Handler(srv interface{}, ctx context.Context, dec func return interceptor(ctx, in, info, handler) } +func _Msg_EditUserGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgEditUserGroup) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).EditUserGroup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/EditUserGroup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).EditUserGroup(ctx, req.(*MsgEditUserGroup)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_SetUserGroupPermissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSetUserGroupPermissions) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).SetUserGroupPermissions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Msg/SetUserGroupPermissions", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).SetUserGroupPermissions(ctx, req.(*MsgSetUserGroupPermissions)) + } + return interceptor(ctx, in, info, handler) +} + func _Msg_DeleteUserGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MsgDeleteUserGroup) if err := dec(in); err != nil { @@ -1167,20 +1487,20 @@ func _Msg_RemoveUserFromUserGroup_Handler(srv interface{}, ctx context.Context, return interceptor(ctx, in, info, handler) } -func _Msg_SetPermissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MsgSetPermissions) +func _Msg_SetUserPermissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgSetUserPermissions) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(MsgServer).SetPermissions(ctx, in) + return srv.(MsgServer).SetUserPermissions(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/desmos.subspaces.v1.Msg/SetPermissions", + FullMethod: "/desmos.subspaces.v1.Msg/SetUserPermissions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MsgServer).SetPermissions(ctx, req.(*MsgSetPermissions)) + return srv.(MsgServer).SetUserPermissions(ctx, req.(*MsgSetUserPermissions)) } return interceptor(ctx, in, info, handler) } @@ -1205,6 +1525,14 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ MethodName: "CreateUserGroup", Handler: _Msg_CreateUserGroup_Handler, }, + { + MethodName: "EditUserGroup", + Handler: _Msg_EditUserGroup_Handler, + }, + { + MethodName: "SetUserGroupPermissions", + Handler: _Msg_SetUserGroupPermissions_Handler, + }, { MethodName: "DeleteUserGroup", Handler: _Msg_DeleteUserGroup_Handler, @@ -1218,8 +1546,8 @@ var _Msg_serviceDesc = grpc.ServiceDesc{ Handler: _Msg_RemoveUserFromUserGroup_Handler, }, { - MethodName: "SetPermissions", - Handler: _Msg_SetPermissions_Handler, + MethodName: "SetUserPermissions", + Handler: _Msg_SetUserPermissions_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -1481,17 +1809,24 @@ func (m *MsgCreateUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Creator) i = encodeVarintMsgs(dAtA, i, uint64(len(m.Creator))) i-- - dAtA[i] = 0x22 + dAtA[i] = 0x2a } if m.DefaultPermissions != 0 { i = encodeVarintMsgs(dAtA, i, uint64(m.DefaultPermissions)) i-- - dAtA[i] = 0x18 + dAtA[i] = 0x20 + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x1a } - if len(m.GroupName) > 0 { - i -= len(m.GroupName) - copy(dAtA[i:], m.GroupName) - i = encodeVarintMsgs(dAtA, i, uint64(len(m.GroupName))) + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Name))) i-- dAtA[i] = 0x12 } @@ -1523,10 +1858,15 @@ func (m *MsgCreateUserGroupResponse) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l + if m.GroupID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.GroupID)) + i-- + dAtA[i] = 0x8 + } return len(dAtA) - i, nil } -func (m *MsgDeleteUserGroup) Marshal() (dAtA []byte, err error) { +func (m *MsgEditUserGroup) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1536,12 +1876,12 @@ func (m *MsgDeleteUserGroup) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MsgDeleteUserGroup) MarshalTo(dAtA []byte) (int, error) { +func (m *MsgEditUserGroup) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgDeleteUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MsgEditUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1551,18 +1891,161 @@ func (m *MsgDeleteUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { copy(dAtA[i:], m.Signer) i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer))) i-- - dAtA[i] = 0x1a + dAtA[i] = 0x2a } - if len(m.GroupName) > 0 { - i -= len(m.GroupName) - copy(dAtA[i:], m.GroupName) - i = encodeVarintMsgs(dAtA, i, uint64(len(m.GroupName))) + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Description))) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x22 } - if m.SubspaceID != 0 { - i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) - i-- + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x1a + } + if m.GroupID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.GroupID)) + i-- + dAtA[i] = 0x10 + } + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgEditUserGroupResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgEditUserGroupResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgEditUserGroupResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgSetUserGroupPermissions) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetUserGroupPermissions) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetUserGroupPermissions) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x22 + } + if m.Permissions != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.Permissions)) + i-- + dAtA[i] = 0x18 + } + if m.GroupID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.GroupID)) + i-- + dAtA[i] = 0x10 + } + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MsgSetUserGroupPermissionsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgSetUserGroupPermissionsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgSetUserGroupPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgDeleteUserGroup) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MsgDeleteUserGroup) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgDeleteUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Signer) > 0 { + i -= len(m.Signer) + copy(dAtA[i:], m.Signer) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.Signer))) + i-- + dAtA[i] = 0x1a + } + if m.GroupID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.GroupID)) + i-- + dAtA[i] = 0x10 + } + if m.SubspaceID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) + i-- dAtA[i] = 0x8 } return len(dAtA) - i, nil @@ -1618,19 +2101,17 @@ func (m *MsgAddUserToUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - if len(m.GroupName) > 0 { - i -= len(m.GroupName) - copy(dAtA[i:], m.GroupName) - i = encodeVarintMsgs(dAtA, i, uint64(len(m.GroupName))) - i-- - dAtA[i] = 0x1a - } if len(m.User) > 0 { i -= len(m.User) copy(dAtA[i:], m.User) i = encodeVarintMsgs(dAtA, i, uint64(len(m.User))) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a + } + if m.GroupID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.GroupID)) + i-- + dAtA[i] = 0x10 } if m.SubspaceID != 0 { i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) @@ -1690,19 +2171,17 @@ func (m *MsgRemoveUserFromUserGroup) MarshalToSizedBuffer(dAtA []byte) (int, err i-- dAtA[i] = 0x22 } - if len(m.GroupName) > 0 { - i -= len(m.GroupName) - copy(dAtA[i:], m.GroupName) - i = encodeVarintMsgs(dAtA, i, uint64(len(m.GroupName))) - i-- - dAtA[i] = 0x1a - } if len(m.User) > 0 { i -= len(m.User) copy(dAtA[i:], m.User) i = encodeVarintMsgs(dAtA, i, uint64(len(m.User))) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x1a + } + if m.GroupID != 0 { + i = encodeVarintMsgs(dAtA, i, uint64(m.GroupID)) + i-- + dAtA[i] = 0x10 } if m.SubspaceID != 0 { i = encodeVarintMsgs(dAtA, i, uint64(m.SubspaceID)) @@ -1735,7 +2214,7 @@ func (m *MsgRemoveUserFromUserGroupResponse) MarshalToSizedBuffer(dAtA []byte) ( return len(dAtA) - i, nil } -func (m *MsgSetPermissions) Marshal() (dAtA []byte, err error) { +func (m *MsgSetUserPermissions) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1745,12 +2224,12 @@ func (m *MsgSetPermissions) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MsgSetPermissions) MarshalTo(dAtA []byte) (int, error) { +func (m *MsgSetUserPermissions) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgSetPermissions) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MsgSetUserPermissions) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1767,10 +2246,10 @@ func (m *MsgSetPermissions) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x18 } - if len(m.Target) > 0 { - i -= len(m.Target) - copy(dAtA[i:], m.Target) - i = encodeVarintMsgs(dAtA, i, uint64(len(m.Target))) + if len(m.User) > 0 { + i -= len(m.User) + copy(dAtA[i:], m.User) + i = encodeVarintMsgs(dAtA, i, uint64(len(m.User))) i-- dAtA[i] = 0x12 } @@ -1782,7 +2261,7 @@ func (m *MsgSetPermissions) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *MsgSetPermissionsResponse) Marshal() (dAtA []byte, err error) { +func (m *MsgSetUserPermissionsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1792,12 +2271,12 @@ func (m *MsgSetPermissionsResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *MsgSetPermissionsResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *MsgSetUserPermissionsResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *MsgSetPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *MsgSetUserPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1932,7 +2411,11 @@ func (m *MsgCreateUserGroup) Size() (n int) { if m.SubspaceID != 0 { n += 1 + sovMsgs(uint64(m.SubspaceID)) } - l = len(m.GroupName) + l = len(m.Name) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Description) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } @@ -1952,10 +2435,13 @@ func (m *MsgCreateUserGroupResponse) Size() (n int) { } var l int _ = l + if m.GroupID != 0 { + n += 1 + sovMsgs(uint64(m.GroupID)) + } return n } -func (m *MsgDeleteUserGroup) Size() (n int) { +func (m *MsgEditUserGroup) Size() (n int) { if m == nil { return 0 } @@ -1964,7 +2450,14 @@ func (m *MsgDeleteUserGroup) Size() (n int) { if m.SubspaceID != 0 { n += 1 + sovMsgs(uint64(m.SubspaceID)) } - l = len(m.GroupName) + if m.GroupID != 0 { + n += 1 + sovMsgs(uint64(m.GroupID)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + l = len(m.Description) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } @@ -1975,7 +2468,7 @@ func (m *MsgDeleteUserGroup) Size() (n int) { return n } -func (m *MsgDeleteUserGroupResponse) Size() (n int) { +func (m *MsgEditUserGroupResponse) Size() (n int) { if m == nil { return 0 } @@ -1984,7 +2477,7 @@ func (m *MsgDeleteUserGroupResponse) Size() (n int) { return n } -func (m *MsgAddUserToUserGroup) Size() (n int) { +func (m *MsgSetUserGroupPermissions) Size() (n int) { if m == nil { return 0 } @@ -1993,11 +2486,69 @@ func (m *MsgAddUserToUserGroup) Size() (n int) { if m.SubspaceID != 0 { n += 1 + sovMsgs(uint64(m.SubspaceID)) } - l = len(m.User) + if m.GroupID != 0 { + n += 1 + sovMsgs(uint64(m.GroupID)) + } + if m.Permissions != 0 { + n += 1 + sovMsgs(uint64(m.Permissions)) + } + l = len(m.Signer) + if l > 0 { + n += 1 + l + sovMsgs(uint64(l)) + } + return n +} + +func (m *MsgSetUserGroupPermissionsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgDeleteUserGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) + } + if m.GroupID != 0 { + n += 1 + sovMsgs(uint64(m.GroupID)) + } + l = len(m.Signer) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } - l = len(m.GroupName) + return n +} + +func (m *MsgDeleteUserGroupResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgAddUserToUserGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovMsgs(uint64(m.SubspaceID)) + } + if m.GroupID != 0 { + n += 1 + sovMsgs(uint64(m.GroupID)) + } + l = len(m.User) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } @@ -2026,11 +2577,10 @@ func (m *MsgRemoveUserFromUserGroup) Size() (n int) { if m.SubspaceID != 0 { n += 1 + sovMsgs(uint64(m.SubspaceID)) } - l = len(m.User) - if l > 0 { - n += 1 + l + sovMsgs(uint64(l)) + if m.GroupID != 0 { + n += 1 + sovMsgs(uint64(m.GroupID)) } - l = len(m.GroupName) + l = len(m.User) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } @@ -2050,7 +2600,7 @@ func (m *MsgRemoveUserFromUserGroupResponse) Size() (n int) { return n } -func (m *MsgSetPermissions) Size() (n int) { +func (m *MsgSetUserPermissions) Size() (n int) { if m == nil { return 0 } @@ -2059,7 +2609,7 @@ func (m *MsgSetPermissions) Size() (n int) { if m.SubspaceID != 0 { n += 1 + sovMsgs(uint64(m.SubspaceID)) } - l = len(m.Target) + l = len(m.User) if l > 0 { n += 1 + l + sovMsgs(uint64(l)) } @@ -2073,7 +2623,7 @@ func (m *MsgSetPermissions) Size() (n int) { return n } -func (m *MsgSetPermissionsResponse) Size() (n int) { +func (m *MsgSetUserPermissionsResponse) Size() (n int) { if m == nil { return 0 } @@ -2480,10 +3030,440 @@ func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { m.Description = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Treasury = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgEditSubspaceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgEditSubspaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgEditSubspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDeleteSubspace) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDeleteSubspace: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDeleteSubspace: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Signer = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgDeleteSubspaceResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgDeleteSubspaceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgDeleteSubspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipMsgs(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMsgs + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MsgCreateUserGroup: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCreateUserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + } + m.SubspaceID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultPermissions", wireType) } - var stringLen uint64 + m.DefaultPermissions = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgs @@ -2493,59 +3473,14 @@ func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.DefaultPermissions |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgs - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgs - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Treasury = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowMsgs - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgs - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgs - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Owner = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2573,7 +3508,7 @@ func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Signer = string(dAtA[iNdEx:postIndex]) + m.Creator = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2596,7 +3531,7 @@ func (m *MsgEditSubspace) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgEditSubspaceResponse) Unmarshal(dAtA []byte) error { +func (m *MsgCreateUserGroupResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2619,12 +3554,31 @@ func (m *MsgEditSubspaceResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgEditSubspaceResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgCreateUserGroupResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgEditSubspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgCreateUserGroupResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupID", wireType) + } + m.GroupID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GroupID |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipMsgs(dAtA[iNdEx:]) @@ -2646,7 +3600,7 @@ func (m *MsgEditSubspaceResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgDeleteSubspace) Unmarshal(dAtA []byte) error { +func (m *MsgEditUserGroup) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2669,10 +3623,10 @@ func (m *MsgDeleteSubspace) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgDeleteSubspace: wiretype end group for non-group") + return fmt.Errorf("proto: MsgEditUserGroup: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgDeleteSubspace: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgEditUserGroup: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2695,6 +3649,89 @@ func (m *MsgDeleteSubspace) Unmarshal(dAtA []byte) error { } } case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupID", wireType) + } + m.GroupID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GroupID |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMsgs + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMsgs + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMsgs + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } @@ -2747,7 +3784,7 @@ func (m *MsgDeleteSubspace) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgDeleteSubspaceResponse) Unmarshal(dAtA []byte) error { +func (m *MsgEditUserGroupResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2770,10 +3807,10 @@ func (m *MsgDeleteSubspaceResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgDeleteSubspaceResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgEditUserGroupResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgDeleteSubspaceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgEditUserGroupResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -2797,7 +3834,7 @@ func (m *MsgDeleteSubspaceResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { +func (m *MsgSetUserGroupPermissions) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2820,10 +3857,10 @@ func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgCreateUserGroup: wiretype end group for non-group") + return fmt.Errorf("proto: MsgSetUserGroupPermissions: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgCreateUserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgSetUserGroupPermissions: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2846,10 +3883,10 @@ func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupID", wireType) } - var stringLen uint64 + m.GroupID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgs @@ -2859,29 +3896,16 @@ func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.GroupID |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgs - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgs - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.GroupName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field DefaultPermissions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) } - m.DefaultPermissions = 0 + m.Permissions = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgs @@ -2891,14 +3915,14 @@ func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.DefaultPermissions |= uint32(b&0x7F) << shift + m.Permissions |= uint32(b&0x7F) << shift if b < 0x80 { break } } case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2926,7 +3950,7 @@ func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Creator = string(dAtA[iNdEx:postIndex]) + m.Signer = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2949,7 +3973,7 @@ func (m *MsgCreateUserGroup) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgCreateUserGroupResponse) Unmarshal(dAtA []byte) error { +func (m *MsgSetUserGroupPermissionsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2972,10 +3996,10 @@ func (m *MsgCreateUserGroupResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgCreateUserGroupResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgSetUserGroupPermissionsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgCreateUserGroupResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgSetUserGroupPermissionsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: @@ -3048,10 +4072,10 @@ func (m *MsgDeleteUserGroup) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupID", wireType) } - var stringLen uint64 + m.GroupID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgs @@ -3061,24 +4085,11 @@ func (m *MsgDeleteUserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.GroupID |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgs - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgs - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.GroupName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Signer", wireType) @@ -3231,10 +4242,10 @@ func (m *MsgAddUserToUserGroup) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupID", wireType) } - var stringLen uint64 + m.GroupID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgs @@ -3244,27 +4255,14 @@ func (m *MsgAddUserToUserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.GroupID |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgs - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgs - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.User = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3292,7 +4290,7 @@ func (m *MsgAddUserToUserGroup) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.GroupName = string(dAtA[iNdEx:postIndex]) + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { @@ -3446,10 +4444,10 @@ func (m *MsgRemoveUserFromUserGroup) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupID", wireType) } - var stringLen uint64 + m.GroupID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowMsgs @@ -3459,27 +4457,14 @@ func (m *MsgRemoveUserFromUserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.GroupID |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthMsgs - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthMsgs - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.User = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3507,7 +4492,7 @@ func (m *MsgRemoveUserFromUserGroup) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.GroupName = string(dAtA[iNdEx:postIndex]) + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { @@ -3612,7 +4597,7 @@ func (m *MsgRemoveUserFromUserGroupResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSetPermissions) Unmarshal(dAtA []byte) error { +func (m *MsgSetUserPermissions) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3635,10 +4620,10 @@ func (m *MsgSetPermissions) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgSetPermissions: wiretype end group for non-group") + return fmt.Errorf("proto: MsgSetUserPermissions: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSetPermissions: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgSetUserPermissions: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -3662,7 +4647,7 @@ func (m *MsgSetPermissions) Unmarshal(dAtA []byte) error { } case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -3690,7 +4675,7 @@ func (m *MsgSetPermissions) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Target = string(dAtA[iNdEx:postIndex]) + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 3: if wireType != 0 { @@ -3764,7 +4749,7 @@ func (m *MsgSetPermissions) Unmarshal(dAtA []byte) error { } return nil } -func (m *MsgSetPermissionsResponse) Unmarshal(dAtA []byte) error { +func (m *MsgSetUserPermissionsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -3787,10 +4772,10 @@ func (m *MsgSetPermissionsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: MsgSetPermissionsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: MsgSetUserPermissionsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: MsgSetPermissionsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: MsgSetUserPermissionsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { default: diff --git a/x/subspaces/types/msgs_test.go b/x/subspaces/types/msgs_test.go index 3166f71451..a0b40cb0ad 100644 --- a/x/subspaces/types/msgs_test.go +++ b/x/subspaces/types/msgs_test.go @@ -246,7 +246,8 @@ func TestMsgDeleteSubspace_GetSigners(t *testing.T) { var msgCreateUserGroup = types.NewMsgCreateUserGroup( 1, - "group", + "Group", + "Description", types.PermissionWrite, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ) @@ -270,6 +271,7 @@ func TestMsgCreateUserGroup_ValidateBasic(t *testing.T) { msg: types.NewMsgCreateUserGroup( 0, "group", + "description", types.PermissionWrite, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -280,6 +282,7 @@ func TestMsgCreateUserGroup_ValidateBasic(t *testing.T) { msg: types.NewMsgCreateUserGroup( 1, "", + "description", types.PermissionWrite, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -290,6 +293,7 @@ func TestMsgCreateUserGroup_ValidateBasic(t *testing.T) { msg: types.NewMsgCreateUserGroup( 1, "group", + "description", types.PermissionWrite, "cosmos1m0czrla04f7rp3zg7dsgc4kl", ), @@ -315,7 +319,7 @@ func TestMsgCreateUserGroup_ValidateBasic(t *testing.T) { } func TestMsgCreateUserGroup_GetSignBytes(t *testing.T) { - expected := `{"creator":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","default_permissions":1,"group_name":"group","subspace_id":"1"}` + expected := `{"creator":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","default_permissions":1,"description":"Description","name":"Group","subspace_id":"1"}` require.Equal(t, expected, string(msgCreateUserGroup.GetSignBytes())) } @@ -326,9 +330,177 @@ func TestMsgCreateUserGroup_GetSigners(t *testing.T) { // -------------------------------------------------------------------------------------------------------------------- +var msgEditUserGroup = types.NewMsgEditUserGroup( + 1, + 1, + "Group", + "Description", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", +) + +func TestMsgEditUserGroup_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgEditUserGroup.Route()) +} + +func TestMsgEditUserGroup_Type(t *testing.T) { + require.Equal(t, types.ActionEditUserGroup, msgEditUserGroup.Type()) +} + +func TestMsgEditUserGroup_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgEditUserGroup + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types.NewMsgEditUserGroup( + 0, + 1, + "group", + "description", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid group name returns error", + msg: types.NewMsgEditUserGroup( + 1, + 0, + "group", + "description", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid creator returns error", + msg: types.NewMsgEditUserGroup( + 1, + 1, + "group", + "description", + "cosmos1m0czrla04f7rp3zg7dsgc4kl", + ), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgEditUserGroup, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgEditUserGroup_GetSignBytes(t *testing.T) { + expected := `{"description":"Description","group_id":1,"name":"Group","signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1"}` + require.Equal(t, expected, string(msgEditUserGroup.GetSignBytes())) +} + +func TestMsgEditUserGroup_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgEditUserGroup.Signer) + require.Equal(t, []sdk.AccAddress{addr}, msgEditUserGroup.GetSigners()) +} + +// -------------------------------------------------------------------------------------------------------------------- + +var msgSetUserGroupPermissions = types.NewMsgSetUserGroupPermissions( + 1, + 1, + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", +) + +func TestMsgSetUserGroupPermissions_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgSetUserGroupPermissions.Route()) +} + +func TestMsgSetUserGroupPermissions_Type(t *testing.T) { + require.Equal(t, types.ActionSetUserGroupPermissions, msgSetUserGroupPermissions.Type()) +} + +func TestMsgSetUserGroupPermissions_ValidateBasic(t *testing.T) { + testCases := []struct { + name string + msg *types.MsgSetUserGroupPermissions + shouldErr bool + }{ + { + name: "invalid subspace id returns error", + msg: types.NewMsgSetUserGroupPermissions( + 0, + 1, + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid group id returns error", + msg: types.NewMsgSetUserGroupPermissions( + 1, + 0, + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "invalid creator returns error", + msg: types.NewMsgSetUserGroupPermissions( + 1, + 1, + types.PermissionWrite, + "cosmos1m0czrla04f7rp3zg7dsgc4kl", + ), + shouldErr: true, + }, + { + name: "valid message returns no error", + msg: msgSetUserGroupPermissions, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + err := tc.msg.ValidateBasic() + if tc.shouldErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestMsgSetUserGroupPermissions_GetSignBytes(t *testing.T) { + expected := `{"group_id":1,"permissions":1,"signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1"}` + require.Equal(t, expected, string(msgSetUserGroupPermissions.GetSignBytes())) +} + +func TestMsgSetUserGroupPermissions_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgSetUserGroupPermissions.Signer) + require.Equal(t, []sdk.AccAddress{addr}, msgSetUserGroupPermissions.GetSigners()) +} + +// -------------------------------------------------------------------------------------------------------------------- + var msgDeleteUserGroup = types.NewMsgDeleteUserGroup( 1, - "group", + 1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ) @@ -350,16 +522,16 @@ func TestMsgDeleteUserGroup_ValidateBasic(t *testing.T) { name: "invalid subspace id returns error", msg: types.NewMsgDeleteUserGroup( 0, - "group", + 1, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), shouldErr: true, }, { - name: "invalid group name returns error", + name: "invalid group id returns error", msg: types.NewMsgDeleteUserGroup( 1, - "", + 0, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), shouldErr: true, @@ -368,7 +540,7 @@ func TestMsgDeleteUserGroup_ValidateBasic(t *testing.T) { name: "invalid signer returns error", msg: types.NewMsgDeleteUserGroup( 1, - "group", + 1, "cosmos1m0czrla04f7rp3zg7dsgc4kl", ), shouldErr: true, @@ -393,7 +565,7 @@ func TestMsgDeleteUserGroup_ValidateBasic(t *testing.T) { } func TestMsgDeleteUserGroup_GetSignBytes(t *testing.T) { - expected := `{"group_name":"group","signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1"}` + expected := `{"group_id":1,"signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1"}` require.Equal(t, expected, string(msgDeleteUserGroup.GetSignBytes())) } @@ -406,7 +578,7 @@ func TestMsgDeleteUserGroup_GetSigners(t *testing.T) { var msgAddUserToGroup = types.NewMsgAddUserToUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ) @@ -429,17 +601,17 @@ func TestMsgAddUserToUserGroup_ValidateBasic(t *testing.T) { name: "invalid subspace id returns error", msg: types.NewMsgAddUserToUserGroup( 0, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), shouldErr: true, }, { - name: "invalid group name returns error", + name: "invalid group id returns error", msg: types.NewMsgAddUserToUserGroup( 1, - "", + 0, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -449,7 +621,7 @@ func TestMsgAddUserToUserGroup_ValidateBasic(t *testing.T) { name: "invalid user returns error", msg: types.NewMsgAddUserToUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znn", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -459,7 +631,7 @@ func TestMsgAddUserToUserGroup_ValidateBasic(t *testing.T) { name: "invalid signer returns error", msg: types.NewMsgAddUserToUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7d", ), @@ -485,7 +657,7 @@ func TestMsgAddUserToUserGroup_ValidateBasic(t *testing.T) { } func TestMsgAddUserToUserGroup_GetSignBytes(t *testing.T) { - expected := `{"group_name":"group","signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","user":"cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"}` + expected := `{"group_id":1,"signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","user":"cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"}` require.Equal(t, expected, string(msgAddUserToGroup.GetSignBytes())) } @@ -498,7 +670,7 @@ func TestMsgAddUserToUserGroup_GetSigners(t *testing.T) { var msgRemoveUserFromUserGroup = types.NewMsgRemoveUserFromUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ) @@ -521,17 +693,17 @@ func TestMsgRemoveUserFromUserGroup_ValidateBasic(t *testing.T) { name: "invalid subspace id returns error", msg: types.NewMsgRemoveUserFromUserGroup( 0, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), shouldErr: true, }, { - name: "invalid group name returns error", + name: "invalid group id returns error", msg: types.NewMsgRemoveUserFromUserGroup( 1, - "", + 0, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -541,7 +713,7 @@ func TestMsgRemoveUserFromUserGroup_ValidateBasic(t *testing.T) { name: "invalid user returns error", msg: types.NewMsgRemoveUserFromUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znn", "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ), @@ -551,7 +723,7 @@ func TestMsgRemoveUserFromUserGroup_ValidateBasic(t *testing.T) { name: "invalid signer returns error", msg: types.NewMsgRemoveUserFromUserGroup( 1, - "group", + 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", "cosmos1m0czrla04f7rp3zg7d", ), @@ -577,7 +749,7 @@ func TestMsgRemoveUserFromUserGroup_ValidateBasic(t *testing.T) { } func TestMsgRemoveUserFromUserGroup_GetSignBytes(t *testing.T) { - expected := `{"group_name":"group","signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","user":"cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"}` + expected := `{"group_id":1,"signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","user":"cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"}` require.Equal(t, expected, string(msgRemoveUserFromUserGroup.GetSignBytes())) } @@ -587,30 +759,30 @@ func TestMsgRemoveUserFromUserGroup_GetSigners(t *testing.T) { } // -------------------------------------------------------------------------------------------------------------------- -var msgSetPermissions = types.NewMsgSetPermissions( +var msgSetUserPermissions = types.NewMsgSetUserPermissions( 1, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", types.PermissionWrite, "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", ) -func TestMsgSetPermissions_Route(t *testing.T) { - require.Equal(t, types.RouterKey, msgSetPermissions.Route()) +func TestMsgSetUserPermissions_Route(t *testing.T) { + require.Equal(t, types.RouterKey, msgSetUserPermissions.Route()) } -func TestMsgSetPermissions_Type(t *testing.T) { - require.Equal(t, types.ActionSetPermissions, msgSetPermissions.Type()) +func TestMsgSetUserPermissions_Type(t *testing.T) { + require.Equal(t, types.ActionSetUserPermissions, msgSetUserPermissions.Type()) } -func TestMsgSetPermissions_ValidateBasic(t *testing.T) { +func TestMsgSetUserPermissions_ValidateBasic(t *testing.T) { testCases := []struct { name string - msg *types.MsgSetPermissions + msg *types.MsgSetUserPermissions shouldErr bool }{ { name: "invalid subspace id returns error", - msg: types.NewMsgSetPermissions( + msg: types.NewMsgSetUserPermissions( 0, "group", types.PermissionWrite, @@ -620,7 +792,7 @@ func TestMsgSetPermissions_ValidateBasic(t *testing.T) { }, { name: "invalid target returns error", - msg: types.NewMsgSetPermissions( + msg: types.NewMsgSetUserPermissions( 1, "", types.PermissionWrite, @@ -630,7 +802,7 @@ func TestMsgSetPermissions_ValidateBasic(t *testing.T) { }, { name: "invalid signer returns error", - msg: types.NewMsgSetPermissions( + msg: types.NewMsgSetUserPermissions( 1, "group", types.PermissionWrite, @@ -640,7 +812,7 @@ func TestMsgSetPermissions_ValidateBasic(t *testing.T) { }, { name: "valid message returns no error", - msg: msgSetPermissions, + msg: msgSetUserPermissions, }, } @@ -657,12 +829,12 @@ func TestMsgSetPermissions_ValidateBasic(t *testing.T) { } } -func TestMsgSetPermissions_GetSignBytes(t *testing.T) { - expected := `{"permissions":1,"signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","target":"cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"}` - require.Equal(t, expected, string(msgSetPermissions.GetSignBytes())) +func TestMsgSetUserPermissions_GetSignBytes(t *testing.T) { + expected := `{"permissions":1,"signer":"cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5","subspace_id":"1","user":"cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"}` + require.Equal(t, expected, string(msgSetUserPermissions.GetSignBytes())) } -func TestMsgSetPermissions_GetSigners(t *testing.T) { - addr, _ := sdk.AccAddressFromBech32(msgSetPermissions.Signer) - require.Equal(t, []sdk.AccAddress{addr}, msgSetPermissions.GetSigners()) +func TestMsgSetUserPermissions_GetSigners(t *testing.T) { + addr, _ := sdk.AccAddressFromBech32(msgSetUserPermissions.Signer) + require.Equal(t, []sdk.AccAddress{addr}, msgSetUserPermissions.GetSigners()) } diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go index a258e38a0c..11ce4020af 100644 --- a/x/subspaces/types/permissions.go +++ b/x/subspaces/types/permissions.go @@ -37,34 +37,35 @@ const ( PermissionEverything = Permission(0b111111) ) +var ( + permissionsMap = map[Permission]string{ + PermissionNothing: "Nothing", + PermissionWrite: "Write", + PermissionModerateContent: "ModerateContent", + PermissionChangeInfo: "ChangeInfo", + PermissionManageGroups: "ManageGroups", + PermissionSetPermissions: "SetUserPermissions", + PermissionEverything: "Everything", + } +) + // ParsePermission parses the given permission string as a single Permissions instance func ParsePermission(permission string) (Permission, error) { - switch { - case strings.EqualFold(permission, "nothing"): - return PermissionNothing, nil - - case strings.EqualFold(permission, "Write"): - return PermissionWrite, nil - - case strings.EqualFold(permission, "ModerateContent"): - return PermissionModerateContent, nil - - case strings.EqualFold(permission, "ChangeInfo"): - return PermissionChangeInfo, nil - - case strings.EqualFold(permission, "ManageGroups"): - return PermissionManageGroups, nil - - case strings.EqualFold(permission, "SetPermissions"): - return PermissionSetPermissions, nil - - case strings.EqualFold(permission, "Everything"): - return PermissionEverything, nil + // Check inside the map if we have anything here + for permValue, permString := range permissionsMap { + if strings.EqualFold(permission, permString) { + return permValue, nil + } } return 0, fmt.Errorf("invalid permission value: %s", permission) } +// SerializePermission serializes the given permission to a string value +func SerializePermission(permission Permission) string { + return permissionsMap[permission] +} + // MarshalPermission marshals the given permission to a byte array func MarshalPermission(permission Permission) (permissionBytes []byte) { permissionBytes = make([]byte, 4) diff --git a/x/subspaces/types/query.go b/x/subspaces/types/query.go index 7a93397d8e..3ef53c6012 100644 --- a/x/subspaces/types/query.go +++ b/x/subspaces/types/query.go @@ -24,21 +24,29 @@ func NewQueryUserGroupsRequest(subspaceID uint64, pagination *query.PageRequest) } } +// NewQueryUserGroupRequest returns a new QueryUserGroupRequest instance +func NewQueryUserGroupRequest(subspaceID uint64, groupID uint32) *QueryUserGroupRequest { + return &QueryUserGroupRequest{ + SubspaceId: subspaceID, + GroupId: groupID, + } +} + // NewQueryUserGroupMembersRequest returns a new QueryUserGroupMembersRequest instance func NewQueryUserGroupMembersRequest( - subspaceID uint64, groupName string, pagination *query.PageRequest, + subspaceID uint64, groupID uint32, pagination *query.PageRequest, ) *QueryUserGroupMembersRequest { return &QueryUserGroupMembersRequest{ SubspaceId: subspaceID, - GroupName: groupName, + GroupId: groupID, Pagination: pagination, } } -// NewQueryPermissionsRequest returns a new QueryPermissionsRequest instance -func NewQueryPermissionsRequest(subspaceID uint64, target string) *QueryPermissionsRequest { - return &QueryPermissionsRequest{ +// NewQueryUserPermissionsRequest returns a new QueryPermissionsRequest instance +func NewQueryUserPermissionsRequest(subspaceID uint64, user string) *QueryUserPermissionsRequest { + return &QueryUserPermissionsRequest{ SubspaceId: subspaceID, - Target: target, + User: user, } } diff --git a/x/subspaces/types/query.pb.go b/x/subspaces/types/query.pb.go index 5c37b815e5..8dc7de992b 100644 --- a/x/subspaces/types/query.pb.go +++ b/x/subspaces/types/query.pb.go @@ -30,89 +30,6 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package -// QuerySubspace is the request type for the Query/Subspace RPC method -type QuerySubspaceRequest struct { - SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` -} - -func (m *QuerySubspaceRequest) Reset() { *m = QuerySubspaceRequest{} } -func (m *QuerySubspaceRequest) String() string { return proto.CompactTextString(m) } -func (*QuerySubspaceRequest) ProtoMessage() {} -func (*QuerySubspaceRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_883a12b013a133fc, []int{0} -} -func (m *QuerySubspaceRequest) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QuerySubspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QuerySubspaceRequest.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QuerySubspaceRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QuerySubspaceRequest.Merge(m, src) -} -func (m *QuerySubspaceRequest) XXX_Size() int { - return m.Size() -} -func (m *QuerySubspaceRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QuerySubspaceRequest.DiscardUnknown(m) -} - -var xxx_messageInfo_QuerySubspaceRequest proto.InternalMessageInfo - -// QuerySubspaceResponse is the response type for the Query/Subspace method -type QuerySubspaceResponse struct { - Subspace Subspace `protobuf:"bytes,1,opt,name=subspace,proto3" json:"subspace"` -} - -func (m *QuerySubspaceResponse) Reset() { *m = QuerySubspaceResponse{} } -func (m *QuerySubspaceResponse) String() string { return proto.CompactTextString(m) } -func (*QuerySubspaceResponse) ProtoMessage() {} -func (*QuerySubspaceResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_883a12b013a133fc, []int{1} -} -func (m *QuerySubspaceResponse) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *QuerySubspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_QuerySubspaceResponse.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *QuerySubspaceResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QuerySubspaceResponse.Merge(m, src) -} -func (m *QuerySubspaceResponse) XXX_Size() int { - return m.Size() -} -func (m *QuerySubspaceResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QuerySubspaceResponse.DiscardUnknown(m) -} - -var xxx_messageInfo_QuerySubspaceResponse proto.InternalMessageInfo - -func (m *QuerySubspaceResponse) GetSubspace() Subspace { - if m != nil { - return m.Subspace - } - return Subspace{} -} - // QuerySubspacesRequest is the request type for the Query/Subspaces RPC method type QuerySubspacesRequest struct { // pagination defines an optional pagination for the request. @@ -123,7 +40,7 @@ func (m *QuerySubspacesRequest) Reset() { *m = QuerySubspacesRequest{} } func (m *QuerySubspacesRequest) String() string { return proto.CompactTextString(m) } func (*QuerySubspacesRequest) ProtoMessage() {} func (*QuerySubspacesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_883a12b013a133fc, []int{2} + return fileDescriptor_883a12b013a133fc, []int{0} } func (m *QuerySubspacesRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -170,7 +87,7 @@ func (m *QuerySubspacesResponse) Reset() { *m = QuerySubspacesResponse{} func (m *QuerySubspacesResponse) String() string { return proto.CompactTextString(m) } func (*QuerySubspacesResponse) ProtoMessage() {} func (*QuerySubspacesResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_883a12b013a133fc, []int{3} + return fileDescriptor_883a12b013a133fc, []int{1} } func (m *QuerySubspacesResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -213,6 +130,89 @@ func (m *QuerySubspacesResponse) GetPagination() *query.PageResponse { return nil } +// QuerySubspace is the request type for the Query/Subspace RPC method +type QuerySubspaceRequest struct { + SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` +} + +func (m *QuerySubspaceRequest) Reset() { *m = QuerySubspaceRequest{} } +func (m *QuerySubspaceRequest) String() string { return proto.CompactTextString(m) } +func (*QuerySubspaceRequest) ProtoMessage() {} +func (*QuerySubspaceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{2} +} +func (m *QuerySubspaceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySubspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySubspaceRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySubspaceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySubspaceRequest.Merge(m, src) +} +func (m *QuerySubspaceRequest) XXX_Size() int { + return m.Size() +} +func (m *QuerySubspaceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySubspaceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySubspaceRequest proto.InternalMessageInfo + +// QuerySubspaceResponse is the response type for the Query/Subspace method +type QuerySubspaceResponse struct { + Subspace Subspace `protobuf:"bytes,1,opt,name=subspace,proto3" json:"subspace"` +} + +func (m *QuerySubspaceResponse) Reset() { *m = QuerySubspaceResponse{} } +func (m *QuerySubspaceResponse) String() string { return proto.CompactTextString(m) } +func (*QuerySubspaceResponse) ProtoMessage() {} +func (*QuerySubspaceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{3} +} +func (m *QuerySubspaceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QuerySubspaceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QuerySubspaceResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QuerySubspaceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QuerySubspaceResponse.Merge(m, src) +} +func (m *QuerySubspaceResponse) XXX_Size() int { + return m.Size() +} +func (m *QuerySubspaceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QuerySubspaceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QuerySubspaceResponse proto.InternalMessageInfo + +func (m *QuerySubspaceResponse) GetSubspace() Subspace { + if m != nil { + return m.Subspace + } + return Subspace{} +} + // QueryUserGroupsRequest is the request type for the Query/UserGroups RPC // method type QueryUserGroupsRequest struct { @@ -271,7 +271,7 @@ func (m *QueryUserGroupsRequest) GetPagination() *query.PageRequest { // QueryUserGroupsResponse is the response type for the Query/UserGroups RPC // method type QueryUserGroupsResponse struct { - Groups []string `protobuf:"bytes,1,rep,name=groups,proto3" json:"groups,omitempty"` + Groups []UserGroup `protobuf:"bytes,1,rep,name=groups,proto3" json:"groups"` Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -308,7 +308,7 @@ func (m *QueryUserGroupsResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryUserGroupsResponse proto.InternalMessageInfo -func (m *QueryUserGroupsResponse) GetGroups() []string { +func (m *QueryUserGroupsResponse) GetGroups() []UserGroup { if m != nil { return m.Groups } @@ -322,11 +322,110 @@ func (m *QueryUserGroupsResponse) GetPagination() *query.PageResponse { return nil } +// QueryUserGroupRequest is the request type for the Query/UserGroup RPC method +type QueryUserGroupRequest struct { + SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` + GroupId uint32 `protobuf:"varint,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty" yaml:"group_id"` +} + +func (m *QueryUserGroupRequest) Reset() { *m = QueryUserGroupRequest{} } +func (m *QueryUserGroupRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUserGroupRequest) ProtoMessage() {} +func (*QueryUserGroupRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{6} +} +func (m *QueryUserGroupRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUserGroupRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUserGroupRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUserGroupRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUserGroupRequest.Merge(m, src) +} +func (m *QueryUserGroupRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryUserGroupRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUserGroupRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUserGroupRequest proto.InternalMessageInfo + +func (m *QueryUserGroupRequest) GetSubspaceId() uint64 { + if m != nil { + return m.SubspaceId + } + return 0 +} + +func (m *QueryUserGroupRequest) GetGroupId() uint32 { + if m != nil { + return m.GroupId + } + return 0 +} + +// QueryUserGroupResponse is the response type for the Query/UserGroup RPC +// method +type QueryUserGroupResponse struct { + Group UserGroup `protobuf:"bytes,1,opt,name=group,proto3" json:"group"` +} + +func (m *QueryUserGroupResponse) Reset() { *m = QueryUserGroupResponse{} } +func (m *QueryUserGroupResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUserGroupResponse) ProtoMessage() {} +func (*QueryUserGroupResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{7} +} +func (m *QueryUserGroupResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryUserGroupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryUserGroupResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryUserGroupResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUserGroupResponse.Merge(m, src) +} +func (m *QueryUserGroupResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryUserGroupResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUserGroupResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryUserGroupResponse proto.InternalMessageInfo + +func (m *QueryUserGroupResponse) GetGroup() UserGroup { + if m != nil { + return m.Group + } + return UserGroup{} +} + // QueryUserGroupMembersRequest is the request type for the // Query/UserGroupMembers RPC method type QueryUserGroupMembersRequest struct { SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` - GroupName string `protobuf:"bytes,2,opt,name=group_name,json=groupName,proto3" json:"group_name,omitempty" yaml:"group_name"` + GroupId uint32 `protobuf:"varint,2,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty" yaml:"group_id"` // pagination defines an optional pagination for the request. Pagination *query.PageRequest `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -335,7 +434,7 @@ func (m *QueryUserGroupMembersRequest) Reset() { *m = QueryUserGroupMemb func (m *QueryUserGroupMembersRequest) String() string { return proto.CompactTextString(m) } func (*QueryUserGroupMembersRequest) ProtoMessage() {} func (*QueryUserGroupMembersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_883a12b013a133fc, []int{6} + return fileDescriptor_883a12b013a133fc, []int{8} } func (m *QueryUserGroupMembersRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -371,11 +470,11 @@ func (m *QueryUserGroupMembersRequest) GetSubspaceId() uint64 { return 0 } -func (m *QueryUserGroupMembersRequest) GetGroupName() string { +func (m *QueryUserGroupMembersRequest) GetGroupId() uint32 { if m != nil { - return m.GroupName + return m.GroupId } - return "" + return 0 } func (m *QueryUserGroupMembersRequest) GetPagination() *query.PageRequest { @@ -396,7 +495,7 @@ func (m *QueryUserGroupMembersResponse) Reset() { *m = QueryUserGroupMem func (m *QueryUserGroupMembersResponse) String() string { return proto.CompactTextString(m) } func (*QueryUserGroupMembersResponse) ProtoMessage() {} func (*QueryUserGroupMembersResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_883a12b013a133fc, []int{7} + return fileDescriptor_883a12b013a133fc, []int{9} } func (m *QueryUserGroupMembersResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -439,24 +538,25 @@ func (m *QueryUserGroupMembersResponse) GetPagination() *query.PageResponse { return nil } -// QuerySubspace is the request type for the Query/Subspace RPC method -type QueryPermissionsRequest struct { +// QueryUserPermissionsRequest is the request type for the Query/UserPermissions +// RPC method +type QueryUserPermissionsRequest struct { SubspaceId uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` - Target string `protobuf:"bytes,2,opt,name=target,proto3" json:"target,omitempty" yaml:"target"` + User string `protobuf:"bytes,2,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` } -func (m *QueryPermissionsRequest) Reset() { *m = QueryPermissionsRequest{} } -func (m *QueryPermissionsRequest) String() string { return proto.CompactTextString(m) } -func (*QueryPermissionsRequest) ProtoMessage() {} -func (*QueryPermissionsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_883a12b013a133fc, []int{8} +func (m *QueryUserPermissionsRequest) Reset() { *m = QueryUserPermissionsRequest{} } +func (m *QueryUserPermissionsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryUserPermissionsRequest) ProtoMessage() {} +func (*QueryUserPermissionsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{10} } -func (m *QueryPermissionsRequest) XXX_Unmarshal(b []byte) error { +func (m *QueryUserPermissionsRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryPermissionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryUserPermissionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryPermissionsRequest.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryUserPermissionsRequest.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -466,35 +566,36 @@ func (m *QueryPermissionsRequest) XXX_Marshal(b []byte, deterministic bool) ([]b return b[:n], nil } } -func (m *QueryPermissionsRequest) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryPermissionsRequest.Merge(m, src) +func (m *QueryUserPermissionsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUserPermissionsRequest.Merge(m, src) } -func (m *QueryPermissionsRequest) XXX_Size() int { +func (m *QueryUserPermissionsRequest) XXX_Size() int { return m.Size() } -func (m *QueryPermissionsRequest) XXX_DiscardUnknown() { - xxx_messageInfo_QueryPermissionsRequest.DiscardUnknown(m) +func (m *QueryUserPermissionsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUserPermissionsRequest.DiscardUnknown(m) } -var xxx_messageInfo_QueryPermissionsRequest proto.InternalMessageInfo +var xxx_messageInfo_QueryUserPermissionsRequest proto.InternalMessageInfo -// QuerySubspaceResponse is the response type for the Query/Subspace method -type QueryPermissionsResponse struct { +// QueryUserPermissionsRequest is the response type for the +// Query/UserPermissions method +type QueryUserPermissionsResponse struct { Permissions uint32 `protobuf:"varint,1,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` } -func (m *QueryPermissionsResponse) Reset() { *m = QueryPermissionsResponse{} } -func (m *QueryPermissionsResponse) String() string { return proto.CompactTextString(m) } -func (*QueryPermissionsResponse) ProtoMessage() {} -func (*QueryPermissionsResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_883a12b013a133fc, []int{9} +func (m *QueryUserPermissionsResponse) Reset() { *m = QueryUserPermissionsResponse{} } +func (m *QueryUserPermissionsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryUserPermissionsResponse) ProtoMessage() {} +func (*QueryUserPermissionsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_883a12b013a133fc, []int{11} } -func (m *QueryPermissionsResponse) XXX_Unmarshal(b []byte) error { +func (m *QueryUserPermissionsResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) } -func (m *QueryPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { +func (m *QueryUserPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { if deterministic { - return xxx_messageInfo_QueryPermissionsResponse.Marshal(b, m, deterministic) + return xxx_messageInfo_QueryUserPermissionsResponse.Marshal(b, m, deterministic) } else { b = b[:cap(b)] n, err := m.MarshalToSizedBuffer(b) @@ -504,19 +605,19 @@ func (m *QueryPermissionsResponse) XXX_Marshal(b []byte, deterministic bool) ([] return b[:n], nil } } -func (m *QueryPermissionsResponse) XXX_Merge(src proto.Message) { - xxx_messageInfo_QueryPermissionsResponse.Merge(m, src) +func (m *QueryUserPermissionsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryUserPermissionsResponse.Merge(m, src) } -func (m *QueryPermissionsResponse) XXX_Size() int { +func (m *QueryUserPermissionsResponse) XXX_Size() int { return m.Size() } -func (m *QueryPermissionsResponse) XXX_DiscardUnknown() { - xxx_messageInfo_QueryPermissionsResponse.DiscardUnknown(m) +func (m *QueryUserPermissionsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryUserPermissionsResponse.DiscardUnknown(m) } -var xxx_messageInfo_QueryPermissionsResponse proto.InternalMessageInfo +var xxx_messageInfo_QueryUserPermissionsResponse proto.InternalMessageInfo -func (m *QueryPermissionsResponse) GetPermissions() uint32 { +func (m *QueryUserPermissionsResponse) GetPermissions() uint32 { if m != nil { return m.Permissions } @@ -524,69 +625,75 @@ func (m *QueryPermissionsResponse) GetPermissions() uint32 { } func init() { - proto.RegisterType((*QuerySubspaceRequest)(nil), "desmos.subspaces.v1.QuerySubspaceRequest") - proto.RegisterType((*QuerySubspaceResponse)(nil), "desmos.subspaces.v1.QuerySubspaceResponse") proto.RegisterType((*QuerySubspacesRequest)(nil), "desmos.subspaces.v1.QuerySubspacesRequest") proto.RegisterType((*QuerySubspacesResponse)(nil), "desmos.subspaces.v1.QuerySubspacesResponse") + proto.RegisterType((*QuerySubspaceRequest)(nil), "desmos.subspaces.v1.QuerySubspaceRequest") + proto.RegisterType((*QuerySubspaceResponse)(nil), "desmos.subspaces.v1.QuerySubspaceResponse") proto.RegisterType((*QueryUserGroupsRequest)(nil), "desmos.subspaces.v1.QueryUserGroupsRequest") proto.RegisterType((*QueryUserGroupsResponse)(nil), "desmos.subspaces.v1.QueryUserGroupsResponse") + proto.RegisterType((*QueryUserGroupRequest)(nil), "desmos.subspaces.v1.QueryUserGroupRequest") + proto.RegisterType((*QueryUserGroupResponse)(nil), "desmos.subspaces.v1.QueryUserGroupResponse") proto.RegisterType((*QueryUserGroupMembersRequest)(nil), "desmos.subspaces.v1.QueryUserGroupMembersRequest") proto.RegisterType((*QueryUserGroupMembersResponse)(nil), "desmos.subspaces.v1.QueryUserGroupMembersResponse") - proto.RegisterType((*QueryPermissionsRequest)(nil), "desmos.subspaces.v1.QueryPermissionsRequest") - proto.RegisterType((*QueryPermissionsResponse)(nil), "desmos.subspaces.v1.QueryPermissionsResponse") + proto.RegisterType((*QueryUserPermissionsRequest)(nil), "desmos.subspaces.v1.QueryUserPermissionsRequest") + proto.RegisterType((*QueryUserPermissionsResponse)(nil), "desmos.subspaces.v1.QueryUserPermissionsResponse") } func init() { proto.RegisterFile("desmos/subspaces/v1/query.proto", fileDescriptor_883a12b013a133fc) } var fileDescriptor_883a12b013a133fc = []byte{ - // 741 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x96, 0x4f, 0x4f, 0x13, 0x4f, - 0x18, 0xc7, 0x3b, 0xc0, 0xaf, 0x3f, 0xfa, 0x34, 0x24, 0x32, 0x02, 0x36, 0x1b, 0xd8, 0x25, 0x1b, - 0x83, 0x02, 0xb2, 0x93, 0x56, 0x13, 0x94, 0x83, 0x68, 0x0f, 0x10, 0x13, 0x35, 0xb8, 0x6a, 0xa2, - 0x5e, 0xc8, 0x2e, 0x4c, 0xd6, 0x26, 0x6c, 0x77, 0xd9, 0xd9, 0x36, 0x22, 0xe1, 0xc2, 0x45, 0x0f, - 0x9a, 0x98, 0x78, 0xd2, 0x13, 0x07, 0x6f, 0x9e, 0x7d, 0x01, 0xde, 0x38, 0x92, 0x18, 0x13, 0x4f, - 0x8d, 0x01, 0x0f, 0x9e, 0x79, 0x05, 0xa6, 0xb3, 0x33, 0xed, 0xf6, 0x8f, 0xb0, 0x02, 0xb7, 0xce, - 0xcc, 0xf7, 0x79, 0x9e, 0xcf, 0x7c, 0xa7, 0xcf, 0xd3, 0x82, 0xb6, 0x4a, 0x99, 0xeb, 0x31, 0xc2, - 0x2a, 0x36, 0xf3, 0xad, 0x15, 0xca, 0x48, 0x35, 0x4f, 0xd6, 0x2b, 0x34, 0xd8, 0x30, 0xfc, 0xc0, - 0x0b, 0x3d, 0x7c, 0x3e, 0x12, 0x18, 0x0d, 0x81, 0x51, 0xcd, 0x2b, 0x43, 0x8e, 0xe7, 0x78, 0xfc, - 0x9c, 0xd4, 0x3f, 0x45, 0x52, 0x65, 0xd4, 0xf1, 0x3c, 0x67, 0x8d, 0x12, 0xcb, 0x2f, 0x11, 0xab, - 0x5c, 0xf6, 0x42, 0x2b, 0x2c, 0x79, 0x65, 0x26, 0x4e, 0xf5, 0x6e, 0x95, 0xe4, 0x42, 0x68, 0xa6, - 0x56, 0x3c, 0xae, 0xb1, 0x2d, 0x46, 0x23, 0x0a, 0x52, 0xcd, 0xdb, 0x34, 0xb4, 0xf2, 0xc4, 0xb7, - 0x9c, 0x52, 0x99, 0x27, 0x8c, 0xb4, 0xfa, 0x53, 0x18, 0x7a, 0x50, 0x57, 0x3c, 0x14, 0x29, 0x4c, - 0xba, 0x5e, 0xa1, 0x2c, 0xc4, 0xb3, 0x90, 0x95, 0x59, 0x97, 0x4b, 0xab, 0x39, 0x34, 0x8e, 0x2e, - 0xf7, 0x15, 0x47, 0x0e, 0x6b, 0x1a, 0xde, 0xb0, 0xdc, 0xb5, 0x39, 0x3d, 0x76, 0xa8, 0x9b, 0x20, - 0x57, 0x77, 0x56, 0xe7, 0xfa, 0x5f, 0xef, 0x68, 0xa9, 0xdf, 0x3b, 0x5a, 0x4a, 0x7f, 0x02, 0xc3, - 0x6d, 0xa9, 0x99, 0xef, 0x95, 0x19, 0xc5, 0xf3, 0xd0, 0x2f, 0x03, 0x78, 0xe2, 0x6c, 0x61, 0xcc, - 0xe8, 0xe2, 0x8f, 0x21, 0x03, 0x8b, 0x7d, 0xbb, 0x35, 0x2d, 0x65, 0x36, 0x82, 0xf4, 0xe5, 0xb6, - 0xcc, 0x4c, 0x52, 0x2f, 0x00, 0x34, 0x6f, 0x28, 0x72, 0x4f, 0x18, 0x91, 0x1d, 0x46, 0xdd, 0x0e, - 0x23, 0x7a, 0x14, 0x61, 0x87, 0xb1, 0x64, 0x39, 0xf2, 0xc6, 0x66, 0x2c, 0x52, 0xff, 0x84, 0x60, - 0xa4, 0xbd, 0x82, 0x80, 0xbf, 0x0d, 0x99, 0x06, 0x64, 0x0e, 0x8d, 0xf7, 0x26, 0xa5, 0x6f, 0x46, - 0xe1, 0xc5, 0x16, 0xca, 0x1e, 0x4e, 0x79, 0xe9, 0x58, 0xca, 0xa8, 0x7e, 0x0b, 0xe6, 0x07, 0x89, - 0xf9, 0x98, 0xd1, 0x60, 0x31, 0xf0, 0x2a, 0x3e, 0x3b, 0xed, 0xfb, 0xb5, 0x59, 0xd8, 0x73, 0x62, - 0x0b, 0x5f, 0xc2, 0x85, 0x0e, 0x34, 0x61, 0xe1, 0x08, 0xa4, 0x1d, 0xbe, 0xc3, 0xfd, 0xcb, 0x98, - 0x62, 0x75, 0x76, 0xbe, 0x7c, 0x47, 0x30, 0xda, 0x5a, 0xfc, 0x1e, 0x75, 0x6d, 0x1a, 0x9c, 0xde, - 0x9d, 0x6b, 0x00, 0x1c, 0x76, 0xb9, 0x6c, 0xb9, 0x94, 0x23, 0x66, 0x8a, 0xc3, 0x87, 0x35, 0x6d, - 0x30, 0x8a, 0x6b, 0x9e, 0xe9, 0x66, 0x86, 0x2f, 0xee, 0x5b, 0x2e, 0x6d, 0xf3, 0xb4, 0xf7, 0xc4, - 0x9e, 0x6e, 0x23, 0x18, 0xfb, 0xcb, 0xbd, 0x84, 0xb5, 0x39, 0xf8, 0xdf, 0x8d, 0xb6, 0x84, 0xb7, - 0x72, 0x79, 0x76, 0xe6, 0xbe, 0x42, 0xe2, 0x65, 0x97, 0x68, 0xe0, 0x96, 0x18, 0xab, 0x0f, 0xa7, - 0x53, 0xfb, 0x3a, 0x09, 0xe9, 0xd0, 0x0a, 0x1c, 0x1a, 0x0a, 0x4f, 0x07, 0x0f, 0x6b, 0xda, 0x40, - 0x14, 0x13, 0xed, 0xeb, 0xa6, 0x10, 0xc4, 0x06, 0xcc, 0x23, 0xc8, 0x75, 0x82, 0x08, 0x23, 0xae, - 0x43, 0xd6, 0x6f, 0x6e, 0x73, 0x92, 0x81, 0x38, 0x49, 0xec, 0x50, 0x37, 0xe3, 0xd2, 0xc2, 0x97, - 0x34, 0xfc, 0xc7, 0xd3, 0xe2, 0xb7, 0x08, 0xfa, 0x65, 0x17, 0xe3, 0xc9, 0xae, 0x4d, 0xde, 0x6d, - 0x76, 0x2a, 0x53, 0x49, 0xa4, 0x11, 0xa7, 0x3e, 0xb5, 0xfd, 0xed, 0xd7, 0xfb, 0x9e, 0x8b, 0x58, - 0x27, 0xdd, 0x06, 0xfb, 0x66, 0xcc, 0xb0, 0x2d, 0xfc, 0x06, 0x41, 0xa6, 0x31, 0x90, 0x70, 0x82, - 0x2a, 0xf2, 0x5d, 0x94, 0xe9, 0x44, 0x5a, 0x81, 0x34, 0xc1, 0x91, 0xc6, 0xb1, 0x4a, 0x8e, 0xfa, - 0xad, 0x61, 0xf8, 0x23, 0x02, 0x68, 0x76, 0x37, 0x3e, 0xa2, 0x46, 0xc7, 0x78, 0x52, 0xae, 0x24, - 0x13, 0x0b, 0xa2, 0x3c, 0x27, 0x9a, 0xc6, 0x93, 0xc7, 0x9b, 0x44, 0xc4, 0x2c, 0xf9, 0x8a, 0xe0, - 0x5c, 0x7b, 0x97, 0xe0, 0x7c, 0x82, 0xaa, 0xad, 0x93, 0x42, 0x29, 0xfc, 0x4b, 0x88, 0xc0, 0x5d, - 0xe0, 0xb8, 0xb7, 0xf0, 0xcd, 0xc4, 0xb8, 0x64, 0xb3, 0x39, 0x39, 0xb6, 0x88, 0x6c, 0xd9, 0xcf, - 0x08, 0xb2, 0xb1, 0xef, 0x36, 0x3e, 0xc2, 0xb4, 0xce, 0x5e, 0x54, 0x66, 0x12, 0xaa, 0x05, 0xf4, - 0x3c, 0x87, 0xbe, 0x81, 0x67, 0x13, 0x40, 0xc7, 0xda, 0x85, 0x6c, 0x46, 0x6d, 0xb9, 0x55, 0xbc, - 0xbb, 0xbb, 0xaf, 0xa2, 0xbd, 0x7d, 0x15, 0xfd, 0xdc, 0x57, 0xd1, 0xbb, 0x03, 0x35, 0xb5, 0x77, - 0xa0, 0xa6, 0x7e, 0x1c, 0xa8, 0xa9, 0x67, 0x05, 0xa7, 0x14, 0x3e, 0xaf, 0xd8, 0xc6, 0x8a, 0xe7, - 0x8a, 0xe4, 0x33, 0x6b, 0x96, 0xcd, 0x64, 0xa1, 0x6a, 0x81, 0xbc, 0x88, 0x55, 0x0b, 0x37, 0x7c, - 0xca, 0xec, 0x34, 0xff, 0x7b, 0x72, 0xf5, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x14, 0x77, 0xad, - 0x4c, 0x5a, 0x09, 0x00, 0x00, + // 809 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0xcf, 0x6b, 0x13, 0x41, + 0x14, 0xc7, 0x33, 0xfd, 0x99, 0xbc, 0x50, 0x2a, 0xd3, 0x5a, 0x4b, 0x6c, 0x37, 0x61, 0x85, 0xda, + 0x5f, 0xee, 0x9a, 0x58, 0xad, 0x94, 0xaa, 0x18, 0xc4, 0x52, 0x50, 0xa8, 0xab, 0x82, 0x7a, 0x29, + 0x9b, 0x66, 0x58, 0x03, 0x49, 0x76, 0x9b, 0x49, 0x82, 0xa5, 0x14, 0xa4, 0x20, 0x78, 0xf0, 0x20, + 0x78, 0x10, 0x3d, 0x15, 0xf1, 0x5f, 0xf0, 0xec, 0xb5, 0x37, 0x0b, 0x5e, 0x3c, 0x05, 0x69, 0x3d, + 0x78, 0xf0, 0xd4, 0xbf, 0x40, 0x76, 0x76, 0x66, 0xb3, 0xd9, 0xae, 0xe9, 0xf6, 0x07, 0xde, 0x92, + 0x9d, 0xef, 0xf7, 0xbd, 0xcf, 0x7b, 0x6f, 0xf6, 0x25, 0x90, 0xcc, 0x13, 0x5a, 0x32, 0xa9, 0x4a, + 0x6b, 0x39, 0x6a, 0xe9, 0x2b, 0x84, 0xaa, 0xf5, 0xb4, 0xba, 0x5a, 0x23, 0x95, 0x35, 0xc5, 0xaa, + 0x98, 0x55, 0x13, 0x0f, 0x38, 0x02, 0xc5, 0x15, 0x28, 0xf5, 0x74, 0x62, 0xd0, 0x30, 0x0d, 0x93, + 0x9d, 0xab, 0xf6, 0x27, 0x47, 0x9a, 0x18, 0x31, 0x4c, 0xd3, 0x28, 0x12, 0x55, 0xb7, 0x0a, 0xaa, + 0x5e, 0x2e, 0x9b, 0x55, 0xbd, 0x5a, 0x30, 0xcb, 0x94, 0x9f, 0xa6, 0x82, 0x32, 0x95, 0xcc, 0x3c, + 0x29, 0x0a, 0xc5, 0xe4, 0x8a, 0xc9, 0x14, 0x39, 0x9d, 0x12, 0x87, 0x41, 0xad, 0xa7, 0x73, 0xa4, + 0xaa, 0xa7, 0x55, 0x4b, 0x37, 0x0a, 0x65, 0x16, 0xce, 0xd1, 0xca, 0xcb, 0x70, 0xf6, 0x81, 0xad, + 0x78, 0x28, 0xa2, 0x69, 0x64, 0xb5, 0x46, 0x68, 0x15, 0xdf, 0x05, 0x68, 0x8a, 0x87, 0x51, 0x0a, + 0x8d, 0xc7, 0x33, 0x63, 0x8a, 0x13, 0x59, 0xb1, 0x23, 0x2b, 0x4e, 0x75, 0x3c, 0xb2, 0xb2, 0xa4, + 0x1b, 0x84, 0x7b, 0x35, 0x8f, 0x53, 0xfe, 0x8c, 0x60, 0xc8, 0x9f, 0x81, 0x5a, 0x66, 0x99, 0x12, + 0x7c, 0x1b, 0x62, 0x6e, 0x11, 0xc3, 0x28, 0xd5, 0x39, 0x1e, 0xcf, 0x8c, 0x2a, 0x01, 0x6d, 0x52, + 0x84, 0x35, 0xdb, 0xb5, 0xdd, 0x48, 0x46, 0xb4, 0xa6, 0x0b, 0x2f, 0xb4, 0x50, 0x76, 0x30, 0xca, + 0x8b, 0x87, 0x52, 0x3a, 0xf9, 0x5b, 0x30, 0x9f, 0xc2, 0x60, 0x0b, 0xa5, 0x68, 0xc3, 0x2c, 0xc4, + 0x45, 0xb6, 0xe5, 0x42, 0x9e, 0xf5, 0xa1, 0x2b, 0x3b, 0xb4, 0xdf, 0x48, 0xe2, 0x35, 0xbd, 0x54, + 0x9c, 0x93, 0x3d, 0x87, 0xb2, 0x06, 0xe2, 0xdb, 0x62, 0x7e, 0x2e, 0xfa, 0x7a, 0x2b, 0x19, 0xf9, + 0xbd, 0x95, 0x8c, 0xc8, 0x4f, 0x7c, 0x2d, 0x76, 0xeb, 0xbf, 0x05, 0x51, 0x61, 0xe0, 0x0d, 0x0e, + 0x55, 0xbe, 0x6b, 0x92, 0x3f, 0x88, 0xde, 0x3e, 0xa6, 0xa4, 0xb2, 0x50, 0x31, 0x6b, 0x16, 0x3d, + 0x29, 0xb7, 0x6f, 0xee, 0x1d, 0xc7, 0x9e, 0xfb, 0x16, 0x82, 0x73, 0x07, 0xd8, 0x78, 0xe1, 0xf3, + 0xd0, 0x63, 0xb0, 0x27, 0x7c, 0xea, 0x52, 0x60, 0xd9, 0xae, 0x91, 0xd7, 0xcd, 0x3d, 0xa7, 0x37, + 0xf3, 0x97, 0x88, 0x4f, 0xc6, 0xcd, 0x74, 0xe2, 0xee, 0x29, 0x10, 0x65, 0x94, 0xb6, 0xcb, 0x26, + 0xeb, 0xcb, 0x0e, 0xec, 0x37, 0x92, 0xfd, 0x8e, 0x4b, 0x9c, 0xc8, 0x5a, 0x2f, 0xfb, 0xb8, 0x98, + 0x97, 0x1f, 0xf9, 0x07, 0xe8, 0xf6, 0x68, 0x0e, 0xba, 0x99, 0x88, 0xdf, 0x8c, 0x70, 0x2d, 0x72, + 0x2c, 0xf2, 0x37, 0x04, 0x23, 0xad, 0x61, 0xef, 0x93, 0x52, 0x8e, 0x54, 0xe8, 0xff, 0xae, 0xcf, + 0x77, 0x9b, 0x3a, 0x8f, 0x7d, 0x9b, 0x36, 0x11, 0x8c, 0xfe, 0xa3, 0x22, 0xde, 0xaf, 0x61, 0xe8, + 0x2d, 0x39, 0x8f, 0xd8, 0xa5, 0x8a, 0x69, 0xe2, 0xeb, 0xe9, 0xdd, 0x97, 0x57, 0x08, 0xce, 0xbb, + 0x10, 0x4b, 0xa4, 0x52, 0x2a, 0x50, 0x6a, 0x2f, 0xe6, 0x13, 0x77, 0xf5, 0x02, 0x74, 0xd5, 0x28, + 0xa9, 0x30, 0xb6, 0x58, 0xb6, 0x7f, 0xbf, 0x91, 0x8c, 0x3b, 0x0e, 0xfb, 0xa9, 0xac, 0xb1, 0xc3, + 0x96, 0x85, 0x32, 0x12, 0x8c, 0xc1, 0x5b, 0x71, 0x1d, 0xe2, 0x56, 0xf3, 0x31, 0xe3, 0xe8, 0xf3, + 0x72, 0x78, 0x0e, 0x65, 0xcd, 0x2b, 0xcd, 0xfc, 0xe9, 0x85, 0x6e, 0x16, 0x1a, 0xbf, 0x41, 0x10, + 0x73, 0x37, 0x36, 0x9e, 0x0c, 0xbc, 0x7d, 0x81, 0x3f, 0x1c, 0x89, 0xa9, 0x50, 0x5a, 0x07, 0x55, + 0x1e, 0xdb, 0xfc, 0xfe, 0xeb, 0x5d, 0x47, 0x0a, 0x4b, 0x6a, 0xd0, 0xaf, 0x5a, 0x73, 0xcf, 0xbf, + 0x47, 0x10, 0x15, 0x6e, 0x3c, 0x71, 0x78, 0x06, 0x01, 0x33, 0x19, 0x46, 0xca, 0x59, 0x66, 0x18, + 0x8b, 0x82, 0xa7, 0xdb, 0xb3, 0xa8, 0xeb, 0x9e, 0x39, 0x6e, 0xe0, 0x8f, 0x08, 0xa0, 0xb9, 0xe2, + 0x70, 0x9b, 0xea, 0x0f, 0x2c, 0xe9, 0xc4, 0x74, 0x38, 0x31, 0xe7, 0x4b, 0x33, 0xbe, 0x29, 0x3c, + 0x11, 0xc8, 0xe7, 0x2c, 0x47, 0x1f, 0xdc, 0x27, 0x04, 0x31, 0x37, 0x52, 0xbb, 0x29, 0xfa, 0x37, + 0x60, 0x62, 0x2a, 0x94, 0x96, 0x93, 0xcd, 0x33, 0xb2, 0x6b, 0x78, 0x26, 0x34, 0x99, 0xba, 0x2e, + 0x96, 0xc5, 0x06, 0xfe, 0x8a, 0xe0, 0x8c, 0xff, 0xb5, 0xc6, 0xe9, 0x10, 0xf9, 0x5b, 0x97, 0x5a, + 0x22, 0x73, 0x14, 0x0b, 0x27, 0xbf, 0xc3, 0xc8, 0x6f, 0xe2, 0xf9, 0xe3, 0x90, 0xab, 0x62, 0xc3, + 0x7c, 0x41, 0xd0, 0xef, 0x7b, 0x19, 0xf1, 0xe5, 0xf6, 0x34, 0x07, 0xd7, 0x47, 0x22, 0x7d, 0x04, + 0x07, 0xc7, 0xbf, 0xc1, 0xf0, 0x67, 0xf1, 0xd5, 0x40, 0x7c, 0xcf, 0x9b, 0xed, 0xaf, 0xc1, 0xde, + 0x28, 0x1b, 0xd9, 0x7b, 0xdb, 0xbb, 0x12, 0xda, 0xd9, 0x95, 0xd0, 0xcf, 0x5d, 0x09, 0xbd, 0xdd, + 0x93, 0x22, 0x3b, 0x7b, 0x52, 0xe4, 0xc7, 0x9e, 0x14, 0x79, 0x96, 0x31, 0x0a, 0xd5, 0xe7, 0xb5, + 0x9c, 0xb2, 0x62, 0x96, 0x78, 0xe8, 0x4b, 0x45, 0x3d, 0x47, 0x45, 0x9a, 0x7a, 0x46, 0x7d, 0xe1, + 0xc9, 0x55, 0x5d, 0xb3, 0x08, 0xcd, 0xf5, 0xb0, 0x7f, 0x94, 0x57, 0xfe, 0x06, 0x00, 0x00, 0xff, + 0xff, 0x39, 0x10, 0x6e, 0x26, 0x0b, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -601,18 +708,20 @@ const _ = grpc.SupportPackageIsVersion4 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { - // Subspace queries all the information about the subspace with the given id - Subspace(ctx context.Context, in *QuerySubspaceRequest, opts ...grpc.CallOption) (*QuerySubspaceResponse, error) // Subspaces queries all the subspaces inside Desmos Subspaces(ctx context.Context, in *QuerySubspacesRequest, opts ...grpc.CallOption) (*QuerySubspacesResponse, error) + // Subspace queries all the information about the subspace with the given id + Subspace(ctx context.Context, in *QuerySubspaceRequest, opts ...grpc.CallOption) (*QuerySubspaceResponse, error) // UserGroups queries all the groups that are present inside the subspace with // the given id UserGroups(ctx context.Context, in *QueryUserGroupsRequest, opts ...grpc.CallOption) (*QueryUserGroupsResponse, error) + // UserGroup queries the user group having the given id inside the specific + // subspace + UserGroup(ctx context.Context, in *QueryUserGroupRequest, opts ...grpc.CallOption) (*QueryUserGroupResponse, error) // UserGroupMembers queries all the members of a given user group UserGroupMembers(ctx context.Context, in *QueryUserGroupMembersRequest, opts ...grpc.CallOption) (*QueryUserGroupMembersResponse, error) - // Permissions queries the permissions for the given target (user address or - // group name) - Permissions(ctx context.Context, in *QueryPermissionsRequest, opts ...grpc.CallOption) (*QueryPermissionsResponse, error) + // UserPermissions queries the permissions for the given user + UserPermissions(ctx context.Context, in *QueryUserPermissionsRequest, opts ...grpc.CallOption) (*QueryUserPermissionsResponse, error) } type queryClient struct { @@ -623,18 +732,18 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } -func (c *queryClient) Subspace(ctx context.Context, in *QuerySubspaceRequest, opts ...grpc.CallOption) (*QuerySubspaceResponse, error) { - out := new(QuerySubspaceResponse) - err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/Subspace", in, out, opts...) +func (c *queryClient) Subspaces(ctx context.Context, in *QuerySubspacesRequest, opts ...grpc.CallOption) (*QuerySubspacesResponse, error) { + out := new(QuerySubspacesResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/Subspaces", in, out, opts...) if err != nil { return nil, err } return out, nil } -func (c *queryClient) Subspaces(ctx context.Context, in *QuerySubspacesRequest, opts ...grpc.CallOption) (*QuerySubspacesResponse, error) { - out := new(QuerySubspacesResponse) - err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/Subspaces", in, out, opts...) +func (c *queryClient) Subspace(ctx context.Context, in *QuerySubspaceRequest, opts ...grpc.CallOption) (*QuerySubspaceResponse, error) { + out := new(QuerySubspaceResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/Subspace", in, out, opts...) if err != nil { return nil, err } @@ -650,6 +759,15 @@ func (c *queryClient) UserGroups(ctx context.Context, in *QueryUserGroupsRequest return out, nil } +func (c *queryClient) UserGroup(ctx context.Context, in *QueryUserGroupRequest, opts ...grpc.CallOption) (*QueryUserGroupResponse, error) { + out := new(QueryUserGroupResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/UserGroup", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *queryClient) UserGroupMembers(ctx context.Context, in *QueryUserGroupMembersRequest, opts ...grpc.CallOption) (*QueryUserGroupMembersResponse, error) { out := new(QueryUserGroupMembersResponse) err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/UserGroupMembers", in, out, opts...) @@ -659,9 +777,9 @@ func (c *queryClient) UserGroupMembers(ctx context.Context, in *QueryUserGroupMe return out, nil } -func (c *queryClient) Permissions(ctx context.Context, in *QueryPermissionsRequest, opts ...grpc.CallOption) (*QueryPermissionsResponse, error) { - out := new(QueryPermissionsResponse) - err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/Permissions", in, out, opts...) +func (c *queryClient) UserPermissions(ctx context.Context, in *QueryUserPermissionsRequest, opts ...grpc.CallOption) (*QueryUserPermissionsResponse, error) { + out := new(QueryUserPermissionsResponse) + err := c.cc.Invoke(ctx, "/desmos.subspaces.v1.Query/UserPermissions", in, out, opts...) if err != nil { return nil, err } @@ -670,76 +788,81 @@ func (c *queryClient) Permissions(ctx context.Context, in *QueryPermissionsReque // QueryServer is the server API for Query service. type QueryServer interface { - // Subspace queries all the information about the subspace with the given id - Subspace(context.Context, *QuerySubspaceRequest) (*QuerySubspaceResponse, error) // Subspaces queries all the subspaces inside Desmos Subspaces(context.Context, *QuerySubspacesRequest) (*QuerySubspacesResponse, error) + // Subspace queries all the information about the subspace with the given id + Subspace(context.Context, *QuerySubspaceRequest) (*QuerySubspaceResponse, error) // UserGroups queries all the groups that are present inside the subspace with // the given id UserGroups(context.Context, *QueryUserGroupsRequest) (*QueryUserGroupsResponse, error) + // UserGroup queries the user group having the given id inside the specific + // subspace + UserGroup(context.Context, *QueryUserGroupRequest) (*QueryUserGroupResponse, error) // UserGroupMembers queries all the members of a given user group UserGroupMembers(context.Context, *QueryUserGroupMembersRequest) (*QueryUserGroupMembersResponse, error) - // Permissions queries the permissions for the given target (user address or - // group name) - Permissions(context.Context, *QueryPermissionsRequest) (*QueryPermissionsResponse, error) + // UserPermissions queries the permissions for the given user + UserPermissions(context.Context, *QueryUserPermissionsRequest) (*QueryUserPermissionsResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. type UnimplementedQueryServer struct { } -func (*UnimplementedQueryServer) Subspace(ctx context.Context, req *QuerySubspaceRequest) (*QuerySubspaceResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Subspace not implemented") -} func (*UnimplementedQueryServer) Subspaces(ctx context.Context, req *QuerySubspacesRequest) (*QuerySubspacesResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Subspaces not implemented") } +func (*UnimplementedQueryServer) Subspace(ctx context.Context, req *QuerySubspaceRequest) (*QuerySubspaceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Subspace not implemented") +} func (*UnimplementedQueryServer) UserGroups(ctx context.Context, req *QueryUserGroupsRequest) (*QueryUserGroupsResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UserGroups not implemented") } +func (*UnimplementedQueryServer) UserGroup(ctx context.Context, req *QueryUserGroupRequest) (*QueryUserGroupResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UserGroup not implemented") +} func (*UnimplementedQueryServer) UserGroupMembers(ctx context.Context, req *QueryUserGroupMembersRequest) (*QueryUserGroupMembersResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method UserGroupMembers not implemented") } -func (*UnimplementedQueryServer) Permissions(ctx context.Context, req *QueryPermissionsRequest) (*QueryPermissionsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Permissions not implemented") +func (*UnimplementedQueryServer) UserPermissions(ctx context.Context, req *QueryUserPermissionsRequest) (*QueryUserPermissionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UserPermissions not implemented") } func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) } -func _Query_Subspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QuerySubspaceRequest) +func _Query_Subspaces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySubspacesRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).Subspace(ctx, in) + return srv.(QueryServer).Subspaces(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/desmos.subspaces.v1.Query/Subspace", + FullMethod: "/desmos.subspaces.v1.Query/Subspaces", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Subspace(ctx, req.(*QuerySubspaceRequest)) + return srv.(QueryServer).Subspaces(ctx, req.(*QuerySubspacesRequest)) } return interceptor(ctx, in, info, handler) } -func _Query_Subspaces_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QuerySubspacesRequest) +func _Query_Subspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QuerySubspaceRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).Subspaces(ctx, in) + return srv.(QueryServer).Subspace(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/desmos.subspaces.v1.Query/Subspaces", + FullMethod: "/desmos.subspaces.v1.Query/Subspace", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Subspaces(ctx, req.(*QuerySubspacesRequest)) + return srv.(QueryServer).Subspace(ctx, req.(*QuerySubspaceRequest)) } return interceptor(ctx, in, info, handler) } @@ -762,6 +885,24 @@ func _Query_UserGroups_Handler(srv interface{}, ctx context.Context, dec func(in return interceptor(ctx, in, info, handler) } +func _Query_UserGroup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUserGroupRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).UserGroup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/desmos.subspaces.v1.Query/UserGroup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).UserGroup(ctx, req.(*QueryUserGroupRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _Query_UserGroupMembers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(QueryUserGroupMembersRequest) if err := dec(in); err != nil { @@ -780,20 +921,20 @@ func _Query_UserGroupMembers_Handler(srv interface{}, ctx context.Context, dec f return interceptor(ctx, in, info, handler) } -func _Query_Permissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(QueryPermissionsRequest) +func _Query_UserPermissions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryUserPermissionsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(QueryServer).Permissions(ctx, in) + return srv.(QueryServer).UserPermissions(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/desmos.subspaces.v1.Query/Permissions", + FullMethod: "/desmos.subspaces.v1.Query/UserPermissions", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(QueryServer).Permissions(ctx, req.(*QueryPermissionsRequest)) + return srv.(QueryServer).UserPermissions(ctx, req.(*QueryUserPermissionsRequest)) } return interceptor(ctx, in, info, handler) } @@ -802,29 +943,117 @@ var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "desmos.subspaces.v1.Query", HandlerType: (*QueryServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "Subspace", - Handler: _Query_Subspace_Handler, - }, { MethodName: "Subspaces", Handler: _Query_Subspaces_Handler, }, + { + MethodName: "Subspace", + Handler: _Query_Subspace_Handler, + }, { MethodName: "UserGroups", Handler: _Query_UserGroups_Handler, }, + { + MethodName: "UserGroup", + Handler: _Query_UserGroup_Handler, + }, { MethodName: "UserGroupMembers", Handler: _Query_UserGroupMembers_Handler, }, { - MethodName: "Permissions", - Handler: _Query_Permissions_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "desmos/subspaces/v1/query.proto", + MethodName: "UserPermissions", + Handler: _Query_UserPermissions_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "desmos/subspaces/v1/query.proto", +} + +func (m *QuerySubspacesRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySubspacesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySubspacesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QuerySubspacesResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QuerySubspacesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QuerySubspacesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Subspaces) > 0 { + for iNdEx := len(m.Subspaces) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Subspaces[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil } func (m *QuerySubspaceRequest) Marshal() (dAtA []byte, err error) { @@ -888,7 +1117,7 @@ func (m *QuerySubspaceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *QuerySubspacesRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryUserGroupsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -898,12 +1127,12 @@ func (m *QuerySubspacesRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QuerySubspacesRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryUserGroupsRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QuerySubspacesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryUserGroupsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -918,12 +1147,17 @@ func (m *QuerySubspacesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i = encodeVarintQuery(dAtA, i, uint64(size)) } i-- - dAtA[i] = 0xa + dAtA[i] = 0x12 + } + if m.SubspaceId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.SubspaceId)) + i-- + dAtA[i] = 0x8 } return len(dAtA) - i, nil } -func (m *QuerySubspacesResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryUserGroupsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -933,12 +1167,12 @@ func (m *QuerySubspacesResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QuerySubspacesResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryUserGroupsResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QuerySubspacesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryUserGroupsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -955,10 +1189,10 @@ func (m *QuerySubspacesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) i-- dAtA[i] = 0x12 } - if len(m.Subspaces) > 0 { - for iNdEx := len(m.Subspaces) - 1; iNdEx >= 0; iNdEx-- { + if len(m.Groups) > 0 { + for iNdEx := len(m.Groups) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.Subspaces[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Groups[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -972,7 +1206,7 @@ func (m *QuerySubspacesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *QueryUserGroupsRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryUserGroupRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -982,27 +1216,20 @@ func (m *QueryUserGroupsRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryUserGroupsRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryUserGroupRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryUserGroupsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryUserGroupRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } + if m.GroupId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.GroupId)) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x10 } if m.SubspaceId != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.SubspaceId)) @@ -1012,7 +1239,7 @@ func (m *QueryUserGroupsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *QueryUserGroupsResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryUserGroupResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1022,37 +1249,26 @@ func (m *QueryUserGroupsResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryUserGroupsResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryUserGroupResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryUserGroupsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryUserGroupResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.Pagination != nil { - { - size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintQuery(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x12 - } - if len(m.Groups) > 0 { - for iNdEx := len(m.Groups) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.Groups[iNdEx]) - copy(dAtA[i:], m.Groups[iNdEx]) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Groups[iNdEx]))) - i-- - dAtA[i] = 0xa + { + size, err := m.Group.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) } + i-- + dAtA[i] = 0xa return len(dAtA) - i, nil } @@ -1088,12 +1304,10 @@ func (m *QueryUserGroupMembersRequest) MarshalToSizedBuffer(dAtA []byte) (int, e i-- dAtA[i] = 0x1a } - if len(m.GroupName) > 0 { - i -= len(m.GroupName) - copy(dAtA[i:], m.GroupName) - i = encodeVarintQuery(dAtA, i, uint64(len(m.GroupName))) + if m.GroupId != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.GroupId)) i-- - dAtA[i] = 0x12 + dAtA[i] = 0x10 } if m.SubspaceId != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.SubspaceId)) @@ -1147,7 +1361,7 @@ func (m *QueryUserGroupMembersResponse) MarshalToSizedBuffer(dAtA []byte) (int, return len(dAtA) - i, nil } -func (m *QueryPermissionsRequest) Marshal() (dAtA []byte, err error) { +func (m *QueryUserPermissionsRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1157,20 +1371,20 @@ func (m *QueryPermissionsRequest) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryPermissionsRequest) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryUserPermissionsRequest) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryPermissionsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryUserPermissionsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if len(m.Target) > 0 { - i -= len(m.Target) - copy(dAtA[i:], m.Target) - i = encodeVarintQuery(dAtA, i, uint64(len(m.Target))) + if len(m.User) > 0 { + i -= len(m.User) + copy(dAtA[i:], m.User) + i = encodeVarintQuery(dAtA, i, uint64(len(m.User))) i-- dAtA[i] = 0x12 } @@ -1182,7 +1396,7 @@ func (m *QueryPermissionsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) return len(dAtA) - i, nil } -func (m *QueryPermissionsResponse) Marshal() (dAtA []byte, err error) { +func (m *QueryUserPermissionsResponse) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -1192,12 +1406,12 @@ func (m *QueryPermissionsResponse) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *QueryPermissionsResponse) MarshalTo(dAtA []byte) (int, error) { +func (m *QueryUserPermissionsResponse) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *QueryPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *QueryUserPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int @@ -1221,6 +1435,38 @@ func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { dAtA[offset] = uint8(v) return base } +func (m *QuerySubspacesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QuerySubspacesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Subspaces) > 0 { + for _, e := range m.Subspaces { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + func (m *QuerySubspaceRequest) Size() (n int) { if m == nil { return 0 @@ -1244,12 +1490,15 @@ func (m *QuerySubspaceResponse) Size() (n int) { return n } -func (m *QuerySubspacesRequest) Size() (n int) { +func (m *QueryUserGroupsRequest) Size() (n int) { if m == nil { return 0 } var l int _ = l + if m.SubspaceId != 0 { + n += 1 + sovQuery(uint64(m.SubspaceId)) + } if m.Pagination != nil { l = m.Pagination.Size() n += 1 + l + sovQuery(uint64(l)) @@ -1257,14 +1506,14 @@ func (m *QuerySubspacesRequest) Size() (n int) { return n } -func (m *QuerySubspacesResponse) Size() (n int) { +func (m *QueryUserGroupsResponse) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.Subspaces) > 0 { - for _, e := range m.Subspaces { + if len(m.Groups) > 0 { + for _, e := range m.Groups { l = e.Size() n += 1 + l + sovQuery(uint64(l)) } @@ -1276,7 +1525,7 @@ func (m *QuerySubspacesResponse) Size() (n int) { return n } -func (m *QueryUserGroupsRequest) Size() (n int) { +func (m *QueryUserGroupRequest) Size() (n int) { if m == nil { return 0 } @@ -1285,29 +1534,20 @@ func (m *QueryUserGroupsRequest) Size() (n int) { if m.SubspaceId != 0 { n += 1 + sovQuery(uint64(m.SubspaceId)) } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) + if m.GroupId != 0 { + n += 1 + sovQuery(uint64(m.GroupId)) } return n } -func (m *QueryUserGroupsResponse) Size() (n int) { +func (m *QueryUserGroupResponse) Size() (n int) { if m == nil { return 0 } var l int _ = l - if len(m.Groups) > 0 { - for _, s := range m.Groups { - l = len(s) - n += 1 + l + sovQuery(uint64(l)) - } - } - if m.Pagination != nil { - l = m.Pagination.Size() - n += 1 + l + sovQuery(uint64(l)) - } + l = m.Group.Size() + n += 1 + l + sovQuery(uint64(l)) return n } @@ -1320,9 +1560,8 @@ func (m *QueryUserGroupMembersRequest) Size() (n int) { if m.SubspaceId != 0 { n += 1 + sovQuery(uint64(m.SubspaceId)) } - l = len(m.GroupName) - if l > 0 { - n += 1 + l + sovQuery(uint64(l)) + if m.GroupId != 0 { + n += 1 + sovQuery(uint64(m.GroupId)) } if m.Pagination != nil { l = m.Pagination.Size() @@ -1350,7 +1589,7 @@ func (m *QueryUserGroupMembersResponse) Size() (n int) { return n } -func (m *QueryPermissionsRequest) Size() (n int) { +func (m *QueryUserPermissionsRequest) Size() (n int) { if m == nil { return 0 } @@ -1359,30 +1598,236 @@ func (m *QueryPermissionsRequest) Size() (n int) { if m.SubspaceId != 0 { n += 1 + sovQuery(uint64(m.SubspaceId)) } - l = len(m.Target) + l = len(m.User) if l > 0 { n += 1 + l + sovQuery(uint64(l)) } - return n -} + return n +} + +func (m *QueryUserPermissionsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Permissions != 0 { + n += 1 + sovQuery(uint64(m.Permissions)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QuerySubspacesRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySubspacesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySubspacesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } -func (m *QueryPermissionsResponse) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.Permissions != 0 { - n += 1 + sovQuery(uint64(m.Permissions)) + if iNdEx > l { + return io.ErrUnexpectedEOF } - return n + return nil } +func (m *QuerySubspacesResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QuerySubspacesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QuerySubspacesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subspaces", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Subspaces = append(m.Subspaces, Subspace{}) + if err := m.Subspaces[len(m.Subspaces)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } -func sovQuery(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozQuery(x uint64) (n int) { - return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil } func (m *QuerySubspaceRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) @@ -1536,7 +1981,7 @@ func (m *QuerySubspaceResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QuerySubspacesRequest) Unmarshal(dAtA []byte) error { +func (m *QueryUserGroupsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1559,13 +2004,32 @@ func (m *QuerySubspacesRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QuerySubspacesRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUserGroupsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QuerySubspacesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUserGroupsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceId", wireType) + } + m.SubspaceId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SubspaceId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) } @@ -1622,7 +2086,7 @@ func (m *QuerySubspacesRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QuerySubspacesResponse) Unmarshal(dAtA []byte) error { +func (m *QueryUserGroupsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1645,15 +2109,15 @@ func (m *QuerySubspacesResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QuerySubspacesResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUserGroupsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QuerySubspacesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUserGroupsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Subspaces", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Groups", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1680,8 +2144,8 @@ func (m *QuerySubspacesResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Subspaces = append(m.Subspaces, Subspace{}) - if err := m.Subspaces[len(m.Subspaces)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Groups = append(m.Groups, UserGroup{}) + if err := m.Groups[len(m.Groups)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -1742,7 +2206,7 @@ func (m *QuerySubspacesResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryUserGroupsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryUserGroupRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1765,10 +2229,10 @@ func (m *QueryUserGroupsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryUserGroupsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUserGroupRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryUserGroupsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUserGroupRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -1791,10 +2255,10 @@ func (m *QueryUserGroupsRequest) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupId", wireType) } - var msglen int + m.GroupId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -1804,28 +2268,11 @@ func (m *QueryUserGroupsRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + m.GroupId |= uint32(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if m.Pagination == nil { - m.Pagination = &query.PageRequest{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) @@ -1847,7 +2294,7 @@ func (m *QueryUserGroupsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryUserGroupsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryUserGroupResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -1870,47 +2317,15 @@ func (m *QueryUserGroupsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryUserGroupsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUserGroupResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryUserGroupsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUserGroupResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Groups", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowQuery - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Groups = append(m.Groups, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -1937,10 +2352,7 @@ func (m *QueryUserGroupsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Pagination == nil { - m.Pagination = &query.PageResponse{} - } - if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Group.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -2014,10 +2426,10 @@ func (m *QueryUserGroupMembersRequest) Unmarshal(dAtA []byte) error { } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field GroupName", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupId", wireType) } - var stringLen uint64 + m.GroupId = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowQuery @@ -2027,24 +2439,11 @@ func (m *QueryUserGroupMembersRequest) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.GroupId |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthQuery - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthQuery - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.GroupName = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) @@ -2220,7 +2619,7 @@ func (m *QueryUserGroupMembersResponse) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryPermissionsRequest) Unmarshal(dAtA []byte) error { +func (m *QueryUserPermissionsRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2243,10 +2642,10 @@ func (m *QueryPermissionsRequest) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryPermissionsRequest: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUserPermissionsRequest: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryPermissionsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUserPermissionsRequest: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -2270,7 +2669,7 @@ func (m *QueryPermissionsRequest) Unmarshal(dAtA []byte) error { } case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Target", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -2298,7 +2697,7 @@ func (m *QueryPermissionsRequest) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Target = string(dAtA[iNdEx:postIndex]) + m.User = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex default: iNdEx = preIndex @@ -2321,7 +2720,7 @@ func (m *QueryPermissionsRequest) Unmarshal(dAtA []byte) error { } return nil } -func (m *QueryPermissionsResponse) Unmarshal(dAtA []byte) error { +func (m *QueryUserPermissionsResponse) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -2344,10 +2743,10 @@ func (m *QueryPermissionsResponse) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: QueryPermissionsResponse: wiretype end group for non-group") + return fmt.Errorf("proto: QueryUserPermissionsResponse: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: QueryPermissionsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: QueryUserPermissionsResponse: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: diff --git a/x/subspaces/types/query.pb.gw.go b/x/subspaces/types/query.pb.gw.go index 844c4da071..21fa099642 100644 --- a/x/subspaces/types/query.pb.gw.go +++ b/x/subspaces/types/query.pb.gw.go @@ -31,6 +31,42 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = descriptor.ForMessage +var ( + filter_Query_Subspaces_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_Subspaces_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySubspacesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Subspaces_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Subspaces(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Subspaces_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QuerySubspacesRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Subspaces_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Subspaces(ctx, &protoReq) + return msg, metadata, err + +} + func request_Query_Subspace_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq QuerySubspaceRequest var metadata runtime.ServerMetadata @@ -86,47 +122,79 @@ func local_request_Query_Subspace_0(ctx context.Context, marshaler runtime.Marsh } var ( - filter_Query_Subspaces_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} + filter_Query_UserGroups_0 = &utilities.DoubleArray{Encoding: map[string]int{"subspace_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} ) -func request_Query_Subspaces_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QuerySubspacesRequest +func request_Query_UserGroups_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserGroupsRequest var metadata runtime.ServerMetadata + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Subspaces_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UserGroups_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := client.Subspaces(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.UserGroups(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_Subspaces_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QuerySubspacesRequest +func local_request_Query_UserGroups_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserGroupsRequest var metadata runtime.ServerMetadata + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["subspace_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "subspace_id") + } + + protoReq.SubspaceId, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) + } + if err := req.ParseForm(); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_Subspaces_0); err != nil { + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UserGroups_0); err != nil { return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) } - msg, err := server.Subspaces(ctx, &protoReq) + msg, err := server.UserGroups(ctx, &protoReq) return msg, metadata, err } -var ( - filter_Query_UserGroups_0 = &utilities.DoubleArray{Encoding: map[string]int{"subspace_id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} -) - -func request_Query_UserGroups_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryUserGroupsRequest +func request_Query_UserGroup_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserGroupRequest var metadata runtime.ServerMetadata var ( @@ -147,20 +215,24 @@ func request_Query_UserGroups_0(ctx context.Context, marshaler runtime.Marshaler return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) } - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + val, ok = pathParams["group_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "group_id") } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UserGroups_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + + protoReq.GroupId, err = runtime.Uint32(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "group_id", err) } - msg, err := client.UserGroups(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.UserGroup(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_UserGroups_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryUserGroupsRequest +func local_request_Query_UserGroup_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserGroupRequest var metadata runtime.ServerMetadata var ( @@ -181,20 +253,24 @@ func local_request_Query_UserGroups_0(ctx context.Context, marshaler runtime.Mar return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) } - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + val, ok = pathParams["group_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "group_id") } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_UserGroups_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + + protoReq.GroupId, err = runtime.Uint32(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "group_id", err) } - msg, err := server.UserGroups(ctx, &protoReq) + msg, err := server.UserGroup(ctx, &protoReq) return msg, metadata, err } var ( - filter_Query_UserGroupMembers_0 = &utilities.DoubleArray{Encoding: map[string]int{"subspace_id": 0, "group_name": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} + filter_Query_UserGroupMembers_0 = &utilities.DoubleArray{Encoding: map[string]int{"subspace_id": 0, "group_id": 1}, Base: []int{1, 1, 2, 0, 0}, Check: []int{0, 1, 1, 2, 3}} ) func request_Query_UserGroupMembers_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { @@ -219,15 +295,15 @@ func request_Query_UserGroupMembers_0(ctx context.Context, marshaler runtime.Mar return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) } - val, ok = pathParams["group_name"] + val, ok = pathParams["group_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "group_name") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "group_id") } - protoReq.GroupName, err = runtime.String(val) + protoReq.GroupId, err = runtime.Uint32(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "group_name", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "group_id", err) } if err := req.ParseForm(); err != nil { @@ -264,15 +340,15 @@ func local_request_Query_UserGroupMembers_0(ctx context.Context, marshaler runti return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) } - val, ok = pathParams["group_name"] + val, ok = pathParams["group_id"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "group_name") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "group_id") } - protoReq.GroupName, err = runtime.String(val) + protoReq.GroupId, err = runtime.Uint32(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "group_name", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "group_id", err) } if err := req.ParseForm(); err != nil { @@ -287,8 +363,8 @@ func local_request_Query_UserGroupMembers_0(ctx context.Context, marshaler runti } -func request_Query_Permissions_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryPermissionsRequest +func request_Query_UserPermissions_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserPermissionsRequest var metadata runtime.ServerMetadata var ( @@ -309,24 +385,24 @@ func request_Query_Permissions_0(ctx context.Context, marshaler runtime.Marshale return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) } - val, ok = pathParams["target"] + val, ok = pathParams["user"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "target") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user") } - protoReq.Target, err = runtime.String(val) + protoReq.User, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "target", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user", err) } - msg, err := client.Permissions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + msg, err := client.UserPermissions(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err } -func local_request_Query_Permissions_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq QueryPermissionsRequest +func local_request_Query_UserPermissions_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryUserPermissionsRequest var metadata runtime.ServerMetadata var ( @@ -347,18 +423,18 @@ func local_request_Query_Permissions_0(ctx context.Context, marshaler runtime.Ma return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "subspace_id", err) } - val, ok = pathParams["target"] + val, ok = pathParams["user"] if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "target") + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "user") } - protoReq.Target, err = runtime.String(val) + protoReq.User, err = runtime.String(val) if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "target", err) + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "user", err) } - msg, err := server.Permissions(ctx, &protoReq) + msg, err := server.UserPermissions(ctx, &protoReq) return msg, metadata, err } @@ -369,7 +445,7 @@ func local_request_Query_Permissions_0(ctx context.Context, marshaler runtime.Ma // Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { - mux.Handle("GET", pattern_Query_Subspace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_Subspaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -378,18 +454,18 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_Subspace_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_Subspaces_0(rctx, inboundMarshaler, server, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Subspace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_Subspaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_Query_Subspaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_Subspace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -398,14 +474,14 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_Subspaces_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_Subspace_0(rctx, inboundMarshaler, server, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Subspaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_Subspace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -429,6 +505,26 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_UserGroup_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_UserGroup_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UserGroup_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_UserGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -449,7 +545,7 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) - mux.Handle("GET", pattern_Query_Permissions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_UserPermissions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -458,14 +554,14 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := local_request_Query_Permissions_0(rctx, inboundMarshaler, server, req, pathParams) + resp, md, err := local_request_Query_UserPermissions_0(rctx, inboundMarshaler, server, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Permissions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_UserPermissions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -510,7 +606,7 @@ func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc // "QueryClient" to call the correct interceptors. func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { - mux.Handle("GET", pattern_Query_Subspace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_Subspaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -519,18 +615,18 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_Subspace_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_Subspaces_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Subspace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_Subspaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) - mux.Handle("GET", pattern_Query_Subspaces_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_Subspace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -539,14 +635,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_Subspaces_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_Subspace_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Subspaces_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_Subspace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -570,6 +666,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_UserGroup_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_UserGroup_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_UserGroup_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + mux.Handle("GET", pattern_Query_UserGroupMembers_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() @@ -590,7 +706,7 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) - mux.Handle("GET", pattern_Query_Permissions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + mux.Handle("GET", pattern_Query_UserPermissions_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { ctx, cancel := context.WithCancel(req.Context()) defer cancel() inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) @@ -599,14 +715,14 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - resp, md, err := request_Query_Permissions_0(rctx, inboundMarshaler, client, req, pathParams) + resp, md, err := request_Query_UserPermissions_0(rctx, inboundMarshaler, client, req, pathParams) ctx = runtime.NewServerMetadataContext(ctx, md) if err != nil { runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) return } - forward_Query_Permissions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + forward_Query_UserPermissions_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) }) @@ -614,25 +730,29 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie } var ( - pattern_Query_Subspace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"desmos", "subspaces", "v1", "subspace_id"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_Subspaces_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1}, []string{"desmos", "subspaces", "v1"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_UserGroups_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"desmos", "subspaces", "v1", "subspace_id", "groups"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_Subspace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1, 1, 0, 4, 1, 5, 3}, []string{"desmos", "subspaces", "v1", "subspace_id"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_UserGroups_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"desmos", "subspaces", "v1", "groups", "subspace_id"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_UserGroup_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"desmos", "subspaces", "v1", "groups", "subspace_id", "group_id"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_UserGroupMembers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"desmos", "subspaces", "v1", "subspace_id", "groups", "group_name", "members"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UserGroupMembers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"desmos", "subspaces", "v1", "groups", "subspace_id", "group_id", "members"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_Permissions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"desmos", "subspaces", "v1", "subspace_id", "permissions", "target"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UserPermissions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"desmos", "subspaces", "v1", "permissions", "subspace_id", "user"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( - forward_Query_Subspace_0 = runtime.ForwardResponseMessage - forward_Query_Subspaces_0 = runtime.ForwardResponseMessage + forward_Query_Subspace_0 = runtime.ForwardResponseMessage + forward_Query_UserGroups_0 = runtime.ForwardResponseMessage + forward_Query_UserGroup_0 = runtime.ForwardResponseMessage + forward_Query_UserGroupMembers_0 = runtime.ForwardResponseMessage - forward_Query_Permissions_0 = runtime.ForwardResponseMessage + forward_Query_UserPermissions_0 = runtime.ForwardResponseMessage ) diff --git a/x/subspaces/types/subspace.pb.go b/x/subspaces/types/subspace.pb.go deleted file mode 100644 index 398c5b9164..0000000000 --- a/x/subspaces/types/subspace.pb.go +++ /dev/null @@ -1,678 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: desmos/subspaces/v1/subspace.proto - -package types - -import ( - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - github_com_gogo_protobuf_types "github.com/gogo/protobuf/types" - _ "google.golang.org/protobuf/types/known/timestamppb" - io "io" - math "math" - math_bits "math/bits" - time "time" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf -var _ = time.Kitchen - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -// Subspace contains all the data of a Desmos subspace -type Subspace struct { - // Unique id that identifies the subspace - ID uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` - // Human-readable name of the subspace - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` - // Optional description of this subspace - Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` - // Represents the account that is associated with the subspace and - // should be used to connect external applications to verify this subspace - Treasury string `protobuf:"bytes,4,opt,name=treasury,proto3" json:"treasury,omitempty" yaml:"treasury"` - // Address of the user that owns the subspace - Owner string `protobuf:"bytes,5,opt,name=owner,proto3" json:"owner,omitempty" yaml:"owner"` - // Address of the subspace creator - Creator string `protobuf:"bytes,6,opt,name=creator,proto3" json:"creator,omitempty" yaml:"creator"` - // the creation time of the subspace - CreationTime time.Time `protobuf:"bytes,7,opt,name=creation_time,json=creationTime,proto3,stdtime" json:"creation_time" yaml:"creation_time"` -} - -func (m *Subspace) Reset() { *m = Subspace{} } -func (m *Subspace) String() string { return proto.CompactTextString(m) } -func (*Subspace) ProtoMessage() {} -func (*Subspace) Descriptor() ([]byte, []int) { - return fileDescriptor_64b466175177a54c, []int{0} -} -func (m *Subspace) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *Subspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_Subspace.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *Subspace) XXX_Merge(src proto.Message) { - xxx_messageInfo_Subspace.Merge(m, src) -} -func (m *Subspace) XXX_Size() int { - return m.Size() -} -func (m *Subspace) XXX_DiscardUnknown() { - xxx_messageInfo_Subspace.DiscardUnknown(m) -} - -var xxx_messageInfo_Subspace proto.InternalMessageInfo - -func (m *Subspace) GetID() uint64 { - if m != nil { - return m.ID - } - return 0 -} - -func (m *Subspace) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *Subspace) GetDescription() string { - if m != nil { - return m.Description - } - return "" -} - -func (m *Subspace) GetTreasury() string { - if m != nil { - return m.Treasury - } - return "" -} - -func (m *Subspace) GetOwner() string { - if m != nil { - return m.Owner - } - return "" -} - -func (m *Subspace) GetCreator() string { - if m != nil { - return m.Creator - } - return "" -} - -func (m *Subspace) GetCreationTime() time.Time { - if m != nil { - return m.CreationTime - } - return time.Time{} -} - -func init() { - proto.RegisterType((*Subspace)(nil), "desmos.subspaces.v1.Subspace") -} - -func init() { - proto.RegisterFile("desmos/subspaces/v1/subspace.proto", fileDescriptor_64b466175177a54c) -} - -var fileDescriptor_64b466175177a54c = []byte{ - // 407 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x92, 0x31, 0x8f, 0xd3, 0x30, - 0x1c, 0xc5, 0xeb, 0x5e, 0xef, 0xae, 0xe7, 0x1e, 0x1c, 0x72, 0x4f, 0x28, 0xea, 0x10, 0x57, 0x3e, - 0x09, 0x75, 0x80, 0x58, 0x57, 0x16, 0x74, 0x63, 0xc5, 0x82, 0xc4, 0x14, 0x98, 0x58, 0x90, 0x93, - 0x98, 0x60, 0xa9, 0x89, 0xa3, 0xd8, 0x29, 0x74, 0xe5, 0x13, 0xdc, 0xc8, 0x78, 0x1f, 0xe7, 0xc6, - 0x8e, 0x4c, 0x06, 0xa5, 0x0b, 0x73, 0x3e, 0xc1, 0x29, 0x76, 0x53, 0x65, 0xfb, 0xff, 0xdf, 0xfb, - 0xbd, 0xbf, 0xa2, 0x17, 0x43, 0x92, 0x70, 0x95, 0x49, 0x45, 0x55, 0x15, 0xa9, 0x82, 0xc5, 0x5c, - 0xd1, 0xcd, 0xed, 0x71, 0x09, 0x8a, 0x52, 0x6a, 0x89, 0xa6, 0x8e, 0x09, 0x8e, 0x4c, 0xb0, 0xb9, - 0x9d, 0x5d, 0xa7, 0x32, 0x95, 0xd6, 0xa7, 0xed, 0xe4, 0xd0, 0x19, 0x4e, 0xa5, 0x4c, 0xd7, 0x9c, - 0xda, 0x2d, 0xaa, 0xbe, 0x51, 0x2d, 0x32, 0xae, 0x34, 0xcb, 0x0a, 0x07, 0x90, 0x5f, 0x27, 0x70, - 0xfc, 0xe9, 0x70, 0x07, 0xdd, 0xc0, 0xa1, 0x48, 0x3c, 0x30, 0x07, 0x8b, 0xd1, 0x6a, 0x5a, 0x1b, - 0x3c, 0xfc, 0xf0, 0xbe, 0x31, 0xf8, 0x62, 0xcb, 0xb2, 0xf5, 0x1d, 0x11, 0x09, 0x09, 0x87, 0x22, - 0x41, 0x37, 0x70, 0x94, 0xb3, 0x8c, 0x7b, 0xc3, 0x39, 0x58, 0x5c, 0xac, 0xae, 0x1a, 0x83, 0x27, - 0x0e, 0x68, 0x55, 0x12, 0x5a, 0x13, 0xbd, 0x83, 0x93, 0x84, 0xab, 0xb8, 0x14, 0x85, 0x16, 0x32, - 0xf7, 0x4e, 0x2c, 0xfb, 0xb2, 0x31, 0x18, 0x39, 0xb6, 0x67, 0x92, 0xb0, 0x8f, 0x22, 0x0a, 0xc7, - 0xba, 0xe4, 0x4c, 0x55, 0xe5, 0xd6, 0x1b, 0xd9, 0xd8, 0xb4, 0x31, 0xf8, 0xca, 0xc5, 0x3a, 0x87, - 0x84, 0x47, 0x08, 0xbd, 0x82, 0xa7, 0xf2, 0x47, 0xce, 0x4b, 0xef, 0xd4, 0xd2, 0x2f, 0x1a, 0x83, - 0x2f, 0x1d, 0x6d, 0x65, 0x12, 0x3a, 0x1b, 0xbd, 0x86, 0xe7, 0x71, 0xc9, 0x99, 0x96, 0xa5, 0x77, - 0x66, 0x49, 0xd4, 0x18, 0xfc, 0xdc, 0x91, 0x07, 0x83, 0x84, 0x1d, 0x82, 0x18, 0x7c, 0x66, 0x47, - 0x21, 0xf3, 0xaf, 0x6d, 0x67, 0xde, 0xf9, 0x1c, 0x2c, 0x26, 0xcb, 0x59, 0xe0, 0x0a, 0x0d, 0xba, - 0x42, 0x83, 0xcf, 0x5d, 0xa1, 0xab, 0xf9, 0xa3, 0xc1, 0x83, 0xc6, 0xe0, 0xeb, 0xde, 0xcd, 0x2e, - 0x4e, 0xee, 0xff, 0x62, 0x10, 0x5e, 0x76, 0x5a, 0x1b, 0xba, 0x1b, 0xff, 0x7e, 0xc0, 0xe0, 0xff, - 0x03, 0x06, 0xab, 0x8f, 0x8f, 0xb5, 0x0f, 0x76, 0xb5, 0x0f, 0xfe, 0xd5, 0x3e, 0xb8, 0xdf, 0xfb, - 0x83, 0xdd, 0xde, 0x1f, 0xfc, 0xd9, 0xfb, 0x83, 0x2f, 0xcb, 0x54, 0xe8, 0xef, 0x55, 0x14, 0xc4, - 0x32, 0xa3, 0xee, 0xaf, 0xbf, 0x59, 0xb3, 0x48, 0x1d, 0x66, 0xba, 0x59, 0xd2, 0x9f, 0xbd, 0xa7, - 0xa2, 0xb7, 0x05, 0x57, 0xd1, 0x99, 0xfd, 0xb6, 0xb7, 0x4f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa1, - 0x97, 0xf2, 0x18, 0x4b, 0x02, 0x00, 0x00, -} - -func (this *Subspace) Equal(that interface{}) bool { - if that == nil { - return this == nil - } - - that1, ok := that.(*Subspace) - if !ok { - that2, ok := that.(Subspace) - if ok { - that1 = &that2 - } else { - return false - } - } - if that1 == nil { - return this == nil - } else if this == nil { - return false - } - if this.ID != that1.ID { - return false - } - if this.Name != that1.Name { - return false - } - if this.Description != that1.Description { - return false - } - if this.Treasury != that1.Treasury { - return false - } - if this.Owner != that1.Owner { - return false - } - if this.Creator != that1.Creator { - return false - } - if !this.CreationTime.Equal(that1.CreationTime) { - return false - } - return true -} -func (m *Subspace) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *Subspace) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *Subspace) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.CreationTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.CreationTime):]) - if err1 != nil { - return 0, err1 - } - i -= n1 - i = encodeVarintSubspace(dAtA, i, uint64(n1)) - i-- - dAtA[i] = 0x3a - if len(m.Creator) > 0 { - i -= len(m.Creator) - copy(dAtA[i:], m.Creator) - i = encodeVarintSubspace(dAtA, i, uint64(len(m.Creator))) - i-- - dAtA[i] = 0x32 - } - if len(m.Owner) > 0 { - i -= len(m.Owner) - copy(dAtA[i:], m.Owner) - i = encodeVarintSubspace(dAtA, i, uint64(len(m.Owner))) - i-- - dAtA[i] = 0x2a - } - if len(m.Treasury) > 0 { - i -= len(m.Treasury) - copy(dAtA[i:], m.Treasury) - i = encodeVarintSubspace(dAtA, i, uint64(len(m.Treasury))) - i-- - dAtA[i] = 0x22 - } - if len(m.Description) > 0 { - i -= len(m.Description) - copy(dAtA[i:], m.Description) - i = encodeVarintSubspace(dAtA, i, uint64(len(m.Description))) - i-- - dAtA[i] = 0x1a - } - if len(m.Name) > 0 { - i -= len(m.Name) - copy(dAtA[i:], m.Name) - i = encodeVarintSubspace(dAtA, i, uint64(len(m.Name))) - i-- - dAtA[i] = 0x12 - } - if m.ID != 0 { - i = encodeVarintSubspace(dAtA, i, uint64(m.ID)) - i-- - dAtA[i] = 0x8 - } - return len(dAtA) - i, nil -} - -func encodeVarintSubspace(dAtA []byte, offset int, v uint64) int { - offset -= sovSubspace(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *Subspace) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ID != 0 { - n += 1 + sovSubspace(uint64(m.ID)) - } - l = len(m.Name) - if l > 0 { - n += 1 + l + sovSubspace(uint64(l)) - } - l = len(m.Description) - if l > 0 { - n += 1 + l + sovSubspace(uint64(l)) - } - l = len(m.Treasury) - if l > 0 { - n += 1 + l + sovSubspace(uint64(l)) - } - l = len(m.Owner) - if l > 0 { - n += 1 + l + sovSubspace(uint64(l)) - } - l = len(m.Creator) - if l > 0 { - n += 1 + l + sovSubspace(uint64(l)) - } - l = github_com_gogo_protobuf_types.SizeOfStdTime(m.CreationTime) - n += 1 + l + sovSubspace(uint64(l)) - return n -} - -func sovSubspace(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozSubspace(x uint64) (n int) { - return sovSubspace(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *Subspace) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubspace - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: Subspace: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: Subspace: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) - } - m.ID = 0 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubspace - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - m.ID |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubspace - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubspace - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubspace - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubspace - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubspace - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubspace - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubspace - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubspace - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubspace - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Treasury = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubspace - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubspace - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubspace - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Owner = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubspace - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthSubspace - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthSubspace - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Creator = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 7: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CreationTime", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowSubspace - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthSubspace - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthSubspace - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.CreationTime, dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipSubspace(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthSubspace - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipSubspace(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSubspace - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSubspace - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowSubspace - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthSubspace - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupSubspace - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthSubspace - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthSubspace = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowSubspace = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupSubspace = fmt.Errorf("proto: unexpected end of group") -) From 96cc2e569597813ca86c8dd2e43d43a4e3fd62a9 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 31 Jan 2022 09:27:03 +0100 Subject: [PATCH 28/47] lint and format Signed-off-by: Riccardo Montagnin --- x/subspaces/types/genesis.go | 3 ++- x/subspaces/types/keys.go | 12 +++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/x/subspaces/types/genesis.go b/x/subspaces/types/genesis.go index 8dfea38fcd..d2ba4f20ac 100644 --- a/x/subspaces/types/genesis.go +++ b/x/subspaces/types/genesis.go @@ -151,7 +151,8 @@ func ValidateGenesis(data *GenesisState) error { return fmt.Errorf("duplicated group for subspace %d and group %d", group.SubspaceID, group.ID) } - groupsCount[group.SubspaceID] = groupsCount[group.SubspaceID] + 1 + // Increment the groups count for this subspace + groupsCount[group.SubspaceID]++ } // Make sure each subspace has a correct initial group id based on the number of groups inside that subspace diff --git a/x/subspaces/types/keys.go b/x/subspaces/types/keys.go index 851c31ba4b..458c1b8af6 100644 --- a/x/subspaces/types/keys.go +++ b/x/subspaces/types/keys.go @@ -30,13 +30,11 @@ const ( ) var ( - SubspacePrefix = []byte{0x00} - SubspaceIDKey = []byte{0x01} - - GroupIDPrefix = []byte{0x02} - GroupsPrefix = []byte{0x03} - GroupMembersStorePrefix = []byte{0x04} - + SubspaceIDKey = []byte{0x00} + SubspacePrefix = []byte{0x01} + GroupIDPrefix = []byte{0x02} + GroupsPrefix = []byte{0x03} + GroupMembersStorePrefix = []byte{0x04} UserPermissionsStorePrefix = []byte{0x05} ) From 1e7a1d2b2720638047b9512bb06f1d19ed61db80 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 31 Jan 2022 10:12:19 +0100 Subject: [PATCH 29/47] added DONTCOVER for subspaces operations files Signed-off-by: Riccardo Montagnin --- x/subspaces/simulation/operations_groups.go | 2 ++ x/subspaces/simulation/operations_permissions.go | 2 ++ 2 files changed, 4 insertions(+) diff --git a/x/subspaces/simulation/operations_groups.go b/x/subspaces/simulation/operations_groups.go index b467b3aaf4..719c11d9b0 100644 --- a/x/subspaces/simulation/operations_groups.go +++ b/x/subspaces/simulation/operations_groups.go @@ -1,5 +1,7 @@ package simulation +// DONTCOVER + import ( "math/rand" diff --git a/x/subspaces/simulation/operations_permissions.go b/x/subspaces/simulation/operations_permissions.go index ad302c68b7..e93b98984d 100644 --- a/x/subspaces/simulation/operations_permissions.go +++ b/x/subspaces/simulation/operations_permissions.go @@ -1,5 +1,7 @@ package simulation +// DONTCOVER + import ( "math/rand" From 7c1a19674fd17667b0acd8df2ca3278a8ff2e019 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 31 Jan 2022 10:45:04 +0100 Subject: [PATCH 30/47] added keeper tests Signed-off-by: Riccardo Montagnin --- x/subspaces/keeper/hooks.go | 2 + x/subspaces/keeper/keeper.go | 2 +- x/subspaces/keeper/keeper_test.go | 46 ++++ x/subspaces/keeper/msg_server.go | 4 +- x/subspaces/keeper/msg_server_test.go | 356 ++++++++++++++++++++++++- x/subspaces/keeper/permissions.go | 13 + x/subspaces/keeper/permissions_test.go | 153 +++++++++++ x/subspaces/keeper/subspaces_test.go | 17 +- 8 files changed, 572 insertions(+), 21 deletions(-) create mode 100644 x/subspaces/keeper/keeper_test.go diff --git a/x/subspaces/keeper/hooks.go b/x/subspaces/keeper/hooks.go index 524c381127..ff0e5e337c 100644 --- a/x/subspaces/keeper/hooks.go +++ b/x/subspaces/keeper/hooks.go @@ -1,5 +1,7 @@ package keeper +// DONTCOVER + import ( sdk "github.com/cosmos/cosmos-sdk/types" diff --git a/x/subspaces/keeper/keeper.go b/x/subspaces/keeper/keeper.go index cc6c045c86..728bd2e6ab 100644 --- a/x/subspaces/keeper/keeper.go +++ b/x/subspaces/keeper/keeper.go @@ -22,7 +22,7 @@ func NewKeeper(cdc codec.BinaryCodec, storeKey sdk.StoreKey) Keeper { } } -// Logger returns a module-specific logger. +// Logger returns a module-specific logger func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/"+types.ModuleName) } diff --git a/x/subspaces/keeper/keeper_test.go b/x/subspaces/keeper/keeper_test.go new file mode 100644 index 0000000000..521ca8312b --- /dev/null +++ b/x/subspaces/keeper/keeper_test.go @@ -0,0 +1,46 @@ +package keeper_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/desmos-labs/desmos/v2/x/subspaces/keeper" + "github.com/desmos-labs/desmos/v2/x/subspaces/types" +) + +func TestKeeper_SetHooks(t *testing.T) { + testCases := []struct { + name string + setup func(k keeper.Keeper) keeper.Keeper + shouldErr bool + }{ + { + name: "setting already set hooks returns error", + setup: func(k keeper.Keeper) keeper.Keeper { + return k.SetHooks(types.MultiSubspacesHooks{}) + }, + shouldErr: true, + }, + { + name: "setting hooks not set works properly", + shouldErr: false, + }, + } + + for _, tc := range testCases { + tc := tc + t.Run(tc.name, func(t *testing.T) { + k := keeper.NewKeeper(nil, nil) + if tc.setup != nil { + k = tc.setup(k) + } + + if tc.shouldErr { + require.Panics(t, func() { k.SetHooks(types.MultiSubspacesHooks{}) }) + } else { + require.NotPanics(t, func() { k.SetHooks(types.MultiSubspacesHooks{}) }) + } + }) + } +} diff --git a/x/subspaces/keeper/msg_server.go b/x/subspaces/keeper/msg_server.go index 4ff2c88840..94591cf4c6 100644 --- a/x/subspaces/keeper/msg_server.go +++ b/x/subspaces/keeper/msg_server.go @@ -232,8 +232,8 @@ func (k msgServer) EditUserGroup(goCtx context.Context, msg *types.MsgEditUserGr return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error()) } - // Save the group - k.SaveUserGroup(ctx, group) + // Save the updated group + k.SaveUserGroup(ctx, updated) ctx.EventManager().EmitEvents(sdk.Events{ sdk.NewEvent( diff --git a/x/subspaces/keeper/msg_server_test.go b/x/subspaces/keeper/msg_server_test.go index 6a292b7e99..6a35de3679 100644 --- a/x/subspaces/keeper/msg_server_test.go +++ b/x/subspaces/keeper/msg_server_test.go @@ -480,12 +480,13 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteSubspace() { func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() { testCases := []struct { - name string - store func(ctx sdk.Context) - msg *types.MsgCreateUserGroup - shouldErr bool - expEvents sdk.Events - check func(ctx sdk.Context) + name string + store func(ctx sdk.Context) + msg *types.MsgCreateUserGroup + shouldErr bool + expResponse *types.MsgCreateUserGroupResponse + expEvents sdk.Events + check func(ctx sdk.Context) }{ { name: "non existing subspace returns error", @@ -553,7 +554,8 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() { types.PermissionWrite, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", ), - shouldErr: false, + shouldErr: false, + expResponse: &types.MsgCreateUserGroupResponse{GroupID: 2}, expEvents: sdk.Events{ sdk.NewEvent( sdk.EventTypeMessage, @@ -583,7 +585,343 @@ func (suite *KeeperTestsuite) TestMsgServer_CreateUserGroup() { // Run the message service := keeper.NewMsgServerImpl(suite.k) - _, err := service.CreateUserGroup(sdk.WrapSDKContext(ctx), tc.msg) + res, err := service.CreateUserGroup(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expResponse, res) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_EditUserGroup() { + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgEditUserGroup + shouldErr bool + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "non existing subspace returns error", + msg: types.NewMsgEditUserGroup( + 1, + 1, + "Test group", + "This is a test group", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "group not found returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + msg: types.NewMsgEditUserGroup( + 1, + 1, + "Test group", + "This is a test group", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "no permission returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + }, + msg: types.NewMsgEditUserGroup( + 1, + 1, + "Test group new name", + "This is a test group with a new name", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "invalid update returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionManageGroups) + }, + msg: types.NewMsgEditUserGroup( + 1, + 1, + "", + "", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "existing group is edited properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionManageGroups) + }, + msg: types.NewMsgEditUserGroup( + 1, + 1, + "Admins", + "Group of the admins of th subspace", + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"), + ), + sdk.NewEvent( + types.EventTypeEditUserGroup, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + sdk.NewAttribute(types.AttributeKeyUserGroupID, "1"), + ), + }, + check: func(ctx sdk.Context) { + group, found := suite.k.GetUserGroup(ctx, 1, 1) + suite.Require().True(found) + + suite.Require().Equal(types.NewUserGroup( + 1, + 1, + "Admins", + "Group of the admins of th subspace", + types.PermissionWrite, + ), group) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + _, err := service.EditUserGroup(sdk.WrapSDKContext(ctx), tc.msg) + + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Equal(tc.expEvents, ctx.EventManager().Events()) + + if tc.check != nil { + tc.check(ctx) + } + } + }) + } +} + +func (suite *KeeperTestsuite) TestMsgServer_SetUserGroupPermissions() { + testCases := []struct { + name string + store func(ctx sdk.Context) + msg *types.MsgSetUserGroupPermissions + shouldErr bool + expEvents sdk.Events + check func(ctx sdk.Context) + }{ + { + name: "subspace not found returns error", + msg: types.NewMsgSetUserGroupPermissions( + 1, + 1, + types.PermissionSetPermissions, + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "group not found returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + }, + msg: types.NewMsgSetUserGroupPermissions( + 1, + 1, + types.PermissionSetPermissions, + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + ), + shouldErr: true, + }, + { + name: "no permission returns error", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + }, + msg: types.NewMsgSetUserGroupPermissions( + 1, + 1, + types.PermissionSetPermissions, + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: true, + }, + { + name: "existing group is deleted properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + "cosmos1m0czrla04f7rp3zg7dsgc4kla54q7pc4xt00l5", + "cosmos1qzskhrcjnkdz2ln4yeafzsdwht8ch08j4wed69", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53") + suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionSetPermissions) + }, + msg: types.NewMsgSetUserGroupPermissions( + 1, + 1, + types.PermissionSetPermissions, + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + ), + shouldErr: false, + expEvents: sdk.Events{ + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53"), + ), + sdk.NewEvent( + types.ActionSetUserGroupPermissions, + sdk.NewAttribute(types.AttributeKeySubspaceID, "1"), + sdk.NewAttribute(types.AttributeKeyUserGroupID, "1"), + ), + }, + check: func(ctx sdk.Context) { + group, found := suite.k.GetUserGroup(ctx, 1, 1) + suite.Require().True(found) + + suite.Require().Equal(types.PermissionSetPermissions, group.Permissions) + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + // Run the message + service := keeper.NewMsgServerImpl(suite.k) + _, err := service.SetUserGroupPermissions(sdk.WrapSDKContext(ctx), tc.msg) if tc.shouldErr { suite.Require().Error(err) @@ -707,7 +1045,7 @@ func (suite *KeeperTestsuite) TestMsgServer_DeleteUserGroup() { ), }, check: func(ctx sdk.Context) { - hasGroup := suite.k.HasUserGroup(ctx, 1, 2) + hasGroup := suite.k.HasUserGroup(ctx, 1, 1) suite.Require().False(hasGroup) }, }, diff --git a/x/subspaces/keeper/permissions.go b/x/subspaces/keeper/permissions.go index 26d116dfdc..580ca281ae 100644 --- a/x/subspaces/keeper/permissions.go +++ b/x/subspaces/keeper/permissions.go @@ -70,6 +70,8 @@ func (k Keeper) GetUsersWithPermission(ctx sdk.Context, subspaceID uint64, permi } users := []sdk.AccAddress{ownerAddr} + + // Iterate over the various groups k.IterateSubspaceGroups(ctx, subspaceID, func(index int64, group types.UserGroup) (stop bool) { if !types.CheckPermission(group.Permissions, permission) { // Return early if the group does not have the permission. We will check other groups anyway @@ -85,6 +87,17 @@ func (k Keeper) GetUsersWithPermission(ctx sdk.Context, subspaceID uint64, permi return false }) + // Iterate over the various individually-set permissions + k.IterateSubspacePermissions(ctx, subspaceID, func(index int64, user sdk.AccAddress, permission types.Permission) (stop bool) { + if !types.CheckPermission(permission, permission) { + // Return early if the user does not have the permission. We will check other users anyway + return false + } + + users = append(users, user) + return false + }) + return users, nil } diff --git a/x/subspaces/keeper/permissions_test.go b/x/subspaces/keeper/permissions_test.go index 280e32b4a0..444b62a9de 100644 --- a/x/subspaces/keeper/permissions_test.go +++ b/x/subspaces/keeper/permissions_test.go @@ -317,6 +317,159 @@ func (suite *KeeperTestsuite) TestKeeper_GetGroupsInheritedPermissions() { } } +func (suite *KeeperTestsuite) TestKeeper_GetUsersWithPermissions() { + testCases := []struct { + name string + store func(ctx sdk.Context) + subspaceID uint64 + permissions types.Permission + shouldErr bool + expUsers []string + }{ + { + name: "subspace not found returns empty slice", + subspaceID: 1, + permissions: types.PermissionWrite, + shouldErr: false, + expUsers: nil, + }, + { + name: "no users found returns empty slice", + store: func(ctx sdk.Context) { + + }, + subspaceID: 1, + permissions: types.PermissionWrite, + shouldErr: false, + expUsers: nil, + }, + { + name: "users with permissions inherited from groups are returned properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite, + )) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, 1, sdkAddr) + suite.Require().NoError(err) + }, + subspaceID: 1, + permissions: types.PermissionWrite, + shouldErr: false, + expUsers: []string{ + "cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", // Owner is always included + }, + }, + { + name: "users with individually set permissions are returned properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd") + suite.Require().NoError(err) + + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionWrite) + }, + subspaceID: 1, + permissions: types.PermissionWrite, + shouldErr: false, + expUsers: []string{ + "cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", // Owner is always included + }, + }, + { + name: "multiple users are returned properly", + store: func(ctx sdk.Context) { + suite.k.SaveSubspace(ctx, types.NewSubspace( + 1, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), + )) + + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionWrite|types.PermissionSetPermissions, + )) + + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1xw69y2z3yf00rgfnly99628gn5c0x7fryyfv5e") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, 1, sdkAddr) + suite.Require().NoError(err) + + sdkAddr, err = sdk.AccAddressFromBech32("cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd") + suite.Require().NoError(err) + + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionWrite|types.PermissionChangeInfo) + }, + subspaceID: 1, + permissions: types.PermissionWrite, + shouldErr: false, + expUsers: []string{ + "cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd", + "cosmos1xw69y2z3yf00rgfnly99628gn5c0x7fryyfv5e", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", // Owner is always included + }, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + ctx, _ := suite.ctx.CacheContext() + if tc.store != nil { + tc.store(ctx) + } + + users, err := suite.k.GetUsersWithPermission(ctx, tc.subspaceID, tc.permissions) + if tc.shouldErr { + suite.Require().Error(err) + } else { + suite.Require().NoError(err) + suite.Require().Len(users, len(tc.expUsers)) + + for _, user := range users { + suite.Require().Contains(tc.expUsers, user.String()) + } + } + }) + } +} + func (suite *KeeperTestsuite) TestKeeper_RemoveUserPermissions() { testCases := []struct { name string diff --git a/x/subspaces/keeper/subspaces_test.go b/x/subspaces/keeper/subspaces_test.go index 93ef79aa10..13c6d66ffa 100644 --- a/x/subspaces/keeper/subspaces_test.go +++ b/x/subspaces/keeper/subspaces_test.go @@ -180,28 +180,27 @@ func (suite *KeeperTestsuite) TestKeeper_HasSubspace() { name string store func(ctx sdk.Context) subspaceID uint64 - groupID uint32 expResult bool }{ { name: "not found subspace returns false", subspaceID: 1, - groupID: 1, expResult: false, }, { name: "found subspace returns the correct data", store: func(ctx sdk.Context) { - suite.k.SaveUserGroup(ctx, types.NewUserGroup( - 1, + suite.k.SaveSubspace(ctx, types.NewSubspace( 1, - "Test group", - "This is a test group", - types.PermissionWrite, + "Test subspace", + "This is a test subspace", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + "cosmos1s0he0z3g92zwsxdj83h0ky9w463sx7gq9mqtgn", + time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) }, subspaceID: 1, - groupID: 1, expResult: true, }, } @@ -214,7 +213,7 @@ func (suite *KeeperTestsuite) TestKeeper_HasSubspace() { tc.store(ctx) } - result := suite.k.HasUserGroup(ctx, tc.subspaceID, tc.groupID) + result := suite.k.HasSubspace(ctx, tc.subspaceID) suite.Require().Equal(tc.expResult, result) }) } From cd50f13865e820721858813ac0e223fa5360c61a Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 31 Jan 2022 10:47:59 +0100 Subject: [PATCH 31/47] added types tests Signed-off-by: Riccardo Montagnin --- x/subspaces/simulation/decoder_test.go | 6 ++++++ x/subspaces/types/hooks.go | 2 ++ x/subspaces/types/query.go | 2 ++ 3 files changed, 10 insertions(+) diff --git a/x/subspaces/simulation/decoder_test.go b/x/subspaces/simulation/decoder_test.go index 2f5eaccfdd..ed8559029f 100644 --- a/x/subspaces/simulation/decoder_test.go +++ b/x/subspaces/simulation/decoder_test.go @@ -52,6 +52,10 @@ func TestDecodeStore(t *testing.T) { Key: types.SubspaceKey(subspace.ID), Value: cdc.MustMarshal(&subspace), }, + { + Key: types.GroupIDStoreKey(1), + Value: types.GetGroupIDBytes(1), + }, { Key: types.GroupStoreKey(1, 1), Value: cdc.MustMarshal(&group), @@ -78,6 +82,8 @@ func TestDecodeStore(t *testing.T) { 1, 1)}, {"Subspace", fmt.Sprintf("SubspaceA: %s\nSubspaceB: %s\n", subspace.String(), subspace.String())}, + {"Group ID", fmt.Sprintf("GroupIDA: %d\nGroupIDB: %d\n", + types.GetGroupIDBytes(1), types.GetGroupIDBytes(1))}, {"Group", fmt.Sprintf("GroupA: %s\nGroupB: %s\n", group.String(), group.String())}, {"Group member", fmt.Sprintf("GroupMemberKeyA: %s\nGroupMemberKeyB: %s\n", diff --git a/x/subspaces/types/hooks.go b/x/subspaces/types/hooks.go index b4fafe3efe..5977f2d72f 100644 --- a/x/subspaces/types/hooks.go +++ b/x/subspaces/types/hooks.go @@ -1,5 +1,7 @@ package types +// DONTCOVER + import ( sdk "github.com/cosmos/cosmos-sdk/types" ) diff --git a/x/subspaces/types/query.go b/x/subspaces/types/query.go index 3ef53c6012..c81d0809b2 100644 --- a/x/subspaces/types/query.go +++ b/x/subspaces/types/query.go @@ -1,5 +1,7 @@ package types +// DONTCOVER + import ( "github.com/cosmos/cosmos-sdk/types/query" ) From 654524a81e1c58d5073d61d7559979a65dfc0d81 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 31 Jan 2022 10:56:29 +0100 Subject: [PATCH 32/47] fixed tests Signed-off-by: Riccardo Montagnin --- x/subspaces/simulation/decoder_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/subspaces/simulation/decoder_test.go b/x/subspaces/simulation/decoder_test.go index ed8559029f..a39705af92 100644 --- a/x/subspaces/simulation/decoder_test.go +++ b/x/subspaces/simulation/decoder_test.go @@ -83,7 +83,7 @@ func TestDecodeStore(t *testing.T) { {"Subspace", fmt.Sprintf("SubspaceA: %s\nSubspaceB: %s\n", subspace.String(), subspace.String())}, {"Group ID", fmt.Sprintf("GroupIDA: %d\nGroupIDB: %d\n", - types.GetGroupIDBytes(1), types.GetGroupIDBytes(1))}, + 1, 1)}, {"Group", fmt.Sprintf("GroupA: %s\nGroupB: %s\n", group.String(), group.String())}, {"Group member", fmt.Sprintf("GroupMemberKeyA: %s\nGroupMemberKeyB: %s\n", From b56fb415c9099dcde94b916813ff88a91bc22154 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 31 Jan 2022 11:20:44 +0100 Subject: [PATCH 33/47] fixed GetUsersWithPermission Signed-off-by: Riccardo Montagnin --- x/subspaces/keeper/permissions.go | 8 +++----- x/subspaces/keeper/permissions_test.go | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/x/subspaces/keeper/permissions.go b/x/subspaces/keeper/permissions.go index 580ca281ae..9210ca4d37 100644 --- a/x/subspaces/keeper/permissions.go +++ b/x/subspaces/keeper/permissions.go @@ -88,13 +88,11 @@ func (k Keeper) GetUsersWithPermission(ctx sdk.Context, subspaceID uint64, permi }) // Iterate over the various individually-set permissions - k.IterateSubspacePermissions(ctx, subspaceID, func(index int64, user sdk.AccAddress, permission types.Permission) (stop bool) { - if !types.CheckPermission(permission, permission) { - // Return early if the user does not have the permission. We will check other users anyway - return false + k.IterateSubspacePermissions(ctx, subspaceID, func(index int64, user sdk.AccAddress, userPerm types.Permission) (stop bool) { + if types.CheckPermission(userPerm, permission) { + users = append(users, user) } - users = append(users, user) return false }) diff --git a/x/subspaces/keeper/permissions_test.go b/x/subspaces/keeper/permissions_test.go index 444b62a9de..c9cc61efc2 100644 --- a/x/subspaces/keeper/permissions_test.go +++ b/x/subspaces/keeper/permissions_test.go @@ -431,10 +431,29 @@ func (suite *KeeperTestsuite) TestKeeper_GetUsersWithPermissions() { err = suite.k.AddUserToGroup(ctx, 1, 1, sdkAddr) suite.Require().NoError(err) + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 2, + "Another test group", + "This is a second test group", + types.PermissionSetPermissions, + )) + + sdkAddr, err = sdk.AccAddressFromBech32("cosmos1e32dfqu7k9e5wj85cjtalqdd2zs6z7adgswnrn") + suite.Require().NoError(err) + + err = suite.k.AddUserToGroup(ctx, 1, 2, sdkAddr) + suite.Require().NoError(err) + sdkAddr, err = sdk.AccAddressFromBech32("cosmos15p3m7a93luselt80ffzpf4jwtn9ama34ray0nd") suite.Require().NoError(err) suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionWrite|types.PermissionChangeInfo) + + sdkAddr, err = sdk.AccAddressFromBech32("cosmos1f3e5dhpg3afanddld0kp6lkayz2qvuetf6hmv3") + suite.Require().NoError(err) + + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionChangeInfo) }, subspaceID: 1, permissions: types.PermissionWrite, From 84d0bb0a6c015880d680c620f2d523a1dd0180d8 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Wed, 2 Feb 2022 07:16:23 +0100 Subject: [PATCH 34/47] fixed CLI typos Signed-off-by: Riccardo Montagnin --- x/subspaces/client/cli/query.go | 30 ++++++++++++++++++++++----- x/subspaces/client/cli/tx.go | 18 ++++++++-------- x/subspaces/keeper/msg_server_test.go | 2 +- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/x/subspaces/client/cli/query.go b/x/subspaces/client/cli/query.go index ef6d2e4f70..c2e3602cf4 100644 --- a/x/subspaces/client/cli/query.go +++ b/x/subspaces/client/cli/query.go @@ -26,8 +26,8 @@ func GetQueryCmd() *cobra.Command { subspaceQueryCmd.AddCommand( GetCmdQuerySubspace(), GetCmdQuerySubspaces(), - GetCmdQueryUserGroups(), - GetCmdQueryUserGroupMembers(), + + GetGroupsQueryCmd(), ) return subspaceQueryCmd } @@ -100,10 +100,30 @@ func GetCmdQuerySubspaces() *cobra.Command { return cmd } +// ------------------------------------------------------------------------------------------------------------------- + +// GetGroupsQueryCmd returns a new command to perform queries for user groups +func GetGroupsQueryCmd() *cobra.Command { + groupsTxCmd := &cobra.Command{ + Use: "groups", + Short: "Querying commands for subspace groups", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + groupsTxCmd.AddCommand( + GetCmdQueryUserGroups(), + GetCmdQueryUserGroupMembers(), + ) + + return groupsTxCmd +} + // GetCmdQueryUserGroups returns the command to query the user groups of a subspace func GetCmdQueryUserGroups() *cobra.Command { cmd := &cobra.Command{ - Use: "user-groups [subspace-id]", + Use: "list [subspace-id]", Short: "Query subspaces with optional pagination", Example: fmt.Sprintf(` %s query subspaces user-groups 1 --page=2 --limit=100`, @@ -147,12 +167,12 @@ func GetCmdQueryUserGroups() *cobra.Command { // GetCmdQueryUserGroupMembers returns the command to query the members of a specific user group func GetCmdQueryUserGroupMembers() *cobra.Command { cmd := &cobra.Command{ - Use: "user-group-members [subspace-id] [group-name]", + Use: "members [subspace-id] [group-id]", Short: "Query subspaces with optional pagination", Example: fmt.Sprintf(` %s query subspaces user-group-members 1 "Admins" --page=2 --limit=100`, version.AppName), - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { diff --git a/x/subspaces/client/cli/tx.go b/x/subspaces/client/cli/tx.go index dbba0d8fa7..e546d7f7f3 100644 --- a/x/subspaces/client/cli/tx.go +++ b/x/subspaces/client/cli/tx.go @@ -292,7 +292,7 @@ Multiple permissions must be specified separating them with a comma (,).`, FlagD func GetCmdEditUserGroup() *cobra.Command { cmd := &cobra.Command{ Use: "edit [subspace-id] [group-id]", - Args: cobra.ExactArgs(1), + Args: cobra.ExactArgs(2), Short: "Edit the group with the given id", Example: fmt.Sprintf(` %s tx subspaces groups edit 1 1 \ @@ -347,7 +347,7 @@ func GetCmdEditUserGroup() *cobra.Command { func GetCmdSetUserGroupPermissions() *cobra.Command { cmd := &cobra.Command{ Use: "set-permissions [subspace-id] [group-id] [permissions]", - Args: cobra.MinimumNArgs(3), + Args: cobra.ExactArgs(3), Short: "Set the permissions for a specific group", Long: `Set the permissions for a specific user group a given subspace. It is mandatory to specify at least one permission to be set. @@ -398,11 +398,11 @@ When specifying multiple permissions, they must be separated by a comma (,).`, // GetCmdDeleteUserGroup returns the command to delete a user group func GetCmdDeleteUserGroup() *cobra.Command { cmd := &cobra.Command{ - Use: "delete [subspace-id] [group-name]", + Use: "delete [subspace-id] [group-id]", Args: cobra.ExactArgs(2), Short: "Delete a user group from a subspace", Example: fmt.Sprintf(` -%s tx subspaces groups delete-user-group 1 "Admins" --from alice +%s tx subspaces groups delete-user-group 1 1 --from alice `, version.AppName), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientTxContext(cmd) @@ -437,11 +437,11 @@ func GetCmdDeleteUserGroup() *cobra.Command { // GetCmdAddUserToUserGroup returns the command to add a user to a user group func GetCmdAddUserToUserGroup() *cobra.Command { cmd := &cobra.Command{ - Use: "add-user [subspace-id] [group-name] [user]", + Use: "add-user [subspace-id] [group-id] [user]", Args: cobra.ExactArgs(3), Short: "Add a user to a user group", Example: fmt.Sprintf(` -%s tx subspaces groups add-user-to-user-group 1 "Admins" desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ +%s tx subspaces groups add-user-to-user-group 1 1 desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ --from alice `, version.AppName), RunE: func(cmd *cobra.Command, args []string) error { @@ -479,11 +479,11 @@ func GetCmdAddUserToUserGroup() *cobra.Command { // GetCmdRemoveUserFromUserGroup returns the command to remove a user from a user group func GetCmdRemoveUserFromUserGroup() *cobra.Command { cmd := &cobra.Command{ - Use: "remove-user [subspace-id] [group-name] [user]", + Use: "remove-user [subspace-id] [group-id] [user]", Args: cobra.ExactArgs(3), Short: "Remove a user from a user group", Example: fmt.Sprintf(` -%s tx subspaces groups remove-user-from-user-group 1 "Admins" desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ +%s tx subspaces groups remove-user-from-user-group 1 1 desmos1p8r4guvdze03md4g9zclhh6mr8ljvtd80pehr3 \ --from alice `, version.AppName), RunE: func(cmd *cobra.Command, args []string) error { @@ -524,7 +524,7 @@ func GetCmdRemoveUserFromUserGroup() *cobra.Command { func GetCmdSetUserPermissions() *cobra.Command { cmd := &cobra.Command{ Use: "set-user-permissions [subspace-id] [user] [permissions]", - Args: cobra.MinimumNArgs(3), + Args: cobra.ExactArgs(3), Short: "Set the permissions for a specific user", Long: `Set the permissions for a specific user inside a given subspace. It is mandatory to specify at least one permission to be set. diff --git a/x/subspaces/keeper/msg_server_test.go b/x/subspaces/keeper/msg_server_test.go index 6a35de3679..cc36b46797 100644 --- a/x/subspaces/keeper/msg_server_test.go +++ b/x/subspaces/keeper/msg_server_test.go @@ -1356,7 +1356,7 @@ func (suite *KeeperTestsuite) TestMsgServer_RemoveUserFromGroup() { shouldErr: true, }, { - name: "user part of group is removes correctly", + name: "user part of group is removed correctly", store: func(ctx sdk.Context) { suite.k.SaveSubspace(ctx, types.NewSubspace( 1, From bd17e42f016cfa32546e27286447d3a3b0bcbcfd Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Wed, 2 Feb 2022 07:25:46 +0100 Subject: [PATCH 35/47] added missing CLI test Signed-off-by: Riccardo Montagnin --- x/subspaces/client/cli/cli_test.go | 56 ++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/x/subspaces/client/cli/cli_test.go b/x/subspaces/client/cli/cli_test.go index cbd2c5e706..4f237ea32b 100644 --- a/x/subspaces/client/cli/cli_test.go +++ b/x/subspaces/client/cli/cli_test.go @@ -276,6 +276,62 @@ func (s *IntegrationTestSuite) TestCmdQueryUserGroups() { } } +func (s *IntegrationTestSuite) TestCmdQueryUserGroupMembers() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + expResponse types.QueryUserGroupMembersResponse + }{ + { + name: "subspace not found returns error", + args: []string{"10", "1"}, + shouldErr: true, + }, + { + name: "group not found returns error", + args: []string{"1", "10"}, + shouldErr: true, + }, + { + name: "members are returned correctly", + args: []string{ + "2", "1", + fmt.Sprintf("--%s=%d", flags.FlagLimit, 1), + fmt.Sprintf("--%s=%d", flags.FlagPage, 1), + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + }, + shouldErr: false, + expResponse: types.QueryUserGroupMembersResponse{ + Members: []string{ + "cosmos1x5pjlvufs4znnhhkwe8v4tw3kz30f3lxgwza53", + }, + }, + }, + } + + for _, tc := range testCases { + tc := tc + + s.Run(tc.name, func() { + cmd := cli.GetCmdQueryUserGroupMembers() + clientCtx := val.ClientCtx + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + + var response types.QueryUserGroupMembersResponse + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), &response), out.String()) + s.Require().Equal(tc.expResponse.Members, response.Members) + } + }) + } +} + func (s *IntegrationTestSuite) TestCmdCreateSubspace() { val := s.network.Validators[0] testCases := []struct { From 8c302fc50bdf37b32552dc49364c2a19db17cfd3 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Fri, 4 Feb 2022 07:18:35 +0100 Subject: [PATCH 36/47] fixed test name and command example Signed-off-by: Riccardo Montagnin --- x/subspaces/client/cli/cli_test.go | 2 +- x/subspaces/client/cli/query.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x/subspaces/client/cli/cli_test.go b/x/subspaces/client/cli/cli_test.go index 4f237ea32b..5dab6f452a 100644 --- a/x/subspaces/client/cli/cli_test.go +++ b/x/subspaces/client/cli/cli_test.go @@ -240,7 +240,7 @@ func (s *IntegrationTestSuite) TestCmdQueryUserGroups() { expResponse types.QueryUserGroupsResponse }{ { - name: "subspaces are returned correctly", + name: "user groups are returned correctly", args: []string{ "2", fmt.Sprintf("--%s=json", tmcli.OutputFlag), diff --git a/x/subspaces/client/cli/query.go b/x/subspaces/client/cli/query.go index c2e3602cf4..8774bc9b2c 100644 --- a/x/subspaces/client/cli/query.go +++ b/x/subspaces/client/cli/query.go @@ -170,7 +170,7 @@ func GetCmdQueryUserGroupMembers() *cobra.Command { Use: "members [subspace-id] [group-id]", Short: "Query subspaces with optional pagination", Example: fmt.Sprintf(` -%s query subspaces user-group-members 1 "Admins" --page=2 --limit=100`, +%s query subspaces user-group-members 1 1 --page=2 --limit=100`, version.AppName), Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { From 631403337e13a03ca384a110401b82ce413403d7 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 7 Feb 2022 08:00:21 +0100 Subject: [PATCH 37/47] docs: fixed typos --- x/subspaces/keeper/hooks.go | 2 +- x/subspaces/types/hooks.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x/subspaces/keeper/hooks.go b/x/subspaces/keeper/hooks.go index ff0e5e337c..5a6035d03e 100644 --- a/x/subspaces/keeper/hooks.go +++ b/x/subspaces/keeper/hooks.go @@ -8,7 +8,7 @@ import ( "github.com/desmos-labs/desmos/v2/x/subspaces/types" ) -// Implements StakingHooks interface +// Implements SubspacesHooks interface var _ types.SubspacesHooks = Keeper{} // AfterSubspaceSaved - call if hook is registered diff --git a/x/subspaces/types/hooks.go b/x/subspaces/types/hooks.go index 5977f2d72f..ebc7d19693 100644 --- a/x/subspaces/types/hooks.go +++ b/x/subspaces/types/hooks.go @@ -31,7 +31,7 @@ type SubspacesHooks interface { // MultiSubspacesHooks combines multiple subspaces hooks, all hook functions are run in array sequence type MultiSubspacesHooks []SubspacesHooks -func NewMultiStakingHooks(hooks ...SubspacesHooks) MultiSubspacesHooks { +func NewMultiSubspacesHooks(hooks ...SubspacesHooks) MultiSubspacesHooks { return hooks } From 62c55086302394445ec04cab9888358b3072b8c4 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 7 Feb 2022 08:02:45 +0100 Subject: [PATCH 38/47] chore: updated query paths --- client/docs/config.json | 3 + client/docs/swagger-ui/swagger.yaml | 919 ++++++++++++++++++++++++++ proto/desmos/subspaces/v1/query.proto | 11 +- x/subspaces/types/query.pb.go | 104 +-- x/subspaces/types/query.pb.gw.go | 8 +- 5 files changed, 984 insertions(+), 61 deletions(-) diff --git a/client/docs/config.json b/client/docs/config.json index e3538b3d4d..db0abdf66b 100644 --- a/client/docs/config.json +++ b/client/docs/config.json @@ -13,6 +13,9 @@ "Params": "ProfilesParams" } } + }, + { + "url": "./tmp-swagger-gen/desmos/subspaces/v1/query.swagger.json" } ] } \ No newline at end of file diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 38bef3acda..63060dc63b 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -4466,6 +4466,655 @@ paths: format: boolean tags: - Query + /desmos/subspaces/v1/subspaces: + get: + summary: Subspaces queries all the subspaces inside Desmos + operationId: Subspaces + responses: + '200': + description: A successful response. + schema: + type: object + properties: + subspaces: + type: array + items: + type: object + properties: + id: + type: string + format: uint64 + title: Unique id that identifies the subspace + name: + type: string + title: Human-readable name of the subspace + description: + type: string + title: Optional description of this subspace + treasury: + type: string + title: >- + Represents the account that is associated with the + subspace and + + should be used to connect external applications to + verify this subspace + owner: + type: string + title: Address of the user that owns the subspace + creator: + type: string + title: Address of the subspace creator + creation_time: + type: string + format: date-time + title: the creation time of the subspace + title: Subspace contains all the data of a Desmos subspace + pagination: + type: object + properties: + next_key: + type: string + format: byte + title: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: >- + PageResponse is to be embedded in gRPC response messages where + the + + corresponding request message has used PageRequest. + + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + title: >- + QuerySubspacesResponse is the response type for the + Query/Subspaces RPC + + method + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: pagination.key + description: |- + key is a value returned in PageResponse.next_key to begin + querying the next page most efficiently. Only one of offset or key + should be set. + in: query + required: false + type: string + format: byte + - name: pagination.offset + description: >- + offset is a numeric offset that can be used when key is unavailable. + + It is less efficient than using key. Only one of offset or key + should + + be set. + in: query + required: false + type: string + format: uint64 + - name: pagination.limit + description: >- + limit is the total number of results to be returned in the result + page. + + If left empty it will default to a value to be set by each app. + in: query + required: false + type: string + format: uint64 + - name: pagination.count_total + description: >- + count_total is set to true to indicate that the result set should + include + + a count of the total number of items available for pagination in + UIs. + + count_total is only respected when offset is used. It is ignored + when key + + is set. + in: query + required: false + type: boolean + format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean + format: boolean + tags: + - Query + '/desmos/subspaces/v1/subspaces/{subspace_id}': + get: + summary: >- + Subspace queries all the information about the subspace with the given + id + operationId: Subspace + responses: + '200': + description: A successful response. + schema: + type: object + properties: + subspace: + type: object + properties: + id: + type: string + format: uint64 + title: Unique id that identifies the subspace + name: + type: string + title: Human-readable name of the subspace + description: + type: string + title: Optional description of this subspace + treasury: + type: string + title: >- + Represents the account that is associated with the + subspace and + + should be used to connect external applications to verify + this subspace + owner: + type: string + title: Address of the user that owns the subspace + creator: + type: string + title: Address of the subspace creator + creation_time: + type: string + format: date-time + title: the creation time of the subspace + title: Subspace contains all the data of a Desmos subspace + title: >- + QuerySubspaceResponse is the response type for the Query/Subspace + method + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: subspace_id + in: path + required: true + type: string + format: uint64 + tags: + - Query + '/desmos/subspaces/v1/subspaces/{subspace_id}/groups': + get: + summary: >- + UserGroups queries all the groups that are present inside the subspace + with + + the given id + operationId: UserGroups + responses: + '200': + description: A successful response. + schema: + type: object + properties: + groups: + type: array + items: + type: object + properties: + subspace_id: + type: string + format: uint64 + id: + type: integer + format: int64 + title: Unique id that identifies the group + name: + type: string + title: Human-readable name of the user group + description: + type: string + permissions: + type: integer + format: int64 + title: UserGroup represents a group of users + pagination: + type: object + properties: + next_key: + type: string + format: byte + title: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: >- + PageResponse is to be embedded in gRPC response messages where + the + + corresponding request message has used PageRequest. + + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + title: >- + QueryUserGroupsResponse is the response type for the + Query/UserGroups RPC + + method + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: subspace_id + in: path + required: true + type: string + format: uint64 + - name: pagination.key + description: |- + key is a value returned in PageResponse.next_key to begin + querying the next page most efficiently. Only one of offset or key + should be set. + in: query + required: false + type: string + format: byte + - name: pagination.offset + description: >- + offset is a numeric offset that can be used when key is unavailable. + + It is less efficient than using key. Only one of offset or key + should + + be set. + in: query + required: false + type: string + format: uint64 + - name: pagination.limit + description: >- + limit is the total number of results to be returned in the result + page. + + If left empty it will default to a value to be set by each app. + in: query + required: false + type: string + format: uint64 + - name: pagination.count_total + description: >- + count_total is set to true to indicate that the result set should + include + + a count of the total number of items available for pagination in + UIs. + + count_total is only respected when offset is used. It is ignored + when key + + is set. + in: query + required: false + type: boolean + format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean + format: boolean + tags: + - Query + '/desmos/subspaces/v1/subspaces/{subspace_id}/groups/{group_id}': + get: + summary: |- + UserGroup queries the user group having the given id inside the specific + subspace + operationId: UserGroup + responses: + '200': + description: A successful response. + schema: + type: object + properties: + group: + type: object + properties: + subspace_id: + type: string + format: uint64 + id: + type: integer + format: int64 + title: Unique id that identifies the group + name: + type: string + title: Human-readable name of the user group + description: + type: string + permissions: + type: integer + format: int64 + title: UserGroup represents a group of users + title: >- + QueryUserGroupResponse is the response type for the + Query/UserGroup RPC + + method + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: subspace_id + in: path + required: true + type: string + format: uint64 + - name: group_id + in: path + required: true + type: integer + format: int64 + tags: + - Query + '/desmos/subspaces/v1/subspaces/{subspace_id}/groups/{group_id}/members': + get: + summary: UserGroupMembers queries all the members of a given user group + operationId: UserGroupMembers + responses: + '200': + description: A successful response. + schema: + type: object + properties: + members: + type: array + items: + type: string + pagination: + type: object + properties: + next_key: + type: string + format: byte + title: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: >- + PageResponse is to be embedded in gRPC response messages where + the + + corresponding request message has used PageRequest. + + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + title: |- + QueryUserGroupMembersResponse is the response type for the + Query/UserGroupMembers RPC method + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: subspace_id + in: path + required: true + type: string + format: uint64 + - name: group_id + in: path + required: true + type: integer + format: int64 + - name: pagination.key + description: |- + key is a value returned in PageResponse.next_key to begin + querying the next page most efficiently. Only one of offset or key + should be set. + in: query + required: false + type: string + format: byte + - name: pagination.offset + description: >- + offset is a numeric offset that can be used when key is unavailable. + + It is less efficient than using key. Only one of offset or key + should + + be set. + in: query + required: false + type: string + format: uint64 + - name: pagination.limit + description: >- + limit is the total number of results to be returned in the result + page. + + If left empty it will default to a value to be set by each app. + in: query + required: false + type: string + format: uint64 + - name: pagination.count_total + description: >- + count_total is set to true to indicate that the result set should + include + + a count of the total number of items available for pagination in + UIs. + + count_total is only respected when offset is used. It is ignored + when key + + is set. + in: query + required: false + type: boolean + format: boolean + - name: pagination.reverse + description: >- + reverse is set to true if results are to be returned in the + descending order. + + + Since: cosmos-sdk 0.43 + in: query + required: false + type: boolean + format: boolean + tags: + - Query + '/desmos/subspaces/v1/subspaces/{subspace_id}/permissions/{user}': + get: + summary: UserPermissions queries the permissions for the given user + operationId: UserPermissions + responses: + '200': + description: A successful response. + schema: + type: object + properties: + permissions: + type: integer + format: int64 + title: |- + QueryUserPermissionsRequest is the response type for the + Query/UserPermissions method + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + value: + type: string + format: byte + parameters: + - name: subspace_id + in: path + required: true + type: string + format: uint64 + - name: user + in: path + required: true + type: string + tags: + - Query definitions: cosmos.base.query.v1beta1.PageRequest: type: object @@ -8194,3 +8843,273 @@ definitions: "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } + desmos.subspaces.v1.QuerySubspaceResponse: + type: object + properties: + subspace: + type: object + properties: + id: + type: string + format: uint64 + title: Unique id that identifies the subspace + name: + type: string + title: Human-readable name of the subspace + description: + type: string + title: Optional description of this subspace + treasury: + type: string + title: >- + Represents the account that is associated with the subspace and + + should be used to connect external applications to verify this + subspace + owner: + type: string + title: Address of the user that owns the subspace + creator: + type: string + title: Address of the subspace creator + creation_time: + type: string + format: date-time + title: the creation time of the subspace + title: Subspace contains all the data of a Desmos subspace + title: QuerySubspaceResponse is the response type for the Query/Subspace method + desmos.subspaces.v1.QuerySubspacesResponse: + type: object + properties: + subspaces: + type: array + items: + type: object + properties: + id: + type: string + format: uint64 + title: Unique id that identifies the subspace + name: + type: string + title: Human-readable name of the subspace + description: + type: string + title: Optional description of this subspace + treasury: + type: string + title: >- + Represents the account that is associated with the subspace and + + should be used to connect external applications to verify this + subspace + owner: + type: string + title: Address of the user that owns the subspace + creator: + type: string + title: Address of the subspace creator + creation_time: + type: string + format: date-time + title: the creation time of the subspace + title: Subspace contains all the data of a Desmos subspace + pagination: + type: object + properties: + next_key: + type: string + format: byte + title: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: |- + PageResponse is to be embedded in gRPC response messages where the + corresponding request message has used PageRequest. + + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + title: |- + QuerySubspacesResponse is the response type for the Query/Subspaces RPC + method + desmos.subspaces.v1.QueryUserGroupMembersResponse: + type: object + properties: + members: + type: array + items: + type: string + pagination: + type: object + properties: + next_key: + type: string + format: byte + title: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: |- + PageResponse is to be embedded in gRPC response messages where the + corresponding request message has used PageRequest. + + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + title: |- + QueryUserGroupMembersResponse is the response type for the + Query/UserGroupMembers RPC method + desmos.subspaces.v1.QueryUserGroupResponse: + type: object + properties: + group: + type: object + properties: + subspace_id: + type: string + format: uint64 + id: + type: integer + format: int64 + title: Unique id that identifies the group + name: + type: string + title: Human-readable name of the user group + description: + type: string + permissions: + type: integer + format: int64 + title: UserGroup represents a group of users + title: |- + QueryUserGroupResponse is the response type for the Query/UserGroup RPC + method + desmos.subspaces.v1.QueryUserGroupsResponse: + type: object + properties: + groups: + type: array + items: + type: object + properties: + subspace_id: + type: string + format: uint64 + id: + type: integer + format: int64 + title: Unique id that identifies the group + name: + type: string + title: Human-readable name of the user group + description: + type: string + permissions: + type: integer + format: int64 + title: UserGroup represents a group of users + pagination: + type: object + properties: + next_key: + type: string + format: byte + title: |- + next_key is the key to be passed to PageRequest.key to + query the next page most efficiently + total: + type: string + format: uint64 + title: >- + total is total number of results available if + PageRequest.count_total + + was set, its value is undefined otherwise + description: |- + PageResponse is to be embedded in gRPC response messages where the + corresponding request message has used PageRequest. + + message SomeResponse { + repeated Bar results = 1; + PageResponse page = 2; + } + title: |- + QueryUserGroupsResponse is the response type for the Query/UserGroups RPC + method + desmos.subspaces.v1.QueryUserPermissionsResponse: + type: object + properties: + permissions: + type: integer + format: int64 + title: |- + QueryUserPermissionsRequest is the response type for the + Query/UserPermissions method + desmos.subspaces.v1.Subspace: + type: object + properties: + id: + type: string + format: uint64 + title: Unique id that identifies the subspace + name: + type: string + title: Human-readable name of the subspace + description: + type: string + title: Optional description of this subspace + treasury: + type: string + title: >- + Represents the account that is associated with the subspace and + + should be used to connect external applications to verify this + subspace + owner: + type: string + title: Address of the user that owns the subspace + creator: + type: string + title: Address of the subspace creator + creation_time: + type: string + format: date-time + title: the creation time of the subspace + title: Subspace contains all the data of a Desmos subspace + desmos.subspaces.v1.UserGroup: + type: object + properties: + subspace_id: + type: string + format: uint64 + id: + type: integer + format: int64 + title: Unique id that identifies the group + name: + type: string + title: Human-readable name of the user group + description: + type: string + permissions: + type: integer + format: int64 + title: UserGroup represents a group of users diff --git a/proto/desmos/subspaces/v1/query.proto b/proto/desmos/subspaces/v1/query.proto index aef6cedf44..a93879159b 100644 --- a/proto/desmos/subspaces/v1/query.proto +++ b/proto/desmos/subspaces/v1/query.proto @@ -25,28 +25,29 @@ service Query { // UserGroups queries all the groups that are present inside the subspace with // the given id rpc UserGroups(QueryUserGroupsRequest) returns (QueryUserGroupsResponse) { - option (google.api.http).get = "/desmos/subspaces/v1/groups/{subspace_id}"; + option (google.api.http).get = + "/desmos/subspaces/v1/subspaces/{subspace_id}/groups"; } // UserGroup queries the user group having the given id inside the specific // subspace rpc UserGroup(QueryUserGroupRequest) returns (QueryUserGroupResponse) { option (google.api.http).get = - "/desmos/subspaces/v1/groups/{subspace_id}/{group_id}"; + "/desmos/subspaces/v1/subspaces/{subspace_id}/groups/{group_id}"; } // UserGroupMembers queries all the members of a given user group rpc UserGroupMembers(QueryUserGroupMembersRequest) returns (QueryUserGroupMembersResponse) { - option (google.api.http).get = - "/desmos/subspaces/v1/groups/{subspace_id}/{group_id}/members"; + option (google.api.http).get = "/desmos/subspaces/v1/subspaces/" + "{subspace_id}/groups/{group_id}/members"; } // UserPermissions queries the permissions for the given user rpc UserPermissions(QueryUserPermissionsRequest) returns (QueryUserPermissionsResponse) { option (google.api.http).get = - "/desmos/subspaces/v1/permissions/{subspace_id}/{user}"; + "/desmos/subspaces/v1/subspaces/{subspace_id}/permissions/{user}"; } } diff --git a/x/subspaces/types/query.pb.go b/x/subspaces/types/query.pb.go index 8dc7de992b..898dff1c23 100644 --- a/x/subspaces/types/query.pb.go +++ b/x/subspaces/types/query.pb.go @@ -642,58 +642,58 @@ func init() { func init() { proto.RegisterFile("desmos/subspaces/v1/query.proto", fileDescriptor_883a12b013a133fc) } var fileDescriptor_883a12b013a133fc = []byte{ - // 809 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0xcf, 0x6b, 0x13, 0x41, - 0x14, 0xc7, 0x33, 0xfd, 0x99, 0xbc, 0x50, 0x2a, 0xd3, 0x5a, 0x4b, 0x6c, 0x37, 0x61, 0x85, 0xda, - 0x5f, 0xee, 0x9a, 0x58, 0xad, 0x94, 0xaa, 0x18, 0xc4, 0x52, 0x50, 0xa8, 0xab, 0x82, 0x7a, 0x29, - 0x9b, 0x66, 0x58, 0x03, 0x49, 0x76, 0x9b, 0x49, 0x82, 0xa5, 0x14, 0xa4, 0x20, 0x78, 0xf0, 0x20, - 0x78, 0x10, 0x3d, 0x15, 0xf1, 0x5f, 0xf0, 0xec, 0xb5, 0x37, 0x0b, 0x5e, 0x3c, 0x05, 0x69, 0x3d, - 0x78, 0xf0, 0xd4, 0xbf, 0x40, 0x76, 0x76, 0x66, 0xb3, 0xd9, 0xae, 0xe9, 0xf6, 0x07, 0xde, 0x92, - 0x9d, 0xef, 0xf7, 0xbd, 0xcf, 0x7b, 0x6f, 0xf6, 0x25, 0x90, 0xcc, 0x13, 0x5a, 0x32, 0xa9, 0x4a, - 0x6b, 0x39, 0x6a, 0xe9, 0x2b, 0x84, 0xaa, 0xf5, 0xb4, 0xba, 0x5a, 0x23, 0x95, 0x35, 0xc5, 0xaa, - 0x98, 0x55, 0x13, 0x0f, 0x38, 0x02, 0xc5, 0x15, 0x28, 0xf5, 0x74, 0x62, 0xd0, 0x30, 0x0d, 0x93, - 0x9d, 0xab, 0xf6, 0x27, 0x47, 0x9a, 0x18, 0x31, 0x4c, 0xd3, 0x28, 0x12, 0x55, 0xb7, 0x0a, 0xaa, - 0x5e, 0x2e, 0x9b, 0x55, 0xbd, 0x5a, 0x30, 0xcb, 0x94, 0x9f, 0xa6, 0x82, 0x32, 0x95, 0xcc, 0x3c, - 0x29, 0x0a, 0xc5, 0xe4, 0x8a, 0xc9, 0x14, 0x39, 0x9d, 0x12, 0x87, 0x41, 0xad, 0xa7, 0x73, 0xa4, - 0xaa, 0xa7, 0x55, 0x4b, 0x37, 0x0a, 0x65, 0x16, 0xce, 0xd1, 0xca, 0xcb, 0x70, 0xf6, 0x81, 0xad, - 0x78, 0x28, 0xa2, 0x69, 0x64, 0xb5, 0x46, 0x68, 0x15, 0xdf, 0x05, 0x68, 0x8a, 0x87, 0x51, 0x0a, - 0x8d, 0xc7, 0x33, 0x63, 0x8a, 0x13, 0x59, 0xb1, 0x23, 0x2b, 0x4e, 0x75, 0x3c, 0xb2, 0xb2, 0xa4, - 0x1b, 0x84, 0x7b, 0x35, 0x8f, 0x53, 0xfe, 0x8c, 0x60, 0xc8, 0x9f, 0x81, 0x5a, 0x66, 0x99, 0x12, - 0x7c, 0x1b, 0x62, 0x6e, 0x11, 0xc3, 0x28, 0xd5, 0x39, 0x1e, 0xcf, 0x8c, 0x2a, 0x01, 0x6d, 0x52, - 0x84, 0x35, 0xdb, 0xb5, 0xdd, 0x48, 0x46, 0xb4, 0xa6, 0x0b, 0x2f, 0xb4, 0x50, 0x76, 0x30, 0xca, - 0x8b, 0x87, 0x52, 0x3a, 0xf9, 0x5b, 0x30, 0x9f, 0xc2, 0x60, 0x0b, 0xa5, 0x68, 0xc3, 0x2c, 0xc4, - 0x45, 0xb6, 0xe5, 0x42, 0x9e, 0xf5, 0xa1, 0x2b, 0x3b, 0xb4, 0xdf, 0x48, 0xe2, 0x35, 0xbd, 0x54, - 0x9c, 0x93, 0x3d, 0x87, 0xb2, 0x06, 0xe2, 0xdb, 0x62, 0x7e, 0x2e, 0xfa, 0x7a, 0x2b, 0x19, 0xf9, - 0xbd, 0x95, 0x8c, 0xc8, 0x4f, 0x7c, 0x2d, 0x76, 0xeb, 0xbf, 0x05, 0x51, 0x61, 0xe0, 0x0d, 0x0e, - 0x55, 0xbe, 0x6b, 0x92, 0x3f, 0x88, 0xde, 0x3e, 0xa6, 0xa4, 0xb2, 0x50, 0x31, 0x6b, 0x16, 0x3d, - 0x29, 0xb7, 0x6f, 0xee, 0x1d, 0xc7, 0x9e, 0xfb, 0x16, 0x82, 0x73, 0x07, 0xd8, 0x78, 0xe1, 0xf3, - 0xd0, 0x63, 0xb0, 0x27, 0x7c, 0xea, 0x52, 0x60, 0xd9, 0xae, 0x91, 0xd7, 0xcd, 0x3d, 0xa7, 0x37, - 0xf3, 0x97, 0x88, 0x4f, 0xc6, 0xcd, 0x74, 0xe2, 0xee, 0x29, 0x10, 0x65, 0x94, 0xb6, 0xcb, 0x26, - 0xeb, 0xcb, 0x0e, 0xec, 0x37, 0x92, 0xfd, 0x8e, 0x4b, 0x9c, 0xc8, 0x5a, 0x2f, 0xfb, 0xb8, 0x98, - 0x97, 0x1f, 0xf9, 0x07, 0xe8, 0xf6, 0x68, 0x0e, 0xba, 0x99, 0x88, 0xdf, 0x8c, 0x70, 0x2d, 0x72, - 0x2c, 0xf2, 0x37, 0x04, 0x23, 0xad, 0x61, 0xef, 0x93, 0x52, 0x8e, 0x54, 0xe8, 0xff, 0xae, 0xcf, - 0x77, 0x9b, 0x3a, 0x8f, 0x7d, 0x9b, 0x36, 0x11, 0x8c, 0xfe, 0xa3, 0x22, 0xde, 0xaf, 0x61, 0xe8, - 0x2d, 0x39, 0x8f, 0xd8, 0xa5, 0x8a, 0x69, 0xe2, 0xeb, 0xe9, 0xdd, 0x97, 0x57, 0x08, 0xce, 0xbb, - 0x10, 0x4b, 0xa4, 0x52, 0x2a, 0x50, 0x6a, 0x2f, 0xe6, 0x13, 0x77, 0xf5, 0x02, 0x74, 0xd5, 0x28, - 0xa9, 0x30, 0xb6, 0x58, 0xb6, 0x7f, 0xbf, 0x91, 0x8c, 0x3b, 0x0e, 0xfb, 0xa9, 0xac, 0xb1, 0xc3, - 0x96, 0x85, 0x32, 0x12, 0x8c, 0xc1, 0x5b, 0x71, 0x1d, 0xe2, 0x56, 0xf3, 0x31, 0xe3, 0xe8, 0xf3, - 0x72, 0x78, 0x0e, 0x65, 0xcd, 0x2b, 0xcd, 0xfc, 0xe9, 0x85, 0x6e, 0x16, 0x1a, 0xbf, 0x41, 0x10, - 0x73, 0x37, 0x36, 0x9e, 0x0c, 0xbc, 0x7d, 0x81, 0x3f, 0x1c, 0x89, 0xa9, 0x50, 0x5a, 0x07, 0x55, - 0x1e, 0xdb, 0xfc, 0xfe, 0xeb, 0x5d, 0x47, 0x0a, 0x4b, 0x6a, 0xd0, 0xaf, 0x5a, 0x73, 0xcf, 0xbf, - 0x47, 0x10, 0x15, 0x6e, 0x3c, 0x71, 0x78, 0x06, 0x01, 0x33, 0x19, 0x46, 0xca, 0x59, 0x66, 0x18, - 0x8b, 0x82, 0xa7, 0xdb, 0xb3, 0xa8, 0xeb, 0x9e, 0x39, 0x6e, 0xe0, 0x8f, 0x08, 0xa0, 0xb9, 0xe2, - 0x70, 0x9b, 0xea, 0x0f, 0x2c, 0xe9, 0xc4, 0x74, 0x38, 0x31, 0xe7, 0x4b, 0x33, 0xbe, 0x29, 0x3c, - 0x11, 0xc8, 0xe7, 0x2c, 0x47, 0x1f, 0xdc, 0x27, 0x04, 0x31, 0x37, 0x52, 0xbb, 0x29, 0xfa, 0x37, - 0x60, 0x62, 0x2a, 0x94, 0x96, 0x93, 0xcd, 0x33, 0xb2, 0x6b, 0x78, 0x26, 0x34, 0x99, 0xba, 0x2e, - 0x96, 0xc5, 0x06, 0xfe, 0x8a, 0xe0, 0x8c, 0xff, 0xb5, 0xc6, 0xe9, 0x10, 0xf9, 0x5b, 0x97, 0x5a, - 0x22, 0x73, 0x14, 0x0b, 0x27, 0xbf, 0xc3, 0xc8, 0x6f, 0xe2, 0xf9, 0xe3, 0x90, 0xab, 0x62, 0xc3, - 0x7c, 0x41, 0xd0, 0xef, 0x7b, 0x19, 0xf1, 0xe5, 0xf6, 0x34, 0x07, 0xd7, 0x47, 0x22, 0x7d, 0x04, - 0x07, 0xc7, 0xbf, 0xc1, 0xf0, 0x67, 0xf1, 0xd5, 0x40, 0x7c, 0xcf, 0x9b, 0xed, 0xaf, 0xc1, 0xde, - 0x28, 0x1b, 0xd9, 0x7b, 0xdb, 0xbb, 0x12, 0xda, 0xd9, 0x95, 0xd0, 0xcf, 0x5d, 0x09, 0xbd, 0xdd, - 0x93, 0x22, 0x3b, 0x7b, 0x52, 0xe4, 0xc7, 0x9e, 0x14, 0x79, 0x96, 0x31, 0x0a, 0xd5, 0xe7, 0xb5, - 0x9c, 0xb2, 0x62, 0x96, 0x78, 0xe8, 0x4b, 0x45, 0x3d, 0x47, 0x45, 0x9a, 0x7a, 0x46, 0x7d, 0xe1, - 0xc9, 0x55, 0x5d, 0xb3, 0x08, 0xcd, 0xf5, 0xb0, 0x7f, 0x94, 0x57, 0xfe, 0x06, 0x00, 0x00, 0xff, - 0xff, 0x39, 0x10, 0x6e, 0x26, 0x0b, 0x0b, 0x00, 0x00, + // 810 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0x4f, 0x4f, 0x13, 0x4f, + 0x18, 0xc7, 0x3b, 0xfc, 0x6d, 0xa7, 0x21, 0xfc, 0x32, 0xf0, 0x43, 0x52, 0x61, 0xdb, 0xac, 0x09, + 0x22, 0xe0, 0x8e, 0x2d, 0x1a, 0x0d, 0x1a, 0x91, 0x1e, 0x40, 0x12, 0x35, 0xb8, 0x6a, 0xa2, 0x5e, + 0xc8, 0x96, 0x4e, 0xd6, 0x26, 0x6d, 0x67, 0xe9, 0xb4, 0x8d, 0x84, 0x90, 0x18, 0x12, 0x13, 0x0f, + 0x1e, 0x4c, 0x34, 0x31, 0xde, 0x38, 0x70, 0xf4, 0x3d, 0x78, 0xc5, 0x93, 0x24, 0x5e, 0x3c, 0x35, + 0x06, 0x3c, 0x78, 0xe6, 0x15, 0x98, 0x9d, 0x9d, 0xd9, 0x6e, 0x97, 0x5a, 0xb6, 0x94, 0x78, 0x6b, + 0x77, 0x9e, 0xef, 0xf3, 0x7c, 0xbe, 0xcf, 0x33, 0x7d, 0xb6, 0x30, 0x9e, 0x25, 0xac, 0x40, 0x19, + 0x66, 0x95, 0x0c, 0xb3, 0x8c, 0x35, 0xc2, 0x70, 0x35, 0x89, 0xd7, 0x2b, 0xa4, 0xb4, 0xa1, 0x59, + 0x25, 0x5a, 0xa6, 0x68, 0xc8, 0x09, 0xd0, 0xdc, 0x00, 0xad, 0x9a, 0x8c, 0x0d, 0x9b, 0xd4, 0xa4, + 0xfc, 0x1c, 0xdb, 0x9f, 0x9c, 0xd0, 0xd8, 0x98, 0x49, 0xa9, 0x99, 0x27, 0xd8, 0xb0, 0x72, 0xd8, + 0x28, 0x16, 0x69, 0xd9, 0x28, 0xe7, 0x68, 0x91, 0x89, 0xd3, 0x44, 0xb3, 0x4a, 0x05, 0x9a, 0x25, + 0x79, 0x19, 0x31, 0xb5, 0x46, 0x79, 0x44, 0xc6, 0x60, 0xc4, 0x61, 0xc0, 0xd5, 0x64, 0x86, 0x94, + 0x8d, 0x24, 0xb6, 0x0c, 0x33, 0x57, 0xe4, 0xe9, 0x9c, 0x58, 0x75, 0x15, 0xfe, 0xff, 0xd0, 0x8e, + 0x78, 0x24, 0xb3, 0xe9, 0x64, 0xbd, 0x42, 0x58, 0x19, 0x2d, 0x42, 0x58, 0x0f, 0x1e, 0x05, 0x09, + 0x30, 0x19, 0x4d, 0x4d, 0x68, 0x4e, 0x66, 0xcd, 0xce, 0xac, 0x39, 0xee, 0x44, 0x66, 0x6d, 0xc5, + 0x30, 0x89, 0xd0, 0xea, 0x1e, 0xa5, 0xba, 0x0b, 0xe0, 0x88, 0xbf, 0x02, 0xb3, 0x68, 0x91, 0x11, + 0xb4, 0x00, 0x23, 0xae, 0x89, 0x51, 0x90, 0xe8, 0x9e, 0x8c, 0xa6, 0xc6, 0xb5, 0x26, 0x6d, 0xd2, + 0xa4, 0x34, 0xdd, 0xb3, 0x57, 0x8b, 0x87, 0xf4, 0xba, 0x0a, 0x2d, 0x35, 0x50, 0x76, 0x71, 0xca, + 0x8b, 0x27, 0x52, 0x3a, 0xf5, 0x1b, 0x30, 0x9f, 0xc1, 0xe1, 0x06, 0x4a, 0xd9, 0x86, 0xeb, 0x30, + 0x2a, 0xab, 0xad, 0xe6, 0xb2, 0xbc, 0x0f, 0x3d, 0xe9, 0x91, 0xa3, 0x5a, 0x1c, 0x6d, 0x18, 0x85, + 0xfc, 0x9c, 0xea, 0x39, 0x54, 0x75, 0x28, 0xbf, 0x2d, 0x67, 0xe7, 0xc2, 0x6f, 0x76, 0xe2, 0xa1, + 0xdf, 0x3b, 0xf1, 0x90, 0xfa, 0xd4, 0xd7, 0x62, 0xd7, 0xff, 0x3c, 0x0c, 0x4b, 0x81, 0x68, 0x70, + 0x20, 0xfb, 0xae, 0x48, 0xfd, 0x24, 0x7b, 0xfb, 0x84, 0x91, 0xd2, 0x52, 0x89, 0x56, 0x2c, 0xd6, + 0x29, 0xb7, 0x6f, 0xee, 0x5d, 0xa7, 0x9e, 0xfb, 0x0e, 0x80, 0xe7, 0x8e, 0xb1, 0x09, 0xe3, 0xb7, + 0x60, 0x9f, 0xc9, 0x9f, 0x88, 0xa9, 0x2b, 0x4d, 0x6d, 0xbb, 0x42, 0xe1, 0x5b, 0x68, 0xce, 0x6e, + 0xe6, 0xaf, 0x80, 0x98, 0x8c, 0x5b, 0xa9, 0xe3, 0xee, 0x69, 0x30, 0xcc, 0x29, 0x6d, 0x95, 0x4d, + 0x36, 0x90, 0x1e, 0x3a, 0xaa, 0xc5, 0x07, 0x1d, 0x95, 0x3c, 0x51, 0xf5, 0x7e, 0xfe, 0x71, 0x39, + 0xab, 0x3e, 0xf6, 0x0f, 0xd0, 0xed, 0xd1, 0x1c, 0xec, 0xe5, 0x41, 0xe2, 0x66, 0x04, 0x6b, 0x91, + 0x23, 0x51, 0xbf, 0x01, 0x38, 0xd6, 0x98, 0xf6, 0x3e, 0x29, 0x64, 0x48, 0x89, 0xfd, 0x6b, 0x7f, + 0xbe, 0xdb, 0xd4, 0x7d, 0xea, 0xdb, 0xb4, 0x0d, 0xe0, 0xf8, 0x5f, 0x1c, 0x89, 0x7e, 0x8d, 0xc2, + 0xfe, 0x82, 0xf3, 0x88, 0x5f, 0xaa, 0x88, 0x2e, 0xbf, 0x9e, 0xdd, 0x7d, 0x79, 0x0d, 0xe0, 0x79, + 0x17, 0x62, 0x85, 0x94, 0x0a, 0x39, 0xc6, 0xec, 0xc5, 0xdc, 0x71, 0x57, 0x2f, 0xc0, 0x9e, 0x0a, + 0x23, 0x25, 0xce, 0x16, 0x49, 0x0f, 0x1e, 0xd5, 0xe2, 0x51, 0x47, 0x61, 0x3f, 0x55, 0x75, 0x7e, + 0xd8, 0xb0, 0x50, 0xc6, 0x9a, 0x63, 0x88, 0x56, 0xdc, 0x80, 0x51, 0xab, 0xfe, 0x98, 0x73, 0x0c, + 0x78, 0x39, 0x3c, 0x87, 0xaa, 0xee, 0x0d, 0x4d, 0x7d, 0x08, 0xc3, 0x5e, 0x9e, 0x1a, 0xbd, 0x05, + 0x30, 0xe2, 0x6e, 0x6c, 0x34, 0xd5, 0xf4, 0xf6, 0x35, 0x7d, 0x71, 0xc4, 0xa6, 0x03, 0xc5, 0x3a, + 0xa8, 0xea, 0xc4, 0xf6, 0xf7, 0x5f, 0xef, 0xbb, 0x12, 0x48, 0xc1, 0xcd, 0xde, 0x6a, 0xf5, 0x3d, + 0xff, 0x11, 0xc0, 0xb0, 0x54, 0xa3, 0x4b, 0x27, 0x57, 0x90, 0x30, 0x53, 0x41, 0x42, 0x05, 0xcb, + 0x55, 0xce, 0xa2, 0xa1, 0x99, 0xd6, 0x2c, 0x78, 0xd3, 0x33, 0xc7, 0x2d, 0xb4, 0x0b, 0x20, 0xac, + 0xaf, 0x38, 0xd4, 0xc2, 0xfd, 0xb1, 0x25, 0x1d, 0x9b, 0x09, 0x16, 0x2c, 0xf8, 0x6e, 0x72, 0xbe, + 0x6b, 0x68, 0xb6, 0x1d, 0x3e, 0x2c, 0x96, 0xe6, 0x67, 0x00, 0x23, 0x6e, 0xce, 0x56, 0xf3, 0xf4, + 0xef, 0xc2, 0xd8, 0x74, 0xa0, 0x58, 0xc1, 0xb8, 0xc8, 0x19, 0xef, 0xa0, 0xdb, 0xa7, 0x60, 0xc4, + 0x9b, 0x72, 0x81, 0x6c, 0xa1, 0xaf, 0x00, 0xfe, 0xe7, 0xff, 0xa9, 0xa3, 0x64, 0x00, 0x92, 0xc6, + 0x45, 0x17, 0x4b, 0xb5, 0x23, 0x11, 0x1e, 0x1e, 0x70, 0x0f, 0x77, 0xd1, 0x62, 0x67, 0x1e, 0xb0, + 0xdc, 0x3f, 0x5f, 0x00, 0x1c, 0xf4, 0xfd, 0x54, 0xd1, 0x95, 0xd6, 0x5c, 0xc7, 0x97, 0x4b, 0x2c, + 0xd9, 0x86, 0x42, 0x18, 0x59, 0xe2, 0x46, 0x16, 0xd0, 0x7c, 0x5b, 0x46, 0x3c, 0xfb, 0x00, 0x6f, + 0xda, 0x9b, 0x67, 0x2b, 0x7d, 0x6f, 0xef, 0x40, 0x01, 0xfb, 0x07, 0x0a, 0xf8, 0x79, 0xa0, 0x80, + 0x77, 0x87, 0x4a, 0x68, 0xff, 0x50, 0x09, 0xfd, 0x38, 0x54, 0x42, 0xcf, 0x53, 0x66, 0xae, 0xfc, + 0xa2, 0x92, 0xd1, 0xd6, 0x68, 0x41, 0x14, 0xb9, 0x9c, 0x37, 0x32, 0x4c, 0x16, 0xac, 0xa6, 0xf0, + 0x4b, 0x4f, 0xa1, 0xf2, 0x86, 0x45, 0x58, 0xa6, 0x8f, 0xff, 0xf3, 0x9c, 0xfd, 0x13, 0x00, 0x00, + 0xff, 0xff, 0xf8, 0xef, 0x64, 0xbc, 0x33, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/x/subspaces/types/query.pb.gw.go b/x/subspaces/types/query.pb.gw.go index 21fa099642..9970076688 100644 --- a/x/subspaces/types/query.pb.gw.go +++ b/x/subspaces/types/query.pb.gw.go @@ -734,13 +734,13 @@ var ( pattern_Query_Subspace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1, 1, 0, 4, 1, 5, 3}, []string{"desmos", "subspaces", "v1", "subspace_id"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_UserGroups_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"desmos", "subspaces", "v1", "groups", "subspace_id"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UserGroups_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"desmos", "subspaces", "v1", "subspace_id", "groups"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_UserGroup_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"desmos", "subspaces", "v1", "groups", "subspace_id", "group_id"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UserGroup_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"desmos", "subspaces", "v1", "subspace_id", "groups", "group_id"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_UserGroupMembers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"desmos", "subspaces", "v1", "groups", "subspace_id", "group_id", "members"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UserGroupMembers_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5, 2, 6}, []string{"desmos", "subspaces", "v1", "subspace_id", "groups", "group_id", "members"}, "", runtime.AssumeColonVerbOpt(true))) - pattern_Query_UserPermissions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"desmos", "subspaces", "v1", "permissions", "subspace_id", "user"}, "", runtime.AssumeColonVerbOpt(true))) + pattern_Query_UserPermissions_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 1, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"desmos", "subspaces", "v1", "subspace_id", "permissions", "user"}, "", runtime.AssumeColonVerbOpt(true))) ) var ( From 00f479d1c0dbcba32cba4d5b38737237da995d71 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 7 Feb 2022 09:10:40 +0100 Subject: [PATCH 39/47] updated the UserPermissionsRequestResponse type --- client/docs/swagger-ui/swagger.yaml | 108 +++ proto/desmos/subspaces/v1/models.proto | 43 + proto/desmos/subspaces/v1/query.proto | 2 + x/subspaces/keeper/grpc_query.go | 24 +- x/subspaces/keeper/grpc_query_test.go | 54 +- x/subspaces/types/models.pb.go | 1230 ++++++++++++++++++++---- x/subspaces/types/permissions.go | 24 + x/subspaces/types/query.pb.go | 170 +++- 8 files changed, 1391 insertions(+), 264 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 63060dc63b..b474bf61f2 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -5078,6 +5078,35 @@ paths: permissions: type: integer format: int64 + details: + type: array + items: + type: object + properties: + user: + title: User represents a user permission + type: object + properties: + user: + type: string + title: User for which the permission was set + permission: + type: integer + format: int64 + title: Permission set to the user + group: + title: Group represents a group permission + type: object + properties: + group_id: + type: integer + format: int64 + title: Error that is associated with the failure + permission: + type: integer + format: int64 + title: Permission set to the group + title: PermissionDetail contains the details data of a permission title: |- QueryUserPermissionsRequest is the response type for the Query/UserPermissions method @@ -8843,6 +8872,56 @@ definitions: "@type": "type.googleapis.com/google.protobuf.Duration", "value": "1.212s" } + desmos.subspaces.v1.PermissionDetail: + type: object + properties: + user: + title: User represents a user permission + type: object + properties: + user: + type: string + title: User for which the permission was set + permission: + type: integer + format: int64 + title: Permission set to the user + group: + title: Group represents a group permission + type: object + properties: + group_id: + type: integer + format: int64 + title: Error that is associated with the failure + permission: + type: integer + format: int64 + title: Permission set to the group + title: PermissionDetail contains the details data of a permission + desmos.subspaces.v1.PermissionDetail.Group: + type: object + properties: + group_id: + type: integer + format: int64 + title: Error that is associated with the failure + permission: + type: integer + format: int64 + title: Permission set to the group + title: Group is a permission that has been set to a user group + desmos.subspaces.v1.PermissionDetail.User: + type: object + properties: + user: + type: string + title: User for which the permission was set + permission: + type: integer + format: int64 + title: Permission set to the user + title: Success is a permission that has been set to a specific user desmos.subspaces.v1.QuerySubspaceResponse: type: object properties: @@ -9060,6 +9139,35 @@ definitions: permissions: type: integer format: int64 + details: + type: array + items: + type: object + properties: + user: + title: User represents a user permission + type: object + properties: + user: + type: string + title: User for which the permission was set + permission: + type: integer + format: int64 + title: Permission set to the user + group: + title: Group represents a group permission + type: object + properties: + group_id: + type: integer + format: int64 + title: Error that is associated with the failure + permission: + type: integer + format: int64 + title: Permission set to the group + title: PermissionDetail contains the details data of a permission title: |- QueryUserPermissionsRequest is the response type for the Query/UserPermissions method diff --git a/proto/desmos/subspaces/v1/models.proto b/proto/desmos/subspaces/v1/models.proto index 676e497816..d49624c9b8 100644 --- a/proto/desmos/subspaces/v1/models.proto +++ b/proto/desmos/subspaces/v1/models.proto @@ -59,4 +59,47 @@ message UserGroup { string description = 4 [ (gogoproto.moretags) = "yaml:\"description\"" ]; uint32 permissions = 5 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; +} + +// PermissionDetail contains the details data of a permission +message PermissionDetail { + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = true; + + // sum is the oneof that specifies whether this represents a user or + // group permission detail + oneof sum { + // User represents a user permission + User user = 1; + + // Group represents a group permission + Group group = 2; + } + + // Success is a permission that has been set to a specific user + message User { + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = true; + + // User for which the permission was set + string user = 1 [ (gogoproto.moretags) = "yaml:\"user\"" ]; + + // Permission set to the user + uint32 permission = 2 [ (gogoproto.moretags) = "yaml:\"permission\"" ]; + } + + // Group is a permission that has been set to a user group + message Group { + option (gogoproto.goproto_getters) = false; + option (gogoproto.equal) = true; + + // Error that is associated with the failure + uint32 group_id = 1 [ + (gogoproto.customname) = "GroupID", + (gogoproto.moretags) = "yaml:\"error\"" + ]; + + // Permission set to the group + uint32 permission = 2; + } } \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/query.proto b/proto/desmos/subspaces/v1/query.proto index a93879159b..5badeb27c6 100644 --- a/proto/desmos/subspaces/v1/query.proto +++ b/proto/desmos/subspaces/v1/query.proto @@ -148,4 +148,6 @@ message QueryUserPermissionsRequest { // Query/UserPermissions method message QueryUserPermissionsResponse { uint32 permissions = 1 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; + repeated PermissionDetail details = 2 + [ (gogoproto.moretags) = "yaml:\"details\"" ]; } \ No newline at end of file diff --git a/x/subspaces/keeper/grpc_query.go b/x/subspaces/keeper/grpc_query.go index 4b4c5413b3..da108f1afe 100644 --- a/x/subspaces/keeper/grpc_query.go +++ b/x/subspaces/keeper/grpc_query.go @@ -149,6 +149,26 @@ func (k Keeper) UserPermissions(ctx context.Context, request *types.QueryUserPer return nil, sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid user address: %s", request.User) } - permission := k.GetUserPermissions(sdkCtx, request.SubspaceId, sdkAddr) - return &types.QueryUserPermissionsResponse{Permissions: permission}, nil + // Get the user specific permissions + userPermission := k.GetUserPermissions(sdkCtx, request.SubspaceId, sdkAddr) + groupPermissions := k.GetGroupsInheritedPermissions(sdkCtx, request.SubspaceId, sdkAddr) + permissionResult := types.CombinePermissions(userPermission, groupPermissions) + + // Get the details of all the permissions + var details []*types.PermissionDetail + if userPermission != types.PermissionNothing { + details = append(details, types.NewPermissionDetailUser(request.User, userPermission)) + } + + k.IterateSubspaceGroups(sdkCtx, request.SubspaceId, func(index int64, group types.UserGroup) (stop bool) { + if k.IsMemberOfGroup(sdkCtx, request.SubspaceId, group.ID, sdkAddr) { + details = append(details, types.NewPermissionDetailGroup(group.ID, group.Permissions)) + } + return false + }) + + return &types.QueryUserPermissionsResponse{ + Permissions: permissionResult, + Details: details, + }, nil } diff --git a/x/subspaces/keeper/grpc_query_test.go b/x/subspaces/keeper/grpc_query_test.go index 84c3e671ed..63c58eca87 100644 --- a/x/subspaces/keeper/grpc_query_test.go +++ b/x/subspaces/keeper/grpc_query_test.go @@ -398,11 +398,11 @@ func (suite *KeeperTestsuite) TestQueryServer_UserGroupMembers() { func (suite *KeeperTestsuite) TestQueryServer_UserPermissions() { testCases := []struct { - name string - store func(ctx sdk.Context) - req *types.QueryUserPermissionsRequest - shouldErr bool - expPermissions types.Permission + name string + store func(ctx sdk.Context) + req *types.QueryUserPermissionsRequest + shouldErr bool + expResponse types.QueryUserPermissionsResponse }{ { name: "not found subspace returns error", @@ -429,12 +429,18 @@ func (suite *KeeperTestsuite) TestQueryServer_UserPermissions() { 1, "cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", ), - shouldErr: false, - expPermissions: types.PermissionNothing, + shouldErr: false, + expResponse: types.QueryUserPermissionsResponse{ + Permissions: types.PermissionNothing, + Details: nil, + }, }, { name: "existing permissions are returned correctly", store: func(ctx sdk.Context) { + sdkAddr, err := sdk.AccAddressFromBech32("cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e") + suite.Require().NoError(err) + suite.k.SaveSubspace(ctx, types.NewSubspace( 1, "Test subspace", @@ -445,16 +451,41 @@ func (suite *KeeperTestsuite) TestQueryServer_UserPermissions() { time.Date(2020, 1, 1, 12, 00, 00, 000, time.UTC), )) - sdkAddr, err := sdk.AccAddressFromBech32("cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e") + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 1, + "Test group", + "This is a test group", + types.PermissionChangeInfo, + )) + err = suite.k.AddUserToGroup(ctx, 1, 1, sdkAddr) + suite.Require().NoError(err) + + suite.k.SaveUserGroup(ctx, types.NewUserGroup( + 1, + 2, + "Another test group", + "This is another test group", + types.PermissionSetPermissions, + )) + err = suite.k.AddUserToGroup(ctx, 1, 2, sdkAddr) suite.Require().NoError(err) + suite.k.SetUserPermissions(ctx, 1, sdkAddr, types.PermissionWrite) }, req: types.NewQueryUserPermissionsRequest( 1, "cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", ), - shouldErr: false, - expPermissions: types.PermissionWrite, + shouldErr: false, + expResponse: types.QueryUserPermissionsResponse{ + Permissions: types.PermissionWrite | types.PermissionChangeInfo | types.PermissionSetPermissions, + Details: []*types.PermissionDetail{ + types.NewPermissionDetailUser("cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", types.PermissionWrite), + types.NewPermissionDetailGroup(1, types.PermissionChangeInfo), + types.NewPermissionDetailGroup(2, types.PermissionSetPermissions), + }, + }, }, } @@ -471,7 +502,8 @@ func (suite *KeeperTestsuite) TestQueryServer_UserPermissions() { suite.Require().Error(err) } else { suite.Require().NoError(err) - suite.Require().Equal(tc.expPermissions, res.Permissions) + suite.Require().Equal(tc.expResponse.Permissions, res.Permissions) + suite.Require().Equal(tc.expResponse.Details, res.Details) } }) } diff --git a/x/subspaces/types/models.pb.go b/x/subspaces/types/models.pb.go index 81ced48fea..335ba2f080 100644 --- a/x/subspaces/types/models.pb.go +++ b/x/subspaces/types/models.pb.go @@ -207,46 +207,230 @@ func (m *UserGroup) GetPermissions() uint32 { return 0 } +// PermissionDetail contains the details data of a permission +type PermissionDetail struct { + // sum is the oneof that specifies whether this represents a user or + // group permission detail + // + // Types that are valid to be assigned to Sum: + // *PermissionDetail_User_ + // *PermissionDetail_Group_ + Sum isPermissionDetail_Sum `protobuf_oneof:"sum"` +} + +func (m *PermissionDetail) Reset() { *m = PermissionDetail{} } +func (m *PermissionDetail) String() string { return proto.CompactTextString(m) } +func (*PermissionDetail) ProtoMessage() {} +func (*PermissionDetail) Descriptor() ([]byte, []int) { + return fileDescriptor_58f218b6c9069791, []int{2} +} +func (m *PermissionDetail) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PermissionDetail) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PermissionDetail.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PermissionDetail) XXX_Merge(src proto.Message) { + xxx_messageInfo_PermissionDetail.Merge(m, src) +} +func (m *PermissionDetail) XXX_Size() int { + return m.Size() +} +func (m *PermissionDetail) XXX_DiscardUnknown() { + xxx_messageInfo_PermissionDetail.DiscardUnknown(m) +} + +var xxx_messageInfo_PermissionDetail proto.InternalMessageInfo + +type isPermissionDetail_Sum interface { + isPermissionDetail_Sum() + Equal(interface{}) bool + MarshalTo([]byte) (int, error) + Size() int +} + +type PermissionDetail_User_ struct { + User *PermissionDetail_User `protobuf:"bytes,1,opt,name=user,proto3,oneof" json:"user,omitempty"` +} +type PermissionDetail_Group_ struct { + Group *PermissionDetail_Group `protobuf:"bytes,2,opt,name=group,proto3,oneof" json:"group,omitempty"` +} + +func (*PermissionDetail_User_) isPermissionDetail_Sum() {} +func (*PermissionDetail_Group_) isPermissionDetail_Sum() {} + +func (m *PermissionDetail) GetSum() isPermissionDetail_Sum { + if m != nil { + return m.Sum + } + return nil +} + +func (m *PermissionDetail) GetUser() *PermissionDetail_User { + if x, ok := m.GetSum().(*PermissionDetail_User_); ok { + return x.User + } + return nil +} + +func (m *PermissionDetail) GetGroup() *PermissionDetail_Group { + if x, ok := m.GetSum().(*PermissionDetail_Group_); ok { + return x.Group + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*PermissionDetail) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*PermissionDetail_User_)(nil), + (*PermissionDetail_Group_)(nil), + } +} + +// Success is a permission that has been set to a specific user +type PermissionDetail_User struct { + // User for which the permission was set + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty" yaml:"user"` + // Permission set to the user + Permission uint32 `protobuf:"varint,2,opt,name=permission,proto3" json:"permission,omitempty" yaml:"permission"` +} + +func (m *PermissionDetail_User) Reset() { *m = PermissionDetail_User{} } +func (m *PermissionDetail_User) String() string { return proto.CompactTextString(m) } +func (*PermissionDetail_User) ProtoMessage() {} +func (*PermissionDetail_User) Descriptor() ([]byte, []int) { + return fileDescriptor_58f218b6c9069791, []int{2, 0} +} +func (m *PermissionDetail_User) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PermissionDetail_User) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PermissionDetail_User.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PermissionDetail_User) XXX_Merge(src proto.Message) { + xxx_messageInfo_PermissionDetail_User.Merge(m, src) +} +func (m *PermissionDetail_User) XXX_Size() int { + return m.Size() +} +func (m *PermissionDetail_User) XXX_DiscardUnknown() { + xxx_messageInfo_PermissionDetail_User.DiscardUnknown(m) +} + +var xxx_messageInfo_PermissionDetail_User proto.InternalMessageInfo + +// Group is a permission that has been set to a user group +type PermissionDetail_Group struct { + // Error that is associated with the failure + GroupID uint32 `protobuf:"varint,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty" yaml:"error"` + // Permission set to the group + Permission uint32 `protobuf:"varint,2,opt,name=permission,proto3" json:"permission,omitempty"` +} + +func (m *PermissionDetail_Group) Reset() { *m = PermissionDetail_Group{} } +func (m *PermissionDetail_Group) String() string { return proto.CompactTextString(m) } +func (*PermissionDetail_Group) ProtoMessage() {} +func (*PermissionDetail_Group) Descriptor() ([]byte, []int) { + return fileDescriptor_58f218b6c9069791, []int{2, 1} +} +func (m *PermissionDetail_Group) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PermissionDetail_Group) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PermissionDetail_Group.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PermissionDetail_Group) XXX_Merge(src proto.Message) { + xxx_messageInfo_PermissionDetail_Group.Merge(m, src) +} +func (m *PermissionDetail_Group) XXX_Size() int { + return m.Size() +} +func (m *PermissionDetail_Group) XXX_DiscardUnknown() { + xxx_messageInfo_PermissionDetail_Group.DiscardUnknown(m) +} + +var xxx_messageInfo_PermissionDetail_Group proto.InternalMessageInfo + func init() { proto.RegisterType((*Subspace)(nil), "desmos.subspaces.v1.Subspace") proto.RegisterType((*UserGroup)(nil), "desmos.subspaces.v1.UserGroup") + proto.RegisterType((*PermissionDetail)(nil), "desmos.subspaces.v1.PermissionDetail") + proto.RegisterType((*PermissionDetail_User)(nil), "desmos.subspaces.v1.PermissionDetail.User") + proto.RegisterType((*PermissionDetail_Group)(nil), "desmos.subspaces.v1.PermissionDetail.Group") } func init() { proto.RegisterFile("desmos/subspaces/v1/models.proto", fileDescriptor_58f218b6c9069791) } var fileDescriptor_58f218b6c9069791 = []byte{ - // 487 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0x31, 0x8f, 0xd3, 0x30, - 0x18, 0x86, 0xeb, 0xb6, 0x77, 0xd7, 0xba, 0x57, 0x0e, 0xb9, 0x27, 0x14, 0x75, 0x88, 0x2b, 0x1f, - 0x42, 0x1d, 0x20, 0xd6, 0x95, 0xe5, 0x74, 0x63, 0x05, 0x42, 0x27, 0x31, 0x05, 0x58, 0x58, 0x4e, - 0x69, 0x63, 0x8a, 0xa5, 0x26, 0x8e, 0xec, 0xa4, 0xd0, 0x95, 0x5f, 0x70, 0x23, 0x62, 0xba, 0x9f, - 0x73, 0xe3, 0x8d, 0x4c, 0x06, 0xa5, 0x0b, 0x73, 0x7e, 0x01, 0x8a, 0x9d, 0x94, 0x6c, 0xc0, 0x66, - 0x7f, 0xef, 0xf3, 0x79, 0x78, 0x1f, 0x19, 0x4e, 0x42, 0xa6, 0x22, 0xa1, 0xa8, 0xca, 0x16, 0x2a, - 0x09, 0x96, 0x4c, 0xd1, 0xcd, 0x39, 0x8d, 0x44, 0xc8, 0xd6, 0xca, 0x4b, 0xa4, 0x48, 0x05, 0x1a, - 0x59, 0xc2, 0xdb, 0x13, 0xde, 0xe6, 0x7c, 0x7c, 0xba, 0x12, 0x2b, 0x61, 0x72, 0x5a, 0x9e, 0x2c, - 0x3a, 0xc6, 0x2b, 0x21, 0x56, 0x6b, 0x46, 0xcd, 0x6d, 0x91, 0x7d, 0xa0, 0x29, 0x8f, 0x98, 0x4a, - 0x83, 0x28, 0xb1, 0x00, 0xf9, 0xd2, 0x81, 0xbd, 0x37, 0xd5, 0x3b, 0xe8, 0x0c, 0xb6, 0x79, 0xe8, - 0x80, 0x09, 0x98, 0x76, 0xe7, 0xa3, 0x5c, 0xe3, 0xf6, 0xd5, 0x8b, 0x42, 0xe3, 0xfe, 0x36, 0x88, - 0xd6, 0x97, 0x84, 0x87, 0xc4, 0x6f, 0xf3, 0x10, 0x9d, 0xc1, 0x6e, 0x1c, 0x44, 0xcc, 0x69, 0x4f, - 0xc0, 0xb4, 0x3f, 0x3f, 0x29, 0x34, 0x1e, 0x58, 0xa0, 0x9c, 0x12, 0xdf, 0x84, 0xe8, 0x02, 0x0e, - 0x42, 0xa6, 0x96, 0x92, 0x27, 0x29, 0x17, 0xb1, 0xd3, 0x31, 0xec, 0xa3, 0x42, 0x63, 0x64, 0xd9, - 0x46, 0x48, 0xfc, 0x26, 0x8a, 0x28, 0xec, 0xa5, 0x92, 0x05, 0x2a, 0x93, 0x5b, 0xa7, 0x6b, 0xd6, - 0x46, 0x85, 0xc6, 0x27, 0x76, 0xad, 0x4e, 0x88, 0xbf, 0x87, 0xd0, 0x13, 0x78, 0x20, 0x3e, 0xc5, - 0x4c, 0x3a, 0x07, 0x86, 0x7e, 0x58, 0x68, 0x7c, 0x6c, 0x69, 0x33, 0x26, 0xbe, 0x8d, 0xd1, 0x53, - 0x78, 0xb4, 0x94, 0x2c, 0x48, 0x85, 0x74, 0x0e, 0x0d, 0x89, 0x0a, 0x8d, 0x1f, 0x58, 0xb2, 0x0a, - 0x88, 0x5f, 0x23, 0x28, 0x80, 0x43, 0x73, 0xe4, 0x22, 0xbe, 0x2e, 0x3b, 0x73, 0x8e, 0x26, 0x60, - 0x3a, 0x98, 0x8d, 0x3d, 0x5b, 0xa8, 0x57, 0x17, 0xea, 0xbd, 0xad, 0x0b, 0x9d, 0x4f, 0xee, 0x34, - 0x6e, 0x15, 0x1a, 0x9f, 0x36, 0xde, 0xac, 0xd7, 0xc9, 0xcd, 0x0f, 0x0c, 0xfc, 0xe3, 0x7a, 0x56, - 0x2e, 0x5d, 0xf6, 0xbe, 0xde, 0x62, 0xf0, 0xeb, 0x16, 0x03, 0xf2, 0xad, 0x0d, 0xfb, 0xef, 0x14, - 0x93, 0xaf, 0xa4, 0xc8, 0x12, 0xf4, 0x12, 0x0e, 0x6a, 0xb3, 0xd7, 0x7b, 0x1d, 0x8f, 0x73, 0x8d, - 0x61, 0x2d, 0xca, 0x68, 0xa9, 0x9a, 0x6c, 0xa0, 0xc4, 0x87, 0xf5, 0xed, 0x2a, 0xac, 0x64, 0x96, - 0x96, 0x86, 0x7f, 0x97, 0xd9, 0xf9, 0x0f, 0x99, 0xdd, 0x7f, 0x97, 0x79, 0x01, 0x07, 0x09, 0x93, - 0x11, 0x57, 0x8a, 0x8b, 0x58, 0x19, 0x43, 0xc3, 0xe6, 0x66, 0x23, 0x24, 0x7e, 0x13, 0xfd, 0x53, - 0xce, 0xfc, 0xf5, 0x5d, 0xee, 0x82, 0xfb, 0xdc, 0x05, 0x3f, 0x73, 0x17, 0xdc, 0xec, 0xdc, 0xd6, - 0xfd, 0xce, 0x6d, 0x7d, 0xdf, 0xb9, 0xad, 0xf7, 0xb3, 0x15, 0x4f, 0x3f, 0x66, 0x0b, 0x6f, 0x29, - 0x22, 0x6a, 0xbf, 0xc4, 0xb3, 0x75, 0xb0, 0x50, 0xd5, 0x99, 0x6e, 0x66, 0xf4, 0x73, 0xe3, 0x17, - 0xa5, 0xdb, 0x84, 0xa9, 0xc5, 0xa1, 0x11, 0xf7, 0xfc, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0x76, - 0x19, 0x66, 0xe6, 0x66, 0x03, 0x00, 0x00, + // 635 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0x4f, 0x6f, 0xd3, 0x30, + 0x00, 0xc5, 0x93, 0xfe, 0xd9, 0x3a, 0x67, 0x65, 0xc3, 0x1b, 0x28, 0x2a, 0x52, 0x5c, 0x79, 0x08, + 0x4d, 0xfc, 0x49, 0xb4, 0x22, 0xd0, 0xb4, 0x13, 0x2a, 0x43, 0x6c, 0x12, 0x07, 0x14, 0xe0, 0xc2, + 0x65, 0x4a, 0x1b, 0x53, 0x2c, 0x35, 0x75, 0x64, 0x27, 0x83, 0x5d, 0xe1, 0xc2, 0x71, 0x47, 0xc4, + 0x69, 0x1f, 0x67, 0xc7, 0x1d, 0x39, 0x19, 0xd4, 0x5e, 0x38, 0xe7, 0x13, 0xa0, 0xd8, 0x49, 0x17, + 0xc6, 0x24, 0xc6, 0xcd, 0xf1, 0xfb, 0x3d, 0xdb, 0x7d, 0xcf, 0x2e, 0xe8, 0x86, 0x44, 0x44, 0x4c, + 0x78, 0x22, 0x1d, 0x88, 0x38, 0x18, 0x12, 0xe1, 0x1d, 0x6e, 0x79, 0x11, 0x0b, 0xc9, 0x58, 0xb8, + 0x31, 0x67, 0x09, 0x83, 0x6b, 0x9a, 0x70, 0xe7, 0x84, 0x7b, 0xb8, 0xd5, 0x59, 0x1f, 0xb1, 0x11, + 0x53, 0xba, 0x97, 0x8f, 0x34, 0xda, 0x41, 0x23, 0xc6, 0x46, 0x63, 0xe2, 0xa9, 0xaf, 0x41, 0xfa, + 0xce, 0x4b, 0x68, 0x44, 0x44, 0x12, 0x44, 0xb1, 0x06, 0xf0, 0xa7, 0x3a, 0x68, 0xbd, 0x2a, 0xd6, + 0x81, 0x1b, 0xa0, 0x46, 0x43, 0xdb, 0xec, 0x9a, 0x9b, 0x8d, 0xfe, 0xda, 0x54, 0xa2, 0xda, 0xfe, + 0x6e, 0x26, 0xd1, 0xd2, 0x51, 0x10, 0x8d, 0x77, 0x30, 0x0d, 0xb1, 0x5f, 0xa3, 0x21, 0xdc, 0x00, + 0x8d, 0x49, 0x10, 0x11, 0xbb, 0xd6, 0x35, 0x37, 0x97, 0xfa, 0x2b, 0x99, 0x44, 0x96, 0x06, 0xf2, + 0x59, 0xec, 0x2b, 0x11, 0x6e, 0x03, 0x2b, 0x24, 0x62, 0xc8, 0x69, 0x9c, 0x50, 0x36, 0xb1, 0xeb, + 0x8a, 0xbd, 0x99, 0x49, 0x04, 0x35, 0x5b, 0x11, 0xb1, 0x5f, 0x45, 0xa1, 0x07, 0x5a, 0x09, 0x27, + 0x81, 0x48, 0xf9, 0x91, 0xdd, 0x50, 0xb6, 0xb5, 0x4c, 0xa2, 0x15, 0x6d, 0x2b, 0x15, 0xec, 0xcf, + 0x21, 0x78, 0x07, 0x34, 0xd9, 0x87, 0x09, 0xe1, 0x76, 0x53, 0xd1, 0xab, 0x99, 0x44, 0xcb, 0x9a, + 0x56, 0xd3, 0xd8, 0xd7, 0x32, 0xbc, 0x0f, 0x16, 0x87, 0x9c, 0x04, 0x09, 0xe3, 0xf6, 0x82, 0x22, + 0x61, 0x26, 0xd1, 0x35, 0x4d, 0x16, 0x02, 0xf6, 0x4b, 0x04, 0x06, 0xa0, 0xad, 0x86, 0x94, 0x4d, + 0x0e, 0xf2, 0xcc, 0xec, 0xc5, 0xae, 0xb9, 0x69, 0xf5, 0x3a, 0xae, 0x0e, 0xd4, 0x2d, 0x03, 0x75, + 0x5f, 0x97, 0x81, 0xf6, 0xbb, 0xa7, 0x12, 0x19, 0x99, 0x44, 0xeb, 0x95, 0x35, 0x4b, 0x3b, 0x3e, + 0xfe, 0x81, 0x4c, 0x7f, 0xb9, 0x9c, 0xcb, 0x4d, 0x3b, 0xad, 0xaf, 0x27, 0xc8, 0xfc, 0x75, 0x82, + 0x4c, 0xfc, 0xad, 0x06, 0x96, 0xde, 0x08, 0xc2, 0x9f, 0x73, 0x96, 0xc6, 0xf0, 0x19, 0xb0, 0xca, + 0x66, 0x0f, 0xe6, 0x75, 0xdc, 0x9e, 0x4a, 0x04, 0xca, 0xa2, 0x54, 0x2d, 0x45, 0x92, 0x15, 0x14, + 0xfb, 0xa0, 0xfc, 0xda, 0x0f, 0x8b, 0x32, 0xf3, 0x96, 0xda, 0xff, 0x2e, 0xb3, 0xfe, 0x1f, 0x65, + 0x36, 0xae, 0x5e, 0xe6, 0x36, 0xb0, 0x62, 0xc2, 0x23, 0x2a, 0x04, 0x65, 0x13, 0xa1, 0x1a, 0x6a, + 0x57, 0x9d, 0x15, 0x11, 0xfb, 0x55, 0xb4, 0x12, 0xce, 0xe7, 0x3a, 0x58, 0x7d, 0x39, 0x57, 0x76, + 0x49, 0x12, 0xd0, 0x31, 0x7c, 0x02, 0x1a, 0xa9, 0x20, 0x5c, 0x85, 0x63, 0xf5, 0xee, 0xba, 0x97, + 0xbc, 0x08, 0xf7, 0xa2, 0xc9, 0xcd, 0x23, 0xde, 0x33, 0x7c, 0xe5, 0x84, 0x4f, 0x41, 0x73, 0x94, + 0xc7, 0xad, 0x12, 0xb2, 0x7a, 0xf7, 0xae, 0xb6, 0x84, 0x6a, 0x68, 0xcf, 0xf0, 0xb5, 0xb7, 0x33, + 0x06, 0x8d, 0x7c, 0xd1, 0x3c, 0xc6, 0xf9, 0x71, 0xfe, 0x88, 0x31, 0x9f, 0xc5, 0xc5, 0x8e, 0x8f, + 0x00, 0x38, 0xff, 0x85, 0x45, 0x31, 0x37, 0x32, 0x89, 0xae, 0x5f, 0xcc, 0x02, 0xfb, 0x15, 0x70, + 0xa7, 0xf5, 0xe5, 0x04, 0x19, 0x79, 0x12, 0x1d, 0x0a, 0x9a, 0xfa, 0x86, 0x3c, 0x06, 0x2d, 0xb5, + 0x7f, 0x79, 0x3d, 0xda, 0xfd, 0x5b, 0x53, 0x89, 0x16, 0x95, 0xa8, 0x5a, 0x2e, 0x1e, 0x00, 0xe1, + 0x5c, 0x5d, 0x6a, 0x05, 0xef, 0x87, 0xd0, 0xf9, 0xfb, 0x04, 0x97, 0x6f, 0x75, 0x3e, 0xea, 0x37, + 0x41, 0x5d, 0xa4, 0x51, 0xff, 0xc5, 0xe9, 0xd4, 0x31, 0xcf, 0xa6, 0x8e, 0xf9, 0x73, 0xea, 0x98, + 0xc7, 0x33, 0xc7, 0x38, 0x9b, 0x39, 0xc6, 0xf7, 0x99, 0x63, 0xbc, 0xed, 0x8d, 0x68, 0xf2, 0x3e, + 0x1d, 0xb8, 0x43, 0x16, 0x79, 0x3a, 0xc3, 0x07, 0xe3, 0x60, 0x20, 0x8a, 0xb1, 0x77, 0xd8, 0xf3, + 0x3e, 0x56, 0xfe, 0xcb, 0x92, 0xa3, 0x98, 0x88, 0xc1, 0x82, 0x7a, 0x3e, 0x0f, 0x7f, 0x07, 0x00, + 0x00, 0xff, 0xff, 0x0c, 0x90, 0x85, 0x9f, 0xec, 0x04, 0x00, 0x00, } func (this *Subspace) Equal(that interface{}) bool { @@ -327,6 +511,138 @@ func (this *UserGroup) Equal(that interface{}) bool { } return true } +func (this *PermissionDetail) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PermissionDetail) + if !ok { + that2, ok := that.(PermissionDetail) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if that1.Sum == nil { + if this.Sum != nil { + return false + } + } else if this.Sum == nil { + return false + } else if !this.Sum.Equal(that1.Sum) { + return false + } + return true +} +func (this *PermissionDetail_User_) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PermissionDetail_User_) + if !ok { + that2, ok := that.(PermissionDetail_User_) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.User.Equal(that1.User) { + return false + } + return true +} +func (this *PermissionDetail_Group_) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PermissionDetail_Group_) + if !ok { + that2, ok := that.(PermissionDetail_Group_) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if !this.Group.Equal(that1.Group) { + return false + } + return true +} +func (this *PermissionDetail_User) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PermissionDetail_User) + if !ok { + that2, ok := that.(PermissionDetail_User) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.User != that1.User { + return false + } + if this.Permission != that1.Permission { + return false + } + return true +} +func (this *PermissionDetail_Group) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*PermissionDetail_Group) + if !ok { + that2, ok := that.(PermissionDetail_Group) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.GroupID != that1.GroupID { + return false + } + if this.Permission != that1.Permission { + return false + } + return true +} func (m *Subspace) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -450,64 +766,206 @@ func (m *UserGroup) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func encodeVarintModels(dAtA []byte, offset int, v uint64) int { - offset -= sovModels(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ +func (m *PermissionDetail) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err } - dAtA[offset] = uint8(v) - return base + return dAtA[:n], nil } -func (m *Subspace) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if m.ID != 0 { - n += 1 + sovModels(uint64(m.ID)) - } - l = len(m.Name) - if l > 0 { - n += 1 + l + sovModels(uint64(l)) - } - l = len(m.Description) - if l > 0 { - n += 1 + l + sovModels(uint64(l)) - } - l = len(m.Treasury) - if l > 0 { - n += 1 + l + sovModels(uint64(l)) - } - l = len(m.Owner) - if l > 0 { - n += 1 + l + sovModels(uint64(l)) - } - l = len(m.Creator) - if l > 0 { - n += 1 + l + sovModels(uint64(l)) - } - l = github_com_gogo_protobuf_types.SizeOfStdTime(m.CreationTime) - n += 1 + l + sovModels(uint64(l)) - return n + +func (m *PermissionDetail) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *UserGroup) Size() (n int) { - if m == nil { - return 0 - } +func (m *PermissionDetail) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i var l int _ = l - if m.SubspaceID != 0 { - n += 1 + sovModels(uint64(m.SubspaceID)) - } - if m.ID != 0 { - n += 1 + sovModels(uint64(m.ID)) + if m.Sum != nil { + { + size := m.Sum.Size() + i -= size + if _, err := m.Sum.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + } } - l = len(m.Name) + return len(dAtA) - i, nil +} + +func (m *PermissionDetail_User_) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PermissionDetail_User_) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.User != nil { + { + size, err := m.User.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintModels(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} +func (m *PermissionDetail_Group_) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PermissionDetail_Group_) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + if m.Group != nil { + { + size, err := m.Group.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintModels(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} +func (m *PermissionDetail_User) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PermissionDetail_User) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PermissionDetail_User) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Permission != 0 { + i = encodeVarintModels(dAtA, i, uint64(m.Permission)) + i-- + dAtA[i] = 0x10 + } + if len(m.User) > 0 { + i -= len(m.User) + copy(dAtA[i:], m.User) + i = encodeVarintModels(dAtA, i, uint64(len(m.User))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PermissionDetail_Group) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PermissionDetail_Group) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PermissionDetail_Group) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Permission != 0 { + i = encodeVarintModels(dAtA, i, uint64(m.Permission)) + i-- + dAtA[i] = 0x10 + } + if m.GroupID != 0 { + i = encodeVarintModels(dAtA, i, uint64(m.GroupID)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintModels(dAtA []byte, offset int, v uint64) int { + offset -= sovModels(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Subspace) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ID != 0 { + n += 1 + sovModels(uint64(m.ID)) + } + l = len(m.Name) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = len(m.Treasury) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = len(m.Owner) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + l = github_com_gogo_protobuf_types.SizeOfStdTime(m.CreationTime) + n += 1 + l + sovModels(uint64(l)) + return n +} + +func (m *UserGroup) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SubspaceID != 0 { + n += 1 + sovModels(uint64(m.SubspaceID)) + } + if m.ID != 0 { + n += 1 + sovModels(uint64(m.ID)) + } + l = len(m.Name) if l > 0 { n += 1 + l + sovModels(uint64(l)) } @@ -518,16 +976,345 @@ func (m *UserGroup) Size() (n int) { if m.Permissions != 0 { n += 1 + sovModels(uint64(m.Permissions)) } - return n -} + return n +} + +func (m *PermissionDetail) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Sum != nil { + n += m.Sum.Size() + } + return n +} + +func (m *PermissionDetail_User_) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.User != nil { + l = m.User.Size() + n += 1 + l + sovModels(uint64(l)) + } + return n +} +func (m *PermissionDetail_Group_) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Group != nil { + l = m.Group.Size() + n += 1 + l + sovModels(uint64(l)) + } + return n +} +func (m *PermissionDetail_User) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.User) + if l > 0 { + n += 1 + l + sovModels(uint64(l)) + } + if m.Permission != 0 { + n += 1 + sovModels(uint64(m.Permission)) + } + return n +} + +func (m *PermissionDetail_Group) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.GroupID != 0 { + n += 1 + sovModels(uint64(m.GroupID)) + } + if m.Permission != 0 { + n += 1 + sovModels(uint64(m.Permission)) + } + return n +} + +func sovModels(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozModels(x uint64) (n int) { + return sovModels(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Subspace) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Subspace: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Subspace: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + } + m.ID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ID |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Treasury = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Owner = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CreationTime", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.CreationTime, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipModels(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthModels + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } -func sovModels(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozModels(x uint64) (n int) { - return sovModels(uint64((x << 1) ^ uint64((int64(x) >> 63)))) + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil } -func (m *Subspace) Unmarshal(dAtA []byte) error { +func (m *UserGroup) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -550,17 +1337,17 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Subspace: wiretype end group for non-group") + return fmt.Errorf("proto: UserGroup: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Subspace: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: UserGroup: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) } - m.ID = 0 + m.SubspaceID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModels @@ -570,16 +1357,16 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ID |= uint64(b&0x7F) << shift + m.SubspaceID |= uint64(b&0x7F) << shift if b < 0x80 { break } } case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) } - var stringLen uint64 + m.ID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModels @@ -589,27 +1376,14 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.ID |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthModels - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthModels - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -637,11 +1411,11 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Description = string(dAtA[iNdEx:postIndex]) + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Treasury", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -669,13 +1443,13 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Treasury = string(dAtA[iNdEx:postIndex]) + m.Description = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Owner", wireType) + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) } - var stringLen uint64 + m.Permissions = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModels @@ -685,29 +1459,66 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.Permissions |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthModels + default: + iNdEx = preIndex + skippy, err := skipModels(dAtA[iNdEx:]) + if err != nil { + return err } - postIndex := iNdEx + intStringLen - if postIndex < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthModels } - if postIndex > l { + if (iNdEx + skippy) > l { return io.ErrUnexpectedEOF } - m.Owner = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 6: + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PermissionDetail) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PermissionDetail: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PermissionDetail: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } - var stringLen uint64 + var msglen int for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModels @@ -717,27 +1528,30 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + msglen |= int(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { + if msglen < 0 { return ErrInvalidLengthModels } - postIndex := iNdEx + intStringLen + postIndex := iNdEx + msglen if postIndex < 0 { return ErrInvalidLengthModels } if postIndex > l { return io.ErrUnexpectedEOF } - m.Creator = string(dAtA[iNdEx:postIndex]) + v := &PermissionDetail_User{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + m.Sum = &PermissionDetail_User_{v} iNdEx = postIndex - case 7: + case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field CreationTime", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Group", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -764,9 +1578,11 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if err := github_com_gogo_protobuf_types.StdTimeUnmarshal(&m.CreationTime, dAtA[iNdEx:postIndex]); err != nil { + v := &PermissionDetail_Group{} + if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } + m.Sum = &PermissionDetail_Group_{v} iNdEx = postIndex default: iNdEx = preIndex @@ -789,7 +1605,7 @@ func (m *Subspace) Unmarshal(dAtA []byte) error { } return nil } -func (m *UserGroup) Unmarshal(dAtA []byte) error { +func (m *PermissionDetail_User) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -812,17 +1628,17 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: UserGroup: wiretype end group for non-group") + return fmt.Errorf("proto: User: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: UserGroup: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: User: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field SubspaceID", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) } - m.SubspaceID = 0 + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModels @@ -832,16 +1648,29 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.SubspaceID |= uint64(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthModels + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthModels + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.User = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field ID", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Permission", wireType) } - m.ID = 0 + m.Permission = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModels @@ -851,48 +1680,66 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.ID |= uint32(b&0x7F) << shift + m.Permission |= uint32(b&0x7F) << shift if b < 0x80 { break } } - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowModels - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } + default: + iNdEx = preIndex + skippy, err := skipModels(dAtA[iNdEx:]) + if err != nil { + return err } - intStringLen := int(stringLen) - if intStringLen < 0 { + if (skippy < 0) || (iNdEx+skippy) < 0 { return ErrInvalidLengthModels } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthModels + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF } - if postIndex > l { + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PermissionDetail_Group) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowModels + } + if iNdEx >= l { return io.ErrUnexpectedEOF } - m.Name = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 4: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break } - var stringLen uint64 + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Group: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Group: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GroupID", wireType) + } + m.GroupID = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModels @@ -902,29 +1749,16 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.GroupID |= uint32(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthModels - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthModels - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Description = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 5: + case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Permissions", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Permission", wireType) } - m.Permissions = 0 + m.Permission = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowModels @@ -934,7 +1768,7 @@ func (m *UserGroup) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.Permissions |= uint32(b&0x7F) << shift + m.Permission |= uint32(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go index 11ce4020af..9e8dd549b8 100644 --- a/x/subspaces/types/permissions.go +++ b/x/subspaces/types/permissions.go @@ -94,3 +94,27 @@ func CombinePermissions(permissions ...Permission) Permission { } return result } + +// -------------------------------------------------------------------------------------------------------------------- + +func NewPermissionDetailUser(user string, permission Permission) *PermissionDetail { + return &PermissionDetail{ + Sum: &PermissionDetail_User_{ + User: &PermissionDetail_User{ + User: user, + Permission: permission, + }, + }, + } +} + +func NewPermissionDetailGroup(groupID uint32, permission Permission) *PermissionDetail { + return &PermissionDetail{ + Sum: &PermissionDetail_Group_{ + Group: &PermissionDetail_Group{ + GroupID: groupID, + Permission: permission, + }, + }, + } +} diff --git a/x/subspaces/types/query.pb.go b/x/subspaces/types/query.pb.go index 898dff1c23..ba6cbe28aa 100644 --- a/x/subspaces/types/query.pb.go +++ b/x/subspaces/types/query.pb.go @@ -581,7 +581,8 @@ var xxx_messageInfo_QueryUserPermissionsRequest proto.InternalMessageInfo // QueryUserPermissionsRequest is the response type for the // Query/UserPermissions method type QueryUserPermissionsResponse struct { - Permissions uint32 `protobuf:"varint,1,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` + Permissions uint32 `protobuf:"varint,1,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` + Details []*PermissionDetail `protobuf:"bytes,2,rep,name=details,proto3" json:"details,omitempty" yaml:"details"` } func (m *QueryUserPermissionsResponse) Reset() { *m = QueryUserPermissionsResponse{} } @@ -624,6 +625,13 @@ func (m *QueryUserPermissionsResponse) GetPermissions() uint32 { return 0 } +func (m *QueryUserPermissionsResponse) GetDetails() []*PermissionDetail { + if m != nil { + return m.Details + } + return nil +} + func init() { proto.RegisterType((*QuerySubspacesRequest)(nil), "desmos.subspaces.v1.QuerySubspacesRequest") proto.RegisterType((*QuerySubspacesResponse)(nil), "desmos.subspaces.v1.QuerySubspacesResponse") @@ -642,58 +650,60 @@ func init() { func init() { proto.RegisterFile("desmos/subspaces/v1/query.proto", fileDescriptor_883a12b013a133fc) } var fileDescriptor_883a12b013a133fc = []byte{ - // 810 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x96, 0x4f, 0x4f, 0x13, 0x4f, - 0x18, 0xc7, 0x3b, 0xfc, 0x6d, 0xa7, 0x21, 0xfc, 0x32, 0xf0, 0x43, 0x52, 0x61, 0xdb, 0xac, 0x09, - 0x22, 0xe0, 0x8e, 0x2d, 0x1a, 0x0d, 0x1a, 0x91, 0x1e, 0x40, 0x12, 0x35, 0xb8, 0x6a, 0xa2, 0x5e, - 0xc8, 0x96, 0x4e, 0xd6, 0x26, 0x6d, 0x67, 0xe9, 0xb4, 0x8d, 0x84, 0x90, 0x18, 0x12, 0x13, 0x0f, - 0x1e, 0x4c, 0x34, 0x31, 0xde, 0x38, 0x70, 0xf4, 0x3d, 0x78, 0xc5, 0x93, 0x24, 0x5e, 0x3c, 0x35, - 0x06, 0x3c, 0x78, 0xe6, 0x15, 0x98, 0x9d, 0x9d, 0xd9, 0x6e, 0x97, 0x5a, 0xb6, 0x94, 0x78, 0x6b, - 0x77, 0x9e, 0xef, 0xf3, 0x7c, 0xbe, 0xcf, 0x33, 0x7d, 0xb6, 0x30, 0x9e, 0x25, 0xac, 0x40, 0x19, - 0x66, 0x95, 0x0c, 0xb3, 0x8c, 0x35, 0xc2, 0x70, 0x35, 0x89, 0xd7, 0x2b, 0xa4, 0xb4, 0xa1, 0x59, - 0x25, 0x5a, 0xa6, 0x68, 0xc8, 0x09, 0xd0, 0xdc, 0x00, 0xad, 0x9a, 0x8c, 0x0d, 0x9b, 0xd4, 0xa4, - 0xfc, 0x1c, 0xdb, 0x9f, 0x9c, 0xd0, 0xd8, 0x98, 0x49, 0xa9, 0x99, 0x27, 0xd8, 0xb0, 0x72, 0xd8, - 0x28, 0x16, 0x69, 0xd9, 0x28, 0xe7, 0x68, 0x91, 0x89, 0xd3, 0x44, 0xb3, 0x4a, 0x05, 0x9a, 0x25, - 0x79, 0x19, 0x31, 0xb5, 0x46, 0x79, 0x44, 0xc6, 0x60, 0xc4, 0x61, 0xc0, 0xd5, 0x64, 0x86, 0x94, - 0x8d, 0x24, 0xb6, 0x0c, 0x33, 0x57, 0xe4, 0xe9, 0x9c, 0x58, 0x75, 0x15, 0xfe, 0xff, 0xd0, 0x8e, - 0x78, 0x24, 0xb3, 0xe9, 0x64, 0xbd, 0x42, 0x58, 0x19, 0x2d, 0x42, 0x58, 0x0f, 0x1e, 0x05, 0x09, - 0x30, 0x19, 0x4d, 0x4d, 0x68, 0x4e, 0x66, 0xcd, 0xce, 0xac, 0x39, 0xee, 0x44, 0x66, 0x6d, 0xc5, - 0x30, 0x89, 0xd0, 0xea, 0x1e, 0xa5, 0xba, 0x0b, 0xe0, 0x88, 0xbf, 0x02, 0xb3, 0x68, 0x91, 0x11, - 0xb4, 0x00, 0x23, 0xae, 0x89, 0x51, 0x90, 0xe8, 0x9e, 0x8c, 0xa6, 0xc6, 0xb5, 0x26, 0x6d, 0xd2, - 0xa4, 0x34, 0xdd, 0xb3, 0x57, 0x8b, 0x87, 0xf4, 0xba, 0x0a, 0x2d, 0x35, 0x50, 0x76, 0x71, 0xca, - 0x8b, 0x27, 0x52, 0x3a, 0xf5, 0x1b, 0x30, 0x9f, 0xc1, 0xe1, 0x06, 0x4a, 0xd9, 0x86, 0xeb, 0x30, - 0x2a, 0xab, 0xad, 0xe6, 0xb2, 0xbc, 0x0f, 0x3d, 0xe9, 0x91, 0xa3, 0x5a, 0x1c, 0x6d, 0x18, 0x85, - 0xfc, 0x9c, 0xea, 0x39, 0x54, 0x75, 0x28, 0xbf, 0x2d, 0x67, 0xe7, 0xc2, 0x6f, 0x76, 0xe2, 0xa1, - 0xdf, 0x3b, 0xf1, 0x90, 0xfa, 0xd4, 0xd7, 0x62, 0xd7, 0xff, 0x3c, 0x0c, 0x4b, 0x81, 0x68, 0x70, - 0x20, 0xfb, 0xae, 0x48, 0xfd, 0x24, 0x7b, 0xfb, 0x84, 0x91, 0xd2, 0x52, 0x89, 0x56, 0x2c, 0xd6, - 0x29, 0xb7, 0x6f, 0xee, 0x5d, 0xa7, 0x9e, 0xfb, 0x0e, 0x80, 0xe7, 0x8e, 0xb1, 0x09, 0xe3, 0xb7, - 0x60, 0x9f, 0xc9, 0x9f, 0x88, 0xa9, 0x2b, 0x4d, 0x6d, 0xbb, 0x42, 0xe1, 0x5b, 0x68, 0xce, 0x6e, - 0xe6, 0xaf, 0x80, 0x98, 0x8c, 0x5b, 0xa9, 0xe3, 0xee, 0x69, 0x30, 0xcc, 0x29, 0x6d, 0x95, 0x4d, - 0x36, 0x90, 0x1e, 0x3a, 0xaa, 0xc5, 0x07, 0x1d, 0x95, 0x3c, 0x51, 0xf5, 0x7e, 0xfe, 0x71, 0x39, - 0xab, 0x3e, 0xf6, 0x0f, 0xd0, 0xed, 0xd1, 0x1c, 0xec, 0xe5, 0x41, 0xe2, 0x66, 0x04, 0x6b, 0x91, - 0x23, 0x51, 0xbf, 0x01, 0x38, 0xd6, 0x98, 0xf6, 0x3e, 0x29, 0x64, 0x48, 0x89, 0xfd, 0x6b, 0x7f, - 0xbe, 0xdb, 0xd4, 0x7d, 0xea, 0xdb, 0xb4, 0x0d, 0xe0, 0xf8, 0x5f, 0x1c, 0x89, 0x7e, 0x8d, 0xc2, - 0xfe, 0x82, 0xf3, 0x88, 0x5f, 0xaa, 0x88, 0x2e, 0xbf, 0x9e, 0xdd, 0x7d, 0x79, 0x0d, 0xe0, 0x79, - 0x17, 0x62, 0x85, 0x94, 0x0a, 0x39, 0xc6, 0xec, 0xc5, 0xdc, 0x71, 0x57, 0x2f, 0xc0, 0x9e, 0x0a, - 0x23, 0x25, 0xce, 0x16, 0x49, 0x0f, 0x1e, 0xd5, 0xe2, 0x51, 0x47, 0x61, 0x3f, 0x55, 0x75, 0x7e, - 0xd8, 0xb0, 0x50, 0xc6, 0x9a, 0x63, 0x88, 0x56, 0xdc, 0x80, 0x51, 0xab, 0xfe, 0x98, 0x73, 0x0c, - 0x78, 0x39, 0x3c, 0x87, 0xaa, 0xee, 0x0d, 0x4d, 0x7d, 0x08, 0xc3, 0x5e, 0x9e, 0x1a, 0xbd, 0x05, - 0x30, 0xe2, 0x6e, 0x6c, 0x34, 0xd5, 0xf4, 0xf6, 0x35, 0x7d, 0x71, 0xc4, 0xa6, 0x03, 0xc5, 0x3a, - 0xa8, 0xea, 0xc4, 0xf6, 0xf7, 0x5f, 0xef, 0xbb, 0x12, 0x48, 0xc1, 0xcd, 0xde, 0x6a, 0xf5, 0x3d, - 0xff, 0x11, 0xc0, 0xb0, 0x54, 0xa3, 0x4b, 0x27, 0x57, 0x90, 0x30, 0x53, 0x41, 0x42, 0x05, 0xcb, - 0x55, 0xce, 0xa2, 0xa1, 0x99, 0xd6, 0x2c, 0x78, 0xd3, 0x33, 0xc7, 0x2d, 0xb4, 0x0b, 0x20, 0xac, - 0xaf, 0x38, 0xd4, 0xc2, 0xfd, 0xb1, 0x25, 0x1d, 0x9b, 0x09, 0x16, 0x2c, 0xf8, 0x6e, 0x72, 0xbe, - 0x6b, 0x68, 0xb6, 0x1d, 0x3e, 0x2c, 0x96, 0xe6, 0x67, 0x00, 0x23, 0x6e, 0xce, 0x56, 0xf3, 0xf4, - 0xef, 0xc2, 0xd8, 0x74, 0xa0, 0x58, 0xc1, 0xb8, 0xc8, 0x19, 0xef, 0xa0, 0xdb, 0xa7, 0x60, 0xc4, - 0x9b, 0x72, 0x81, 0x6c, 0xa1, 0xaf, 0x00, 0xfe, 0xe7, 0xff, 0xa9, 0xa3, 0x64, 0x00, 0x92, 0xc6, - 0x45, 0x17, 0x4b, 0xb5, 0x23, 0x11, 0x1e, 0x1e, 0x70, 0x0f, 0x77, 0xd1, 0x62, 0x67, 0x1e, 0xb0, - 0xdc, 0x3f, 0x5f, 0x00, 0x1c, 0xf4, 0xfd, 0x54, 0xd1, 0x95, 0xd6, 0x5c, 0xc7, 0x97, 0x4b, 0x2c, - 0xd9, 0x86, 0x42, 0x18, 0x59, 0xe2, 0x46, 0x16, 0xd0, 0x7c, 0x5b, 0x46, 0x3c, 0xfb, 0x00, 0x6f, - 0xda, 0x9b, 0x67, 0x2b, 0x7d, 0x6f, 0xef, 0x40, 0x01, 0xfb, 0x07, 0x0a, 0xf8, 0x79, 0xa0, 0x80, - 0x77, 0x87, 0x4a, 0x68, 0xff, 0x50, 0x09, 0xfd, 0x38, 0x54, 0x42, 0xcf, 0x53, 0x66, 0xae, 0xfc, - 0xa2, 0x92, 0xd1, 0xd6, 0x68, 0x41, 0x14, 0xb9, 0x9c, 0x37, 0x32, 0x4c, 0x16, 0xac, 0xa6, 0xf0, - 0x4b, 0x4f, 0xa1, 0xf2, 0x86, 0x45, 0x58, 0xa6, 0x8f, 0xff, 0xf3, 0x9c, 0xfd, 0x13, 0x00, 0x00, - 0xff, 0xff, 0xf8, 0xef, 0x64, 0xbc, 0x33, 0x0b, 0x00, 0x00, + // 845 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x6b, 0x13, 0x41, + 0x14, 0xce, 0xa4, 0xbf, 0x92, 0x09, 0xb5, 0x32, 0xad, 0x35, 0xc4, 0x76, 0x37, 0xac, 0x58, 0x6b, + 0x5b, 0x77, 0x4d, 0xaa, 0x28, 0x55, 0xac, 0x0d, 0xd2, 0x5a, 0x50, 0xa9, 0x5b, 0x05, 0xf5, 0x52, + 0x36, 0xcd, 0xb0, 0x06, 0x92, 0xec, 0x36, 0xb3, 0x09, 0x96, 0x52, 0x90, 0x82, 0xe0, 0xc1, 0x83, + 0xa0, 0x20, 0xde, 0x7a, 0xe8, 0x51, 0xff, 0x06, 0xaf, 0xf5, 0x64, 0xc1, 0x8b, 0xa7, 0x20, 0xad, + 0x07, 0xcf, 0xf9, 0x0b, 0x64, 0x67, 0x67, 0x36, 0x9b, 0x6d, 0x4c, 0x93, 0xa6, 0x78, 0x4b, 0x66, + 0xbe, 0xef, 0xbd, 0xef, 0x7b, 0xef, 0xe5, 0x4d, 0xa0, 0x98, 0xc1, 0x24, 0x6f, 0x10, 0x85, 0x94, + 0xd2, 0xc4, 0xd4, 0x56, 0x31, 0x51, 0xca, 0x09, 0x65, 0xad, 0x84, 0x8b, 0xeb, 0xb2, 0x59, 0x34, + 0x2c, 0x03, 0x0d, 0x3a, 0x00, 0xd9, 0x05, 0xc8, 0xe5, 0x44, 0x6c, 0x48, 0x37, 0x74, 0x83, 0xde, + 0x2b, 0xf6, 0x27, 0x07, 0x1a, 0x1b, 0xd1, 0x0d, 0x43, 0xcf, 0x61, 0x45, 0x33, 0xb3, 0x8a, 0x56, + 0x28, 0x18, 0x96, 0x66, 0x65, 0x8d, 0x02, 0x61, 0xb7, 0xf1, 0x46, 0x99, 0xf2, 0x46, 0x06, 0xe7, + 0x38, 0x62, 0x62, 0xd5, 0xa0, 0x88, 0xb4, 0x46, 0xb0, 0xa3, 0x41, 0x29, 0x27, 0xd2, 0xd8, 0xd2, + 0x12, 0x8a, 0xa9, 0xe9, 0xd9, 0x02, 0x0d, 0xe7, 0x60, 0xa5, 0x15, 0x78, 0xe6, 0x91, 0x8d, 0x58, + 0xe6, 0xd1, 0x54, 0xbc, 0x56, 0xc2, 0xc4, 0x42, 0xf3, 0x10, 0xd6, 0xc0, 0x51, 0x10, 0x07, 0xe3, + 0x91, 0xe4, 0x98, 0xec, 0x44, 0x96, 0xed, 0xc8, 0xb2, 0xe3, 0x8e, 0x45, 0x96, 0x97, 0x34, 0x1d, + 0x33, 0xae, 0xea, 0x61, 0x4a, 0x3b, 0x00, 0x0e, 0xfb, 0x33, 0x10, 0xd3, 0x28, 0x10, 0x8c, 0xe6, + 0x60, 0xd8, 0x35, 0x11, 0x05, 0xf1, 0xae, 0xf1, 0x48, 0x72, 0x54, 0x6e, 0x50, 0x26, 0x99, 0x53, + 0x53, 0xdd, 0xbb, 0x15, 0x31, 0xa0, 0xd6, 0x58, 0x68, 0xa1, 0x4e, 0x65, 0x90, 0xaa, 0xbc, 0x78, + 0xa4, 0x4a, 0x27, 0x7f, 0x9d, 0xcc, 0x67, 0x70, 0xa8, 0x4e, 0x25, 0x2f, 0xc3, 0x75, 0x18, 0xe1, + 0xd9, 0x56, 0xb2, 0x19, 0x5a, 0x87, 0xee, 0xd4, 0x70, 0xb5, 0x22, 0xa2, 0x75, 0x2d, 0x9f, 0x9b, + 0x91, 0x3c, 0x97, 0x92, 0x0a, 0xf9, 0xb7, 0xc5, 0xcc, 0x4c, 0xe8, 0xcd, 0xb6, 0x18, 0xf8, 0xb3, + 0x2d, 0x06, 0xa4, 0xa7, 0xbe, 0x12, 0xbb, 0xfe, 0x67, 0x61, 0x88, 0x13, 0x58, 0x81, 0x5b, 0xb2, + 0xef, 0x92, 0xa4, 0x4f, 0xbc, 0xb6, 0x4f, 0x08, 0x2e, 0x2e, 0x14, 0x8d, 0x92, 0x49, 0x3a, 0xd5, + 0xed, 0xeb, 0x7b, 0xf0, 0xd8, 0x7d, 0xdf, 0x06, 0xf0, 0xec, 0x21, 0x6d, 0xcc, 0xf8, 0x2d, 0xd8, + 0xab, 0xd3, 0x13, 0xd6, 0x75, 0xa1, 0xa1, 0x6d, 0x97, 0xc8, 0x7c, 0x33, 0xce, 0xc9, 0xf5, 0xfc, + 0x15, 0x60, 0x9d, 0x71, 0x33, 0x75, 0x5c, 0x3d, 0x19, 0x86, 0xa8, 0x4a, 0x9b, 0x65, 0x2b, 0xeb, + 0x4f, 0x0d, 0x56, 0x2b, 0xe2, 0x80, 0xc3, 0xe2, 0x37, 0x92, 0xda, 0x47, 0x3f, 0x2e, 0x66, 0xa4, + 0xc7, 0xfe, 0x06, 0xba, 0x35, 0x9a, 0x81, 0x3d, 0x14, 0xc4, 0x26, 0xa3, 0xb5, 0x12, 0x39, 0x14, + 0xe9, 0x3b, 0x80, 0x23, 0xf5, 0x61, 0x1f, 0xe0, 0x7c, 0x1a, 0x17, 0xc9, 0xff, 0xf6, 0xe7, 0x9b, + 0xa6, 0xae, 0x63, 0x4f, 0xd3, 0x16, 0x80, 0xa3, 0xff, 0x70, 0xc4, 0xea, 0x15, 0x85, 0x7d, 0x79, + 0xe7, 0x88, 0x0e, 0x55, 0x58, 0xe5, 0x5f, 0x4f, 0x6e, 0x5e, 0x5e, 0x03, 0x78, 0xce, 0x15, 0xb1, + 0x84, 0x8b, 0xf9, 0x2c, 0x21, 0xf6, 0x62, 0xee, 0xb8, 0xaa, 0xe7, 0x61, 0x77, 0x89, 0xe0, 0x22, + 0xd5, 0x16, 0x4e, 0x0d, 0x54, 0x2b, 0x62, 0xc4, 0x61, 0xd8, 0xa7, 0x92, 0x4a, 0x2f, 0x3d, 0x0b, + 0xe5, 0x8b, 0xb7, 0xbd, 0x75, 0x3a, 0x58, 0x2d, 0x6e, 0xc0, 0x88, 0x59, 0x3b, 0xa6, 0x42, 0xfa, + 0xbd, 0x42, 0x3c, 0x97, 0x92, 0xea, 0x85, 0xa2, 0x65, 0xd8, 0x97, 0xc1, 0x96, 0x96, 0xcd, 0x91, + 0x68, 0x90, 0xfe, 0x34, 0x2f, 0x34, 0x9c, 0xbb, 0x5a, 0xd2, 0xbb, 0x14, 0x9d, 0x42, 0xd5, 0x8a, + 0x78, 0xca, 0x09, 0xce, 0xf8, 0x92, 0xca, 0x23, 0x25, 0x3f, 0x84, 0x60, 0x0f, 0xd5, 0x8b, 0xde, + 0x02, 0x18, 0x76, 0xdf, 0x01, 0x34, 0xd1, 0x30, 0x76, 0xc3, 0xe7, 0x28, 0x36, 0xd9, 0x12, 0xd6, + 0xf1, 0x2f, 0x8d, 0x6d, 0xfd, 0xf8, 0xfd, 0x3e, 0x18, 0x47, 0x82, 0xd2, 0xe8, 0xad, 0xac, 0xbd, + 0x1e, 0x1f, 0x01, 0x0c, 0x71, 0x36, 0xba, 0x74, 0x74, 0x06, 0x2e, 0x66, 0xa2, 0x15, 0x28, 0xd3, + 0x72, 0x95, 0x6a, 0x91, 0xd1, 0x54, 0x73, 0x2d, 0xca, 0x86, 0x67, 0x3a, 0x36, 0xd1, 0x0e, 0x80, + 0xb0, 0xb6, 0x38, 0x51, 0x13, 0xf7, 0x87, 0x56, 0x7f, 0x6c, 0xaa, 0x35, 0x30, 0xd3, 0x77, 0x93, + 0xea, 0xbb, 0x86, 0xa6, 0xdb, 0xd1, 0xa7, 0xb0, 0x55, 0xfc, 0x19, 0xc0, 0xb0, 0x1b, 0xb3, 0x59, + 0x3f, 0xfd, 0x1b, 0x36, 0x36, 0xd9, 0x12, 0x96, 0x69, 0x9c, 0xa7, 0x1a, 0xef, 0xa0, 0xdb, 0xc7, + 0xd0, 0xa8, 0x6c, 0xf0, 0xb5, 0xb4, 0x89, 0xbe, 0x01, 0x78, 0xda, 0xbf, 0x40, 0x50, 0xa2, 0x05, + 0x25, 0xf5, 0xeb, 0x33, 0x96, 0x6c, 0x87, 0xc2, 0x3c, 0x3c, 0xa4, 0x1e, 0xee, 0xa1, 0xf9, 0xce, + 0x3c, 0x28, 0x7c, 0xab, 0x7d, 0x05, 0x70, 0xc0, 0xf7, 0xfb, 0x47, 0x57, 0x9a, 0xeb, 0x3a, 0xbc, + 0xb2, 0x62, 0x89, 0x36, 0x18, 0xcc, 0xc8, 0x02, 0x35, 0x32, 0x87, 0x66, 0xdb, 0x32, 0xe2, 0x59, + 0x32, 0xca, 0x86, 0xbd, 0xcf, 0x36, 0x53, 0xf7, 0x77, 0xf7, 0x05, 0xb0, 0xb7, 0x2f, 0x80, 0x5f, + 0xfb, 0x02, 0x78, 0x77, 0x20, 0x04, 0xf6, 0x0e, 0x84, 0xc0, 0xcf, 0x03, 0x21, 0xf0, 0x3c, 0xa9, + 0x67, 0xad, 0x17, 0xa5, 0xb4, 0xbc, 0x6a, 0xe4, 0x59, 0x92, 0xcb, 0x39, 0x2d, 0x4d, 0x78, 0xc2, + 0x72, 0x52, 0x79, 0xe9, 0x49, 0x64, 0xad, 0x9b, 0x98, 0xa4, 0x7b, 0xe9, 0xff, 0xd9, 0xe9, 0xbf, + 0x01, 0x00, 0x00, 0xff, 0xff, 0xc2, 0x51, 0xa4, 0xf8, 0x89, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1416,6 +1426,20 @@ func (m *QueryUserPermissionsResponse) MarshalToSizedBuffer(dAtA []byte) (int, e _ = i var l int _ = l + if len(m.Details) > 0 { + for iNdEx := len(m.Details) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Details[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } if m.Permissions != 0 { i = encodeVarintQuery(dAtA, i, uint64(m.Permissions)) i-- @@ -1614,6 +1638,12 @@ func (m *QueryUserPermissionsResponse) Size() (n int) { if m.Permissions != 0 { n += 1 + sovQuery(uint64(m.Permissions)) } + if len(m.Details) > 0 { + for _, e := range m.Details { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } return n } @@ -2768,6 +2798,40 @@ func (m *QueryUserPermissionsResponse) Unmarshal(dAtA []byte) error { break } } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Details", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Details = append(m.Details, &PermissionDetail{}) + if err := m.Details[len(m.Details)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipQuery(dAtA[iNdEx:]) From 387ce971a8dc4f60373d05d357b7934a88416c8d Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 7 Feb 2022 09:13:06 +0100 Subject: [PATCH 40/47] moved the permission details definitions --- x/subspaces/types/models.go | 26 ++++++++++++++++++++++++++ x/subspaces/types/permissions.go | 24 ------------------------ 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/x/subspaces/types/models.go b/x/subspaces/types/models.go index f2aac5ae2a..a7139ff8ef 100644 --- a/x/subspaces/types/models.go +++ b/x/subspaces/types/models.go @@ -201,3 +201,29 @@ func (group UserGroup) Update(update *GroupUpdate) UserGroup { group.Permissions, ) } + +// -------------------------------------------------------------------------------------------------------------------- + +// NewPermissionDetailUser returns a new PermissionDetail for the user with the given address and permission value +func NewPermissionDetailUser(user string, permission Permission) *PermissionDetail { + return &PermissionDetail{ + Sum: &PermissionDetail_User_{ + User: &PermissionDetail_User{ + User: user, + Permission: permission, + }, + }, + } +} + +// NewPermissionDetailGroup returns a new PermissionDetail for the user with the given id and permission value +func NewPermissionDetailGroup(groupID uint32, permission Permission) *PermissionDetail { + return &PermissionDetail{ + Sum: &PermissionDetail_Group_{ + Group: &PermissionDetail_Group{ + GroupID: groupID, + Permission: permission, + }, + }, + } +} diff --git a/x/subspaces/types/permissions.go b/x/subspaces/types/permissions.go index 9e8dd549b8..11ce4020af 100644 --- a/x/subspaces/types/permissions.go +++ b/x/subspaces/types/permissions.go @@ -94,27 +94,3 @@ func CombinePermissions(permissions ...Permission) Permission { } return result } - -// -------------------------------------------------------------------------------------------------------------------- - -func NewPermissionDetailUser(user string, permission Permission) *PermissionDetail { - return &PermissionDetail{ - Sum: &PermissionDetail_User_{ - User: &PermissionDetail_User{ - User: user, - Permission: permission, - }, - }, - } -} - -func NewPermissionDetailGroup(groupID uint32, permission Permission) *PermissionDetail { - return &PermissionDetail{ - Sum: &PermissionDetail_Group_{ - Group: &PermissionDetail_Group{ - GroupID: groupID, - Permission: permission, - }, - }, - } -} From ebdc036793eb9c168a804a25183394bc15698dd4 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 7 Feb 2022 09:14:05 +0100 Subject: [PATCH 41/47] fixed groups query cmd variable name --- x/subspaces/client/cli/query.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/subspaces/client/cli/query.go b/x/subspaces/client/cli/query.go index 8774bc9b2c..17559f89df 100644 --- a/x/subspaces/client/cli/query.go +++ b/x/subspaces/client/cli/query.go @@ -104,7 +104,7 @@ func GetCmdQuerySubspaces() *cobra.Command { // GetGroupsQueryCmd returns a new command to perform queries for user groups func GetGroupsQueryCmd() *cobra.Command { - groupsTxCmd := &cobra.Command{ + groupsQueryCmd := &cobra.Command{ Use: "groups", Short: "Querying commands for subspace groups", DisableFlagParsing: true, @@ -112,12 +112,12 @@ func GetGroupsQueryCmd() *cobra.Command { RunE: client.ValidateCmd, } - groupsTxCmd.AddCommand( + groupsQueryCmd.AddCommand( GetCmdQueryUserGroups(), GetCmdQueryUserGroupMembers(), ) - return groupsTxCmd + return groupsQueryCmd } // GetCmdQueryUserGroups returns the command to query the user groups of a subspace From 7e560b7cbbc57206289a1b508dc9dcb2fcd3f231 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Mon, 7 Feb 2022 10:57:28 +0100 Subject: [PATCH 42/47] Update x/subspaces/keeper/groups.go Co-authored-by: Paul --- x/subspaces/keeper/groups.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/subspaces/keeper/groups.go b/x/subspaces/keeper/groups.go index b70287f658..6104626cf8 100644 --- a/x/subspaces/keeper/groups.go +++ b/x/subspaces/keeper/groups.go @@ -104,7 +104,6 @@ func (k Keeper) IsMemberOfGroup(ctx sdk.Context, subspaceID uint64, groupID uint } // RemoveUserFromGroup removes the specified user from the subspace group having the given id. -// If the group does not exist inside the subspace, it returns an error. func (k Keeper) RemoveUserFromGroup(ctx sdk.Context, subspaceID uint64, groupID uint32, user sdk.AccAddress) { store := ctx.KVStore(k.storeKey) store.Delete(types.GroupMemberStoreKey(subspaceID, groupID, user)) From 59fac8fb0b1682491882b3aec01ca2d2d1c12bc9 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 10 Feb 2022 09:23:36 +0100 Subject: [PATCH 43/47] fixed PR suggestions --- proto/desmos/subspaces/v1/genesis.proto | 1 - proto/desmos/subspaces/v1/query.proto | 6 +- x/profiles/simulation/genesis.go | 2 +- x/subspaces/keeper/grpc_query.go | 2 +- x/subspaces/keeper/grpc_query_test.go | 2 +- x/subspaces/types/models.go | 8 +- x/subspaces/types/query.pb.go | 117 ++++++++++++------------ 7 files changed, 70 insertions(+), 68 deletions(-) diff --git a/proto/desmos/subspaces/v1/genesis.proto b/proto/desmos/subspaces/v1/genesis.proto index 8e5481946f..622ab901dc 100644 --- a/proto/desmos/subspaces/v1/genesis.proto +++ b/proto/desmos/subspaces/v1/genesis.proto @@ -51,6 +51,5 @@ message UserGroupMembersEntry { uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID" ]; uint32 group_id = 2 [ (gogoproto.customname) = "GroupID" ]; - ; repeated string members = 3; } \ No newline at end of file diff --git a/proto/desmos/subspaces/v1/query.proto b/proto/desmos/subspaces/v1/query.proto index 5badeb27c6..edf99643d3 100644 --- a/proto/desmos/subspaces/v1/query.proto +++ b/proto/desmos/subspaces/v1/query.proto @@ -148,6 +148,8 @@ message QueryUserPermissionsRequest { // Query/UserPermissions method message QueryUserPermissionsResponse { uint32 permissions = 1 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; - repeated PermissionDetail details = 2 - [ (gogoproto.moretags) = "yaml:\"details\"" ]; + repeated PermissionDetail details = 2 [ + (gogoproto.nullable) = false, + (gogoproto.moretags) = "yaml:\"details\"" + ]; } \ No newline at end of file diff --git a/x/profiles/simulation/genesis.go b/x/profiles/simulation/genesis.go index 164262d5ef..0301aee49f 100644 --- a/x/profiles/simulation/genesis.go +++ b/x/profiles/simulation/genesis.go @@ -40,7 +40,7 @@ func RandomizedGenState(simsState *module.SimulationState) { } simsState.GenState[authtypes.ModuleName] = bz - // Create and set profiles state + // Create and set subspaces state var subspacesState subspacestypes.GenesisState err = simsState.Cdc.UnmarshalJSON(simsState.GenState[subspacestypes.ModuleName], &subspacesState) if err != nil { diff --git a/x/subspaces/keeper/grpc_query.go b/x/subspaces/keeper/grpc_query.go index da108f1afe..dc3397efd0 100644 --- a/x/subspaces/keeper/grpc_query.go +++ b/x/subspaces/keeper/grpc_query.go @@ -155,7 +155,7 @@ func (k Keeper) UserPermissions(ctx context.Context, request *types.QueryUserPer permissionResult := types.CombinePermissions(userPermission, groupPermissions) // Get the details of all the permissions - var details []*types.PermissionDetail + var details []types.PermissionDetail if userPermission != types.PermissionNothing { details = append(details, types.NewPermissionDetailUser(request.User, userPermission)) } diff --git a/x/subspaces/keeper/grpc_query_test.go b/x/subspaces/keeper/grpc_query_test.go index 63c58eca87..c75a35bafb 100644 --- a/x/subspaces/keeper/grpc_query_test.go +++ b/x/subspaces/keeper/grpc_query_test.go @@ -480,7 +480,7 @@ func (suite *KeeperTestsuite) TestQueryServer_UserPermissions() { shouldErr: false, expResponse: types.QueryUserPermissionsResponse{ Permissions: types.PermissionWrite | types.PermissionChangeInfo | types.PermissionSetPermissions, - Details: []*types.PermissionDetail{ + Details: []types.PermissionDetail{ types.NewPermissionDetailUser("cosmos1nv9kkuads7f627q2zf4k9kwdudx709rjck3s7e", types.PermissionWrite), types.NewPermissionDetailGroup(1, types.PermissionChangeInfo), types.NewPermissionDetailGroup(2, types.PermissionSetPermissions), diff --git a/x/subspaces/types/models.go b/x/subspaces/types/models.go index a7139ff8ef..cf5968a40c 100644 --- a/x/subspaces/types/models.go +++ b/x/subspaces/types/models.go @@ -205,8 +205,8 @@ func (group UserGroup) Update(update *GroupUpdate) UserGroup { // -------------------------------------------------------------------------------------------------------------------- // NewPermissionDetailUser returns a new PermissionDetail for the user with the given address and permission value -func NewPermissionDetailUser(user string, permission Permission) *PermissionDetail { - return &PermissionDetail{ +func NewPermissionDetailUser(user string, permission Permission) PermissionDetail { + return PermissionDetail{ Sum: &PermissionDetail_User_{ User: &PermissionDetail_User{ User: user, @@ -217,8 +217,8 @@ func NewPermissionDetailUser(user string, permission Permission) *PermissionDeta } // NewPermissionDetailGroup returns a new PermissionDetail for the user with the given id and permission value -func NewPermissionDetailGroup(groupID uint32, permission Permission) *PermissionDetail { - return &PermissionDetail{ +func NewPermissionDetailGroup(groupID uint32, permission Permission) PermissionDetail { + return PermissionDetail{ Sum: &PermissionDetail_Group_{ Group: &PermissionDetail_Group{ GroupID: groupID, diff --git a/x/subspaces/types/query.pb.go b/x/subspaces/types/query.pb.go index ba6cbe28aa..636bb79103 100644 --- a/x/subspaces/types/query.pb.go +++ b/x/subspaces/types/query.pb.go @@ -581,8 +581,8 @@ var xxx_messageInfo_QueryUserPermissionsRequest proto.InternalMessageInfo // QueryUserPermissionsRequest is the response type for the // Query/UserPermissions method type QueryUserPermissionsResponse struct { - Permissions uint32 `protobuf:"varint,1,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` - Details []*PermissionDetail `protobuf:"bytes,2,rep,name=details,proto3" json:"details,omitempty" yaml:"details"` + Permissions uint32 `protobuf:"varint,1,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` + Details []PermissionDetail `protobuf:"bytes,2,rep,name=details,proto3" json:"details" yaml:"details"` } func (m *QueryUserPermissionsResponse) Reset() { *m = QueryUserPermissionsResponse{} } @@ -625,7 +625,7 @@ func (m *QueryUserPermissionsResponse) GetPermissions() uint32 { return 0 } -func (m *QueryUserPermissionsResponse) GetDetails() []*PermissionDetail { +func (m *QueryUserPermissionsResponse) GetDetails() []PermissionDetail { if m != nil { return m.Details } @@ -650,60 +650,61 @@ func init() { func init() { proto.RegisterFile("desmos/subspaces/v1/query.proto", fileDescriptor_883a12b013a133fc) } var fileDescriptor_883a12b013a133fc = []byte{ - // 845 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x6b, 0x13, 0x41, - 0x14, 0xce, 0xa4, 0xbf, 0x92, 0x09, 0xb5, 0x32, 0xad, 0x35, 0xc4, 0x76, 0x37, 0xac, 0x58, 0x6b, - 0x5b, 0x77, 0x4d, 0xaa, 0x28, 0x55, 0xac, 0x0d, 0xd2, 0x5a, 0x50, 0xa9, 0x5b, 0x05, 0xf5, 0x52, - 0x36, 0xcd, 0xb0, 0x06, 0x92, 0xec, 0x36, 0xb3, 0x09, 0x96, 0x52, 0x90, 0x82, 0xe0, 0xc1, 0x83, - 0xa0, 0x20, 0xde, 0x7a, 0xe8, 0x51, 0xff, 0x06, 0xaf, 0xf5, 0x64, 0xc1, 0x8b, 0xa7, 0x20, 0xad, - 0x07, 0xcf, 0xf9, 0x0b, 0x64, 0x67, 0x67, 0x36, 0x9b, 0x6d, 0x4c, 0x93, 0xa6, 0x78, 0x4b, 0x66, - 0xbe, 0xef, 0xbd, 0xef, 0x7b, 0xef, 0xe5, 0x4d, 0xa0, 0x98, 0xc1, 0x24, 0x6f, 0x10, 0x85, 0x94, - 0xd2, 0xc4, 0xd4, 0x56, 0x31, 0x51, 0xca, 0x09, 0x65, 0xad, 0x84, 0x8b, 0xeb, 0xb2, 0x59, 0x34, - 0x2c, 0x03, 0x0d, 0x3a, 0x00, 0xd9, 0x05, 0xc8, 0xe5, 0x44, 0x6c, 0x48, 0x37, 0x74, 0x83, 0xde, - 0x2b, 0xf6, 0x27, 0x07, 0x1a, 0x1b, 0xd1, 0x0d, 0x43, 0xcf, 0x61, 0x45, 0x33, 0xb3, 0x8a, 0x56, - 0x28, 0x18, 0x96, 0x66, 0x65, 0x8d, 0x02, 0x61, 0xb7, 0xf1, 0x46, 0x99, 0xf2, 0x46, 0x06, 0xe7, - 0x38, 0x62, 0x62, 0xd5, 0xa0, 0x88, 0xb4, 0x46, 0xb0, 0xa3, 0x41, 0x29, 0x27, 0xd2, 0xd8, 0xd2, - 0x12, 0x8a, 0xa9, 0xe9, 0xd9, 0x02, 0x0d, 0xe7, 0x60, 0xa5, 0x15, 0x78, 0xe6, 0x91, 0x8d, 0x58, - 0xe6, 0xd1, 0x54, 0xbc, 0x56, 0xc2, 0xc4, 0x42, 0xf3, 0x10, 0xd6, 0xc0, 0x51, 0x10, 0x07, 0xe3, - 0x91, 0xe4, 0x98, 0xec, 0x44, 0x96, 0xed, 0xc8, 0xb2, 0xe3, 0x8e, 0x45, 0x96, 0x97, 0x34, 0x1d, - 0x33, 0xae, 0xea, 0x61, 0x4a, 0x3b, 0x00, 0x0e, 0xfb, 0x33, 0x10, 0xd3, 0x28, 0x10, 0x8c, 0xe6, - 0x60, 0xd8, 0x35, 0x11, 0x05, 0xf1, 0xae, 0xf1, 0x48, 0x72, 0x54, 0x6e, 0x50, 0x26, 0x99, 0x53, - 0x53, 0xdd, 0xbb, 0x15, 0x31, 0xa0, 0xd6, 0x58, 0x68, 0xa1, 0x4e, 0x65, 0x90, 0xaa, 0xbc, 0x78, - 0xa4, 0x4a, 0x27, 0x7f, 0x9d, 0xcc, 0x67, 0x70, 0xa8, 0x4e, 0x25, 0x2f, 0xc3, 0x75, 0x18, 0xe1, - 0xd9, 0x56, 0xb2, 0x19, 0x5a, 0x87, 0xee, 0xd4, 0x70, 0xb5, 0x22, 0xa2, 0x75, 0x2d, 0x9f, 0x9b, - 0x91, 0x3c, 0x97, 0x92, 0x0a, 0xf9, 0xb7, 0xc5, 0xcc, 0x4c, 0xe8, 0xcd, 0xb6, 0x18, 0xf8, 0xb3, - 0x2d, 0x06, 0xa4, 0xa7, 0xbe, 0x12, 0xbb, 0xfe, 0x67, 0x61, 0x88, 0x13, 0x58, 0x81, 0x5b, 0xb2, - 0xef, 0x92, 0xa4, 0x4f, 0xbc, 0xb6, 0x4f, 0x08, 0x2e, 0x2e, 0x14, 0x8d, 0x92, 0x49, 0x3a, 0xd5, - 0xed, 0xeb, 0x7b, 0xf0, 0xd8, 0x7d, 0xdf, 0x06, 0xf0, 0xec, 0x21, 0x6d, 0xcc, 0xf8, 0x2d, 0xd8, - 0xab, 0xd3, 0x13, 0xd6, 0x75, 0xa1, 0xa1, 0x6d, 0x97, 0xc8, 0x7c, 0x33, 0xce, 0xc9, 0xf5, 0xfc, - 0x15, 0x60, 0x9d, 0x71, 0x33, 0x75, 0x5c, 0x3d, 0x19, 0x86, 0xa8, 0x4a, 0x9b, 0x65, 0x2b, 0xeb, - 0x4f, 0x0d, 0x56, 0x2b, 0xe2, 0x80, 0xc3, 0xe2, 0x37, 0x92, 0xda, 0x47, 0x3f, 0x2e, 0x66, 0xa4, - 0xc7, 0xfe, 0x06, 0xba, 0x35, 0x9a, 0x81, 0x3d, 0x14, 0xc4, 0x26, 0xa3, 0xb5, 0x12, 0x39, 0x14, - 0xe9, 0x3b, 0x80, 0x23, 0xf5, 0x61, 0x1f, 0xe0, 0x7c, 0x1a, 0x17, 0xc9, 0xff, 0xf6, 0xe7, 0x9b, - 0xa6, 0xae, 0x63, 0x4f, 0xd3, 0x16, 0x80, 0xa3, 0xff, 0x70, 0xc4, 0xea, 0x15, 0x85, 0x7d, 0x79, - 0xe7, 0x88, 0x0e, 0x55, 0x58, 0xe5, 0x5f, 0x4f, 0x6e, 0x5e, 0x5e, 0x03, 0x78, 0xce, 0x15, 0xb1, - 0x84, 0x8b, 0xf9, 0x2c, 0x21, 0xf6, 0x62, 0xee, 0xb8, 0xaa, 0xe7, 0x61, 0x77, 0x89, 0xe0, 0x22, - 0xd5, 0x16, 0x4e, 0x0d, 0x54, 0x2b, 0x62, 0xc4, 0x61, 0xd8, 0xa7, 0x92, 0x4a, 0x2f, 0x3d, 0x0b, - 0xe5, 0x8b, 0xb7, 0xbd, 0x75, 0x3a, 0x58, 0x2d, 0x6e, 0xc0, 0x88, 0x59, 0x3b, 0xa6, 0x42, 0xfa, - 0xbd, 0x42, 0x3c, 0x97, 0x92, 0xea, 0x85, 0xa2, 0x65, 0xd8, 0x97, 0xc1, 0x96, 0x96, 0xcd, 0x91, - 0x68, 0x90, 0xfe, 0x34, 0x2f, 0x34, 0x9c, 0xbb, 0x5a, 0xd2, 0xbb, 0x14, 0x9d, 0x42, 0xd5, 0x8a, - 0x78, 0xca, 0x09, 0xce, 0xf8, 0x92, 0xca, 0x23, 0x25, 0x3f, 0x84, 0x60, 0x0f, 0xd5, 0x8b, 0xde, - 0x02, 0x18, 0x76, 0xdf, 0x01, 0x34, 0xd1, 0x30, 0x76, 0xc3, 0xe7, 0x28, 0x36, 0xd9, 0x12, 0xd6, - 0xf1, 0x2f, 0x8d, 0x6d, 0xfd, 0xf8, 0xfd, 0x3e, 0x18, 0x47, 0x82, 0xd2, 0xe8, 0xad, 0xac, 0xbd, - 0x1e, 0x1f, 0x01, 0x0c, 0x71, 0x36, 0xba, 0x74, 0x74, 0x06, 0x2e, 0x66, 0xa2, 0x15, 0x28, 0xd3, - 0x72, 0x95, 0x6a, 0x91, 0xd1, 0x54, 0x73, 0x2d, 0xca, 0x86, 0x67, 0x3a, 0x36, 0xd1, 0x0e, 0x80, - 0xb0, 0xb6, 0x38, 0x51, 0x13, 0xf7, 0x87, 0x56, 0x7f, 0x6c, 0xaa, 0x35, 0x30, 0xd3, 0x77, 0x93, - 0xea, 0xbb, 0x86, 0xa6, 0xdb, 0xd1, 0xa7, 0xb0, 0x55, 0xfc, 0x19, 0xc0, 0xb0, 0x1b, 0xb3, 0x59, - 0x3f, 0xfd, 0x1b, 0x36, 0x36, 0xd9, 0x12, 0x96, 0x69, 0x9c, 0xa7, 0x1a, 0xef, 0xa0, 0xdb, 0xc7, - 0xd0, 0xa8, 0x6c, 0xf0, 0xb5, 0xb4, 0x89, 0xbe, 0x01, 0x78, 0xda, 0xbf, 0x40, 0x50, 0xa2, 0x05, - 0x25, 0xf5, 0xeb, 0x33, 0x96, 0x6c, 0x87, 0xc2, 0x3c, 0x3c, 0xa4, 0x1e, 0xee, 0xa1, 0xf9, 0xce, - 0x3c, 0x28, 0x7c, 0xab, 0x7d, 0x05, 0x70, 0xc0, 0xf7, 0xfb, 0x47, 0x57, 0x9a, 0xeb, 0x3a, 0xbc, - 0xb2, 0x62, 0x89, 0x36, 0x18, 0xcc, 0xc8, 0x02, 0x35, 0x32, 0x87, 0x66, 0xdb, 0x32, 0xe2, 0x59, - 0x32, 0xca, 0x86, 0xbd, 0xcf, 0x36, 0x53, 0xf7, 0x77, 0xf7, 0x05, 0xb0, 0xb7, 0x2f, 0x80, 0x5f, - 0xfb, 0x02, 0x78, 0x77, 0x20, 0x04, 0xf6, 0x0e, 0x84, 0xc0, 0xcf, 0x03, 0x21, 0xf0, 0x3c, 0xa9, - 0x67, 0xad, 0x17, 0xa5, 0xb4, 0xbc, 0x6a, 0xe4, 0x59, 0x92, 0xcb, 0x39, 0x2d, 0x4d, 0x78, 0xc2, - 0x72, 0x52, 0x79, 0xe9, 0x49, 0x64, 0xad, 0x9b, 0x98, 0xa4, 0x7b, 0xe9, 0xff, 0xd9, 0xe9, 0xbf, - 0x01, 0x00, 0x00, 0xff, 0xff, 0xc2, 0x51, 0xa4, 0xf8, 0x89, 0x0b, 0x00, 0x00, + // 849 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x56, 0xcf, 0x4f, 0x13, 0x41, + 0x14, 0xee, 0x94, 0x5f, 0xed, 0x34, 0x88, 0x19, 0x10, 0x9b, 0x0a, 0xbb, 0xcd, 0x1a, 0x11, 0x01, + 0x77, 0x6d, 0xd1, 0x68, 0xd0, 0x88, 0x34, 0x06, 0x24, 0x51, 0x83, 0xab, 0xc6, 0x1f, 0x17, 0xb2, + 0xa5, 0x93, 0xb5, 0x49, 0xdb, 0x5d, 0x3a, 0xdb, 0x46, 0x42, 0x48, 0x0c, 0x89, 0x89, 0x07, 0x0f, + 0x26, 0x9a, 0x18, 0x6f, 0x1c, 0x38, 0x7a, 0xf1, 0x2f, 0xf0, 0x8a, 0x27, 0x49, 0xbc, 0x78, 0x6a, + 0x0c, 0x78, 0xf0, 0xdc, 0xbf, 0xc0, 0xec, 0xec, 0xcc, 0x76, 0xbb, 0xd4, 0xd2, 0x52, 0xe2, 0xad, + 0x3b, 0xf3, 0x7d, 0xef, 0x7d, 0xdf, 0x7b, 0x8f, 0x37, 0x40, 0x31, 0x83, 0x49, 0xde, 0x20, 0x0a, + 0x29, 0xa5, 0x89, 0xa9, 0xad, 0x60, 0xa2, 0x94, 0x13, 0xca, 0x6a, 0x09, 0x17, 0xd7, 0x64, 0xb3, + 0x68, 0x58, 0x06, 0x1a, 0x74, 0x00, 0xb2, 0x0b, 0x90, 0xcb, 0x89, 0xd8, 0x90, 0x6e, 0xe8, 0x06, + 0xbd, 0x57, 0xec, 0x5f, 0x0e, 0x34, 0x36, 0xa2, 0x1b, 0x86, 0x9e, 0xc3, 0x8a, 0x66, 0x66, 0x15, + 0xad, 0x50, 0x30, 0x2c, 0xcd, 0xca, 0x1a, 0x05, 0xc2, 0x6e, 0xe3, 0x8d, 0x32, 0xe5, 0x8d, 0x0c, + 0xce, 0x71, 0xc4, 0xc4, 0x8a, 0x41, 0x11, 0x69, 0x8d, 0x60, 0x47, 0x83, 0x52, 0x4e, 0xa4, 0xb1, + 0xa5, 0x25, 0x14, 0x53, 0xd3, 0xb3, 0x05, 0x1a, 0xce, 0xc1, 0x4a, 0xcb, 0xf0, 0xd4, 0x03, 0x1b, + 0xf1, 0x90, 0x47, 0x53, 0xf1, 0x6a, 0x09, 0x13, 0x0b, 0xcd, 0x43, 0x58, 0x03, 0x47, 0x41, 0x1c, + 0x8c, 0x47, 0x92, 0x63, 0xb2, 0x13, 0x59, 0xb6, 0x23, 0xcb, 0x8e, 0x3b, 0x16, 0x59, 0x5e, 0xd2, + 0x74, 0xcc, 0xb8, 0xaa, 0x87, 0x29, 0x6d, 0x03, 0x38, 0xec, 0xcf, 0x40, 0x4c, 0xa3, 0x40, 0x30, + 0x9a, 0x83, 0x61, 0xd7, 0x44, 0x14, 0xc4, 0xbb, 0xc6, 0x23, 0xc9, 0x51, 0xb9, 0x41, 0x99, 0x64, + 0x4e, 0x4d, 0x75, 0xef, 0x54, 0xc4, 0x80, 0x5a, 0x63, 0xa1, 0x85, 0x3a, 0x95, 0x41, 0xaa, 0xf2, + 0xfc, 0xa1, 0x2a, 0x9d, 0xfc, 0x75, 0x32, 0x9f, 0xc1, 0xa1, 0x3a, 0x95, 0xbc, 0x0c, 0x57, 0x61, + 0x84, 0x67, 0x5b, 0xce, 0x66, 0x68, 0x1d, 0xba, 0x53, 0xc3, 0xd5, 0x8a, 0x88, 0xd6, 0xb4, 0x7c, + 0x6e, 0x46, 0xf2, 0x5c, 0x4a, 0x2a, 0xe4, 0x5f, 0x8b, 0x99, 0x99, 0xd0, 0x9b, 0x2d, 0x31, 0xf0, + 0x67, 0x4b, 0x0c, 0x48, 0x4f, 0x7d, 0x25, 0x76, 0xfd, 0xcf, 0xc2, 0x10, 0x27, 0xb0, 0x02, 0xb7, + 0x64, 0xdf, 0x25, 0x49, 0x9f, 0x78, 0x6d, 0x1f, 0x13, 0x5c, 0x5c, 0x28, 0x1a, 0x25, 0x93, 0x74, + 0xaa, 0xdb, 0xd7, 0xf7, 0xe0, 0x91, 0xfb, 0xbe, 0x05, 0xe0, 0xe9, 0x03, 0xda, 0x98, 0xf1, 0x1b, + 0xb0, 0x57, 0xa7, 0x27, 0xac, 0xeb, 0x42, 0x43, 0xdb, 0x2e, 0x91, 0xf9, 0x66, 0x9c, 0xe3, 0xeb, + 0xf9, 0x2b, 0xc0, 0x3a, 0xe3, 0x66, 0xea, 0xb8, 0x7a, 0x32, 0x0c, 0x51, 0x95, 0x36, 0xcb, 0x56, + 0xd6, 0x9f, 0x1a, 0xac, 0x56, 0xc4, 0x01, 0x87, 0xc5, 0x6f, 0x24, 0xb5, 0x8f, 0xfe, 0x5c, 0xcc, + 0x48, 0x8f, 0xfc, 0x0d, 0x74, 0x6b, 0x34, 0x03, 0x7b, 0x28, 0x88, 0x4d, 0x46, 0x6b, 0x25, 0x72, + 0x28, 0xd2, 0x77, 0x00, 0x47, 0xea, 0xc3, 0xde, 0xc3, 0xf9, 0x34, 0x2e, 0x92, 0xff, 0xed, 0xcf, + 0x37, 0x4d, 0x5d, 0x47, 0x9e, 0xa6, 0x4d, 0x00, 0x47, 0xff, 0xe1, 0x88, 0xd5, 0x2b, 0x0a, 0xfb, + 0xf2, 0xce, 0x11, 0x1d, 0xaa, 0xb0, 0xca, 0x3f, 0x8f, 0x6f, 0x5e, 0x5e, 0x03, 0x78, 0xc6, 0x15, + 0xb1, 0x84, 0x8b, 0xf9, 0x2c, 0x21, 0xf6, 0x62, 0xee, 0xb8, 0xaa, 0x67, 0x61, 0x77, 0x89, 0xe0, + 0x22, 0xd5, 0x16, 0x4e, 0x0d, 0x54, 0x2b, 0x62, 0xc4, 0x61, 0xd8, 0xa7, 0x92, 0x4a, 0x2f, 0x3d, + 0x0b, 0xe5, 0x8b, 0xb7, 0xbd, 0x75, 0x3a, 0x58, 0x2d, 0xae, 0xc1, 0x88, 0x59, 0x3b, 0xa6, 0x42, + 0xfa, 0xbd, 0x42, 0x3c, 0x97, 0x92, 0xea, 0x85, 0xa2, 0x27, 0xb0, 0x2f, 0x83, 0x2d, 0x2d, 0x9b, + 0x23, 0xd1, 0x20, 0xfd, 0xd3, 0x3c, 0xd7, 0x70, 0xee, 0x6a, 0x49, 0x6f, 0x53, 0x74, 0x6a, 0xd8, + 0x1e, 0xbf, 0x6a, 0x45, 0x3c, 0xe1, 0x24, 0x60, 0x31, 0x24, 0x95, 0x47, 0x4b, 0x7e, 0x08, 0xc1, + 0x1e, 0xaa, 0x19, 0xbd, 0x05, 0x30, 0xec, 0xbe, 0x05, 0x68, 0xa2, 0x61, 0xfc, 0x86, 0x4f, 0x52, + 0x6c, 0xb2, 0x25, 0xac, 0x53, 0x03, 0x69, 0x6c, 0xf3, 0xc7, 0xef, 0xf7, 0xc1, 0x38, 0x12, 0x94, + 0x46, 0xef, 0x65, 0xed, 0x05, 0xf9, 0x08, 0x60, 0x88, 0xb3, 0xd1, 0x85, 0xc3, 0x33, 0x70, 0x31, + 0x13, 0xad, 0x40, 0x99, 0x96, 0xcb, 0x54, 0x8b, 0x8c, 0xa6, 0x9a, 0x6b, 0x51, 0xd6, 0x3d, 0x13, + 0xb2, 0x81, 0xb6, 0x01, 0x84, 0xb5, 0xe5, 0x89, 0x9a, 0xb8, 0x3f, 0xb0, 0xfe, 0x63, 0x53, 0xad, + 0x81, 0x99, 0xbe, 0xeb, 0x54, 0xdf, 0x15, 0x34, 0xdd, 0x8e, 0x3e, 0x85, 0xad, 0xe3, 0xcf, 0x00, + 0x86, 0xdd, 0x98, 0xcd, 0xfa, 0xe9, 0xdf, 0xb2, 0xb1, 0xc9, 0x96, 0xb0, 0x4c, 0xe3, 0x3c, 0xd5, + 0x78, 0x0b, 0xdd, 0x3c, 0x82, 0x46, 0x65, 0x9d, 0xaf, 0xa6, 0x0d, 0xf4, 0x0d, 0xc0, 0x93, 0xfe, + 0x25, 0x82, 0x12, 0x2d, 0x28, 0xa9, 0x5f, 0xa1, 0xb1, 0x64, 0x3b, 0x14, 0xe6, 0xe1, 0x3e, 0xf5, + 0x70, 0x07, 0xcd, 0x77, 0xe6, 0x41, 0xe1, 0x9b, 0xed, 0x2b, 0x80, 0x03, 0xbe, 0x1d, 0x80, 0x2e, + 0x35, 0xd7, 0x75, 0x70, 0x6d, 0xc5, 0x12, 0x6d, 0x30, 0x98, 0x91, 0x05, 0x6a, 0x64, 0x0e, 0xcd, + 0xb6, 0x65, 0xc4, 0xb3, 0x68, 0x94, 0x75, 0x7b, 0xa7, 0x6d, 0xa4, 0xee, 0xee, 0xec, 0x09, 0x60, + 0x77, 0x4f, 0x00, 0xbf, 0xf6, 0x04, 0xf0, 0x6e, 0x5f, 0x08, 0xec, 0xee, 0x0b, 0x81, 0x9f, 0xfb, + 0x42, 0xe0, 0x79, 0x52, 0xcf, 0x5a, 0x2f, 0x4a, 0x69, 0x79, 0xc5, 0xc8, 0xb3, 0x24, 0x17, 0x73, + 0x5a, 0x9a, 0xf0, 0x84, 0xe5, 0xa4, 0xf2, 0xd2, 0x93, 0xc8, 0x5a, 0x33, 0x31, 0x49, 0xf7, 0xd2, + 0xff, 0x69, 0xa7, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x50, 0x81, 0xfc, 0xb3, 0x8d, 0x0b, 0x00, + 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2827,7 +2828,7 @@ func (m *QueryUserPermissionsResponse) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Details = append(m.Details, &PermissionDetail{}) + m.Details = append(m.Details, PermissionDetail{}) if err := m.Details[len(m.Details)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } From 8628788762cc1310f521cbe86e2948c693b5bf95 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 10 Feb 2022 09:51:32 +0100 Subject: [PATCH 44/47] updated related ADR --- docs/architecture/adr-006-subspace-module.md | 193 ++++++++++++------- 1 file changed, 125 insertions(+), 68 deletions(-) diff --git a/docs/architecture/adr-006-subspace-module.md b/docs/architecture/adr-006-subspace-module.md index 1125482ff5..daa44d6164 100644 --- a/docs/architecture/adr-006-subspace-module.md +++ b/docs/architecture/adr-006-subspace-module.md @@ -5,13 +5,14 @@ - December 15th, 2021: Initial draft; - December 16th, 2021: First review; - January 06th, 2022: Second review; -- January 13th, 2021: Third review; -- January 14th, 2021: Fourth review; -- January 17th, 2021: Fifth review. +- January 13th, 2022: Third review; +- January 14th, 2022: Fourth review; +- January 17th, 2022: Fifth review; +- February 10th, 2022: Sixth review. ## Status -PROPOSED +ACCEPTED ## Abstract This ADR defines the `x/subspaces` module which allows users to create and manage the representation of different social networks inside which contents will be created. @@ -58,67 +59,84 @@ type Subspace struct { } ``` -#### ACL -In order to easily implement an ACL, we will use a simple set of keys made as follows: -``` -ACLPrefix + Subspace ID + -> ACL Value -``` +#### Permissions +Since each subspace is thought to represent an independent application, we SHOULD allow different subspaces owners to set different permissions for each user. -The `ACL Value` will be a simple binary value allowing us to perform bitwise operations to combine the following different permissions: +For this reason, we will implement an ACL (*Access Control List*) system that can be customized for each subspace. Each ACL MUST support setting permissions for both individual users and user groups. + +##### Permission value +To easily implement a composable system, we will use byte-based permissions: each value will be represented by an integer value, and composed permissions can be obtained by using the byte-wide *or* (`|`) operator. Also, this will allow us to easily check whether a user has a specific permission by using the byte-wide *and* (`&`) operator. ```go const ( - // Identifies users that can create content inside the subspace - PermissionWrite = 0b000001 - - // Allows users to moderate contents of other users (e.g. deleting it) - PermissionModerateContent = 0b000010 - - // Allows to add a link for this subspace - PermissionAddLink = 0b000100 - - // Allows to change the information of the subspace - PermissionChangeInfo = 0b001000 - - // Allows to set other users' permissions (except PermissionSetPermissions). - // This includes managing user groups and the associated permissions - PermissionSetPermissions = 0b010000 + // PermissionNothing represents the permission to do nothing + PermissionNothing = Permission(0b000000) + + // PermissionWrite identifies users that can create content inside the subspace + PermissionWrite = Permission(0b000001) + + // PermissionModerateContent allows users to moderate contents of other users (e.g. deleting it) + PermissionModerateContent = Permission(0b000010) + + // PermissionChangeInfo allows to change the information of the subspace + PermissionChangeInfo = Permission(0b000100) + + // PermissionManageGroups allows users to manage user groups and members + PermissionManageGroups = Permission(0b001000) + + // PermissionSetPermissions allows users to set other users' permissions (except PermissionSetPermissions). + // This includes managing user groups and the associated permissions + PermissionSetPermissions = Permission(0b010000) + + // PermissionDeleteSubspace allows users to delete the subspace. + PermissionDeleteSubspace = Permission(0b100000) + + // PermissionEverything allows to do everything. + // This should usually be reserved only to the owner (which has it by default) + PermissionEverything = Permission(0b111111) ) -``` - -> **Note**: -> Only the `Owner` account will be able to grant other users the `PermissionSetPermissions` -Using this kind of permissions will allow us to easily set permissions and check whether a user has a permission or not: -```go -userPermissions := PermissionWrite | PermissionAddLink | PermissionChangeInfo +userPermissions := PermissionWrite | PermissionManageGroups | PermissionChangeInfo canWrite := (userPermissions & PermissionWrite) == PermissionWrite // True canModerateContent := (userPermissions & PermissionModerateContent) == PermissionModerateContent // False ``` -##### Group permissions -In order to simplify the handling of multiple users' permissions, we SHOULD allow subspace admins to set group-wide permissions. -Each group will be represented by its own name, which can be defined by the admins themselves, and each group will have the same importance as others. -We reserve the group name `Others` to identify all the users that are not part of any other group (i.e. those users who are not registered inside a subspace). - -While checking a user permission to do something, the following actions will be performed: -1. get the permissions set for that specific user; -2. get all the permissions for all the groups the user is part of; -3. compute the resulting permission associated to the user using the `OR` operator. +> **Note**: +> Only the `Owner` account will be able to grant other users the `PermissionSetPermissions` -In order to properly store groups and members information, the following store keys will be used: -``` -// Store the belonging of a group to a subspace -SubspaceGroupPrefix + Subspace ID + Group name -> 0x01 +##### User groups +In order to properly implement user groups, we are going to define the following structure: + +```golang +type UserGroup struct { + // SubspaceID represents the ID of the subspace inside which the group exists + SubspaceID uint64 + // Unique id that identifies the group inside the subspace + ID uint32 + // Human-readable name of the user group + Name string + // Optional description of the group + Description string + // Permissions that will be granted to all the users inside this group + Permissions uint32 +} -// Store the belonging of a user to a specific subspace group -UserGroupPrefix + Subspace ID + Group name + User Address -> 0x01 ``` -In both cases, the `0x01` value is used only as a placeholder to make it possible for the key to exist. +The `ID` of each group will be a sequential value starting from `1` for each subspace. + +To store a group and its members, we will use the following key: +``` +GroupPrefix + SubspaceID + GroupID -> Group +``` +This will allow us to easily iterate over all the groups inside a subspace. -These keys will allow us to iterate over all the users that are part of a group as well as all the groups inside a subspace. This will allow clients to easily get all the groups of a subspace and the users that are part of such groups. On the other hand, it will make it harder to get all the groups that a user is part of. The decision to prioritize the first instead of the latter is made to make sure that permission checking is sufficiently fast: since subspace will have a limited amount of groups, it will be quite inexpensive to iterate over all of them and check if a given user is part of each group. +At the same time, to store each member of a group we will use the following store keys: +``` +GroupMemberPrefix + SubspaceID + GroupID + -> 0x01 +``` +In this case, the `0x01` value is just a placeholder that allows the key to exist. This key will allow us to easily iterate over all the members of a subspace, as well as to check whether a user is part of a group or not. ### `Msg` Service We will allow the following operations to be performed. @@ -126,14 +144,17 @@ We will allow the following operations to be performed. **Subspace administration** * Create a subspace * Edit a subspace +* Set a group's permissions +* Delete a subspace **Content management** * Delete contents that do not respect the ToS **Groups management** * Create a new group -* Delete a group +* Edit a group * Set group permissions +* Delete a group **Users management** * Add a user to a group @@ -153,7 +174,14 @@ service Msg { // CreateUserGroup allows to create a new user group rpc CreateUserGroup(MsgCreateUserGroup) returns (MsgCreateUserGroupResponse); - + + // EditUserGroup allows to edit a user group + rpc EditUserGroup(MsgEditUserGroup) returns (MsgEditUserGroupResponse); + + // SetUserGroupPermissions allows to set the permissions for a specific group + rpc SetUserGroupPermissions(MsgSetUserGroupPermissions) + returns (MsgSetUserGroupPermissionsResponse); + // DeleteUserGroup allows to delete an existing user group rpc DeleteUserGroup(MsgDeleteUserGroup) returns (MsgDeleteUserGroupResponse); @@ -164,14 +192,14 @@ service Msg { rpc RemoveUserFromUserGroup(MsgRemoveUserFromUserGroup) returns (MsgRemoveUserFromUserGroupResponse); // SetPermissions allows to set the permissions of a user or user group - rpc SetPermissions(MsgSetPermissions) returns (MsgSetPermissionsResponse); + rpc SetUserPermissions(MsgSetUserPermissions) returns (MsgSetUserPermissionsResponse); } message MsgCreateSubspace { string name = 1; string description = 2; - string owner = 3; - string treasury = 4; + string treasury = 3; + string owner = 4; string creator = 5; } @@ -180,28 +208,57 @@ message MsgCreateSubspaceResponse { } message MsgEditSubspace { - uint64 id = 1; + uint64 subspace_id = 1; string name = 2; string description = 3; - string owner = 4; - string treasury = 5; + string treasury = 4; + string owner = 5; string signer = 6; } message MsgEditSubspaceResponse {} +message MsgDeleteSubspace { + uint64 subspace_id = 1; + string signer = 2; +} + +message MsgDeleteSubspaceResponse {} + message MsgCreateUserGroup { uint64 subspace_id = 1; - string group_name = 2; - bytes default_permissions = 3; + string name = 2; + string description = 3; + bytes default_permissions = 4; + string creator = 5; +} + +message MsgCreateUserGroupResponse { + uint32 group_id = 1; +} + +message MsgEditUserGroup { + uint64 subspace_id = 1; + uint32 group_id = 2; + string name = 3; + string description = 4; + string signer = 5; +} + +message MsgEditUserGroupResponse {} + +message MsgSetUserGroupPermissions { + uint64 subspace_id = 1; + uint32 group_id = 2; + uint32 permissions = 3; string signer = 4; } -message MsgCreateUserGroupResponse {} +message MsgSetUserGroupPermissionsResponse {} message MsgDeleteUserGroup { uint64 subspace_id = 1; - string group_name = 2; + uint32 group_id = 2; string signer = 3; } @@ -209,8 +266,8 @@ message MsgDeleteUserGroupResponse {} message MsgAddUserToUserGroup { uint64 subspace_id = 1; - string user = 2; - string group_name = 3; + uint32 group_id = 2; + string user = 3; string signer = 4; } @@ -218,21 +275,21 @@ message MsgAddUserToUserGroupResponse {} message MsgRemoveUserFromUserGroup { uint64 subspace_id = 1; - string user = 2; - string group_name = 3; + uint32 group_id = 2; + string user = 3; string signer = 4; } message MsgRemoveUserFromUserGroupResponse {} -message MsgSetPermissions { +message MsgSetUserPermissions { uint64 subspace_id = 1; - string target = 2; + string user = 2; bytes permissions = 3; string signer = 4; } -message MsgSetPermissionsResponse {} +message MsgSetUserPermissionsResponse {} ``` ## Consequences From a9ce20aaa9f2b526af69a32bde3ffd10dfa9d276 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 10 Feb 2022 09:51:44 +0100 Subject: [PATCH 45/47] updated models documentation --- proto/desmos/subspaces/v1/models.proto | 3 +++ x/subspaces/types/models.pb.go | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/proto/desmos/subspaces/v1/models.proto b/proto/desmos/subspaces/v1/models.proto index d49624c9b8..2b68fec0ca 100644 --- a/proto/desmos/subspaces/v1/models.proto +++ b/proto/desmos/subspaces/v1/models.proto @@ -44,6 +44,7 @@ message UserGroup { option (gogoproto.equal) = true; option (gogoproto.goproto_stringer) = true; + // ID of the subspace inside which this group exists uint64 subspace_id = 1 [ (gogoproto.customname) = "SubspaceID", (gogoproto.moretags) = "yaml:\"subspace_id\"" @@ -56,8 +57,10 @@ message UserGroup { // Human-readable name of the user group string name = 3 [ (gogoproto.moretags) = "yaml:\"name\"" ]; + // Optional description of this group string description = 4 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + // Permissions that will be granted to all the users part of this group uint32 permissions = 5 [ (gogoproto.moretags) = "yaml:\"permissions\"" ]; } diff --git a/x/subspaces/types/models.pb.go b/x/subspaces/types/models.pb.go index 335ba2f080..b416cb8cee 100644 --- a/x/subspaces/types/models.pb.go +++ b/x/subspaces/types/models.pb.go @@ -130,12 +130,15 @@ func (m *Subspace) GetCreationTime() time.Time { // UserGroup represents a group of users type UserGroup struct { + // ID of the subspace inside which this group exists SubspaceID uint64 `protobuf:"varint,1,opt,name=subspace_id,json=subspaceId,proto3" json:"subspace_id,omitempty" yaml:"subspace_id"` // Unique id that identifies the group ID uint32 `protobuf:"varint,2,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // Human-readable name of the user group - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` + // Optional description of this group Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` + // Permissions that will be granted to all the users part of this group Permissions uint32 `protobuf:"varint,5,opt,name=permissions,proto3" json:"permissions,omitempty" yaml:"permissions"` } From b9e87696389a13cf5c8c4b3c141a28cd540253d3 Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Thu, 10 Feb 2022 10:05:39 +0100 Subject: [PATCH 46/47] updated Go version to 1.17 --- go.mod | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- go.sum | 5 --- 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 7fda1d46fc..1a9374d9b1 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/desmos-labs/desmos/v2 -go 1.15 +go 1.17 require ( github.com/CosmWasm/wasmd v0.21.1-0.20220105132732-3d2affb31f82 @@ -31,6 +31,100 @@ require ( gopkg.in/yaml.v2 v2.4.0 ) +require ( + filippo.io/edwards25519 v1.0.0-beta.2 // indirect + github.com/99designs/keyring v1.1.6 // indirect + github.com/ChainSafe/go-schnorrkel v0.0.0-20200405005733-88cbf1b4c40d // indirect + github.com/CosmWasm/wasmvm v1.0.0-beta5 // indirect + github.com/DataDog/zstd v1.4.5 // indirect + github.com/Workiva/go-datastructures v1.0.53 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/cespare/xxhash v1.1.0 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect + github.com/coinbase/rosetta-sdk-go v0.6.10 // indirect + github.com/confio/ics23/go v0.6.6 // indirect + github.com/cosmos/btcutil v1.0.4 // indirect + github.com/cosmos/iavl v0.17.3 // indirect + github.com/cosmos/ledger-cosmos-go v0.11.1 // indirect + github.com/cosmos/ledger-go v0.9.2 // indirect + github.com/danieljoos/wincred v1.0.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect + github.com/dgraph-io/badger/v2 v2.2007.2 // indirect + github.com/dgraph-io/ristretto v0.0.3 // indirect + github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect + github.com/dustin/go-humanize v1.0.0 // indirect + github.com/dvsekhvalnov/jose2go v0.0.0-20200901110807-248326c1351b // indirect + github.com/felixge/httpsnoop v1.0.1 // indirect + github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/go-kit/kit v0.12.0 // indirect + github.com/go-kit/log v0.2.0 // indirect + github.com/go-logfmt/logfmt v0.5.1 // indirect + github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect + github.com/gogo/gateway v1.1.0 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/btree v1.0.0 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/orderedcode v0.0.1 // indirect + github.com/gorilla/handlers v1.5.1 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect + github.com/gtank/merlin v0.1.1 // indirect + github.com/gtank/ristretto255 v0.1.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hdevalence/ed25519consensus v0.0.0-20210204194344-59a8610d2b87 // indirect + github.com/improbable-eng/grpc-web v0.14.1 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jmhodges/levigo v1.0.0 // indirect + github.com/keybase/go-keychain v0.0.0-20190712205309-48d3d31d256d // indirect + github.com/klauspost/compress v1.13.6 // indirect + github.com/lib/pq v1.10.4 // indirect + github.com/libp2p/go-buffer-pool v0.0.2 // indirect + github.com/magiconair/properties v1.8.5 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/mitchellh/mapstructure v1.4.3 // indirect + github.com/mtibben/percent v0.2.1 // indirect + github.com/pelletier/go-toml v1.9.4 // indirect + github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect + github.com/rs/cors v1.8.0 // indirect + github.com/rs/zerolog v1.26.0 // indirect + github.com/sasha-s/go-deadlock v0.2.1-0.20190427202633-1595213edefa // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.10.1 // indirect + github.com/subosito/gotenv v1.2.0 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c // indirect + github.com/tendermint/btcd v0.1.1 // indirect + github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect + github.com/tendermint/go-amino v0.16.0 // indirect + github.com/zondax/hid v0.9.0 // indirect + go.etcd.io/bbolt v1.3.6 // indirect + golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect + golang.org/x/net v0.0.0-20211005001312-d4b1ae081e3b // indirect + golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect + golang.org/x/text v0.3.7 // indirect + gopkg.in/ini.v1 v1.66.2 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect + nhooyr.io/websocket v1.8.6 // indirect +) + replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 replace github.com/cosmos/cosmos-sdk => github.com/desmos-labs/cosmos-sdk v0.43.0-alpha1.0.20211206072111-16bfceb83430 diff --git a/go.sum b/go.sum index 2ce12719fc..e938296e2f 100644 --- a/go.sum +++ b/go.sum @@ -375,7 +375,6 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= @@ -515,7 +514,6 @@ github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qH github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gotestyourself/gotestyourself v2.2.0+incompatible h1:AQwinXlbQR2HvPjQZOmDhRqsv5mZf+Jb1RnSLxcqZcI= github.com/gotestyourself/gotestyourself v2.2.0+incompatible/go.mod h1:zZKM6oeNM8k+FRljX1mnzVYeS8wiGgQyvST1/GafPbY= github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= @@ -845,10 +843,8 @@ github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnh github.com/otiai10/copy v1.6.0 h1:IinKAryFFuPONZ7cm6T6E2QX/vcJwSnlaA5lfoaXIiQ= github.com/otiai10/copy v1.6.0/go.mod h1:XWfuS3CrI0R6IE0FbgHsEazaXO8G0LpMp9o8tos0x4E= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= -github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= -github.com/otiai10/mint v1.3.2 h1:VYWnrP5fXmz1MXvjuUvcBrXSjGE6xjON+axB/UrpO3E= github.com/otiai10/mint v1.3.2/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -1683,7 +1679,6 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 6c6e53bfcc5d982f2353020a21393da8057b1adc Mon Sep 17 00:00:00 2001 From: Riccardo Montagnin Date: Tue, 15 Feb 2022 11:58:33 +0100 Subject: [PATCH 47/47] added missing cmd tests Signed-off-by: Riccardo Montagnin --- x/subspaces/client/cli/cli_test.go | 99 ++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/x/subspaces/client/cli/cli_test.go b/x/subspaces/client/cli/cli_test.go index 5dab6f452a..cdd9f35b35 100644 --- a/x/subspaces/client/cli/cli_test.go +++ b/x/subspaces/client/cli/cli_test.go @@ -548,6 +548,105 @@ func (s *IntegrationTestSuite) TestCmdCreateUserGroup() { } } +func (s *IntegrationTestSuite) TestCmdEditUserGroup() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + respType proto.Message + }{ + { + name: "invalid subspace id returns error", + args: []string{"0", "1"}, + shouldErr: true, + }, + { + name: "invalid group id returns error", + args: []string{"1", "0"}, + shouldErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "1", "1", + fmt.Sprintf("--%s=%s", flags.FlagName, "This is my new group name"), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + shouldErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdEditUserGroup() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} + +func (s *IntegrationTestSuite) TestCmdSetUserGroupPermissions() { + val := s.network.Validators[0] + testCases := []struct { + name string + args []string + shouldErr bool + respType proto.Message + }{ + { + name: "invalid subspace id returns error", + args: []string{"0", "1"}, + shouldErr: true, + }, + { + name: "invalid group id returns error", + args: []string{"1", "0"}, + shouldErr: true, + }, + { + name: "valid data returns no error", + args: []string{ + "1", "1", types.SerializePermission(types.PermissionWrite), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + }, + shouldErr: false, + respType: &sdk.TxResponse{}, + }, + } + + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + cmd := cli.GetCmdSetUserGroupPermissions() + clientCtx := val.ClientCtx + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args) + if tc.shouldErr { + s.Require().Error(err) + } else { + s.Require().NoError(err) + s.Require().NoError(clientCtx.JSONCodec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) + } + }) + } +} + func (s *IntegrationTestSuite) TestCmdDeleteUserGroup() { val := s.network.Validators[0] testCases := []struct {