Skip to content

Commit

Permalink
docs: Add docs for group module (cosmos#10800)
Browse files Browse the repository at this point in the history
## Description

Closes: cosmos#9902 
Add docs for group module

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
  • Loading branch information
likhita-809 authored Jan 4, 2022
1 parent 59793e6 commit 7521bcc
Show file tree
Hide file tree
Showing 6 changed files with 1,821 additions and 0 deletions.
74 changes: 74 additions & 0 deletions x/group/spec/01_concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!--
order: 1
-->

# Concepts

## Group

A group is simply an aggregation of accounts with associated weights. It is not
an account and doesn't have a balance. It doesn't in and of itself have any
sort of voting or decision weight. It does have an "administrator" which has
the ability to add, remove and update members in the group. Note that a
group account could be an administrator of a group.

## Group Account

A group account is an account associated with a group and a decision policy.
Group accounts are abstracted from groups because a single group may have
multiple decision policies for different types of actions. Managing group
membership separately from decision policies results in the least overhead
and keeps membership consistent across different policies. The pattern that
is recommended is to have a single master group account for a given group,
and then to create separate group accounts with different decision policies
and delegate the desired permissions from the master account to
those "sub-accounts" using the `x/authz` module.

## Decision Policy

A decision policy is the mechanism by which members of a group can vote on
proposals.

All decision policies generally would have a minimum and maximum voting window.
The minimum voting window is the minimum amount of time that must pass in order
for a proposal to potentially pass, and it may be set to 0. The maximum voting
window is the maximum time that a proposal may be voted on before it is closed.
Both of these values must be less than a chain-wide max voting window parameter.

### Threshold decision policy

A threshold decision policy defines a threshold of yes votes (based on a tally
of voter weights) that must be achieved in order for a proposal to pass. For
this decision policy, abstain and veto are simply treated as no's.

## Proposal

Any member of a group can submit a proposal for a group account to decide upon.
A proposal consists of a set of messages that will be executed if the proposal
passes as well as any metadata associated with the proposal.

## Voting

There are four choices to choose while voting - yes, no, abstain and veto. Not
all decision policies will support them. Votes can contain some optional metadata.
During the voting window, accounts that have already voted may change their vote.
In the current implementation, the voting window begins as soon as a proposal
is submitted.

## Executing Proposals

Proposals will not be automatically executed by the chain in this current design,
but rather a user must submit a `Msg/Exec` transaction to attempt to execute the
proposal based on the current votes and decision policy.
It's also possible to try to execute a proposal immediately on creation or on
new votes using the `Exec` field of `Msg/CreateProposal` and `Msg/Vote` requests.
In the former case, proposers signatures are considered as yes votes.
For now, if the proposal can't be executed, it'll still be opened for new votes and
could be executed later on.

### Changing Group Membership

In the current implementation, changing a group's membership (adding or removing members or changing their weight)
will cause all existing proposals for group accounts linked to this group
to be invalidated. They will simply fail if someone calls `Msg/Exec` and will
eventually be garbage collected.
103 changes: 103 additions & 0 deletions x/group/spec/02_state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<!--
order: 2
-->

# State

The `group` module uses the `orm` package which provides table storage with support for
primary keys and secondary indexes. `orm` also defines `Sequence` which is a persistent unique key generator based on a counter that can be used along with `Table`s.

Here's the list of tables and associated sequences and indexes stored as part of the `group` module.

## Group Table

The `groupTable` stores `GroupInfo`: `0x0 | BigEndian(GroupId) -> ProtocolBuffer(GroupInfo)`.

### groupSeq

The value of `groupSeq` is incremented when creating a new group and corresponds to the new `GroupId`: `0x1 | 0x1 -> BigEndian`.

The second `0x1` corresponds to the ORM `sequenceStorageKey`.

### groupByAdminIndex

`groupByAdminIndex` allows to retrieve groups by admin address:
`0x2 | len([]byte(group.Admin)) | []byte(group.Admin) | BigEndian(GroupId) -> []byte()`.

## Group Member Table

The `groupMemberTable` stores `GroupMember`s: `0x10 | BigEndian(GroupId) | []byte(member.Address) -> ProtocolBuffer(GroupMember)`.

The `groupMemberTable` is a primary key table and its `PrimaryKey` is given by
`BigEndian(GroupId) | []byte(member.Address)` which is used by the following indexes.

### groupMemberByGroupIndex

`groupMemberByGroupIndex` allows to retrieve group members by group id:
`0x11 | BigEndian(GroupId) | PrimaryKey -> []byte()`.

### groupMemberByMemberIndex

`groupMemberByMemberIndex` allows to retrieve group members by member address:
`0x12 | len([]byte(member.Address)) | []byte(member.Address) | PrimaryKey -> []byte()`.

## Group Account Table

The `groupAccountTable` stores `GroupAccountInfo`: `0x20 | len([]byte(Address)) | []byte(Address) -> ProtocolBuffer(GroupAccountInfo)`.

The `groupAccountTable` is a primary key table and its `PrimaryKey` is given by
`len([]byte(Address)) | []byte(Address)` which is used by the following indexes.

### groupAccountSeq

The value of `groupAccountSeq` is incremented when creating a new group account and is used to generate the new group account `Address`:
`0x21 | 0x1 -> BigEndian`.

The second `0x1` corresponds to the ORM `sequenceStorageKey`.

### groupAccountByGroupIndex

`groupAccountByGroupIndex` allows to retrieve group accounts by group id:
`0x22 | BigEndian(GroupId) | PrimaryKey -> []byte()`.

### groupAccountByAdminIndex

`groupAccountByAdminIndex` allows to retrieve group accounts by admin address:
`0x23 | len([]byte(Address)) | []byte(Address) | PrimaryKey -> []byte()`.

## Proposal Table

The `proposalTable` stores `Proposal`s: `0x30 | BigEndian(ProposalId) -> ProtocolBuffer(Proposal)`.

### proposalSeq

The value of `proposalSeq` is incremented when creating a new proposal and corresponds to the new `ProposalId`: `0x31 | 0x1 -> BigEndian`.

The second `0x1` corresponds to the ORM `sequenceStorageKey`.

### proposalByGroupAccountIndex

`proposalByGroupAccountIndex` allows to retrieve proposals by group account address:
`0x32 | len([]byte(account.Address)) | []byte(account.Address) | BigEndian(ProposalId) -> []byte()`.

### proposalByProposerIndex

`proposalByProposerIndex` allows to retrieve proposals by proposer address:
`0x33 | len([]byte(proposer.Address)) | []byte(proposer.Address) | BigEndian(ProposalId) -> []byte()`.

## Vote Table

The `voteTable` stores `Vote`s: `0x40 | BigEndian(ProposalId) | []byte(voter.Address) -> ProtocolBuffer(Vote)`.

The `voteTable` is a primary key table and its `PrimaryKey` is given by
`BigEndian(ProposalId) | []byte(voter.Address)` which is used by the following indexes.

### voteByProposalIndex

`voteByProposalIndex` allows to retrieve votes by proposal id:
`0x41 | BigEndian(ProposalId) | PrimaryKey -> []byte()`.

### voteByVoterIndex

`voteByVoterIndex` allows to retrieve votes by voter address:
`0x42 | len([]byte(voter.Address)) | []byte(voter.Address) | PrimaryKey -> []byte()`.
106 changes: 106 additions & 0 deletions x/group/spec/03_messages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<!--
order: 3
-->

# Msg Service

## Msg/CreateGroup

A new group can be created with the `MsgCreateGroup`, which has an admin address, a list of members and some optional metadata bytes.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L54-L65

It's expecting to fail if metadata length is greater than some `MaxMetadataLength`.

## Msg/UpdateGroupMembers

Group members can be updated with the `UpdateGroupMembers`.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L74-L86

In the list of `MemberUpdates`, an existing member can be removed by setting its weight to 0.

It's expecting to fail if the signer is not the admin of the group.

## Msg/UpdateGroupAdmin

The `UpdateGroupAdmin` can be used to update a group admin.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L91-L102

It's expecting to fail if the signer is not the admin of the group.

## Msg/UpdateGroupMetadata

The `UpdateGroupMetadata` can be used to update a group metadata.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L107-L118

It's expecting to fail if:
- new metadata length is greater than some `MaxMetadataLength`.
- the signer is not the admin of the group.

## Msg/CreateGroupAccount

A new group account can be created with the `MsgCreateGroupAccount`, which has an admin address, a group id, a decision policy and some optional metadata bytes.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L121-L142

It's expecting to fail if metadata length is greater than some `MaxMetadataLength`.

## Msg/UpdateGroupAccountAdmin

The `UpdateGroupAccountAdmin` can be used to update a group account admin.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L151-L162

It's expecting to fail if the signer is not the admin of the group account.

## Msg/UpdateGroupAccountDecisionPolicy

The `UpdateGroupAccountDecisionPolicy` can be used to update a decision policy.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L167-L179

It's expecting to fail if the signer is not the admin of the group account.

## Msg/UpdateGroupAccountMetadata

The `UpdateGroupAccountMetadata` can be used to update a group account metadata.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L184-L195

It's expecting to fail if:
- new metadata length is greater than some `MaxMetadataLength`.
- the signer is not the admin of the group.

## Msg/CreateProposal

A new group account can be created with the `MsgCreateProposal`, which has a group account address, a list of proposers addresses, a list of messages to execute if the proposal is accepted and some optional metadata bytes.
An optional `Exec` value can be provided to try to execute the proposal immediately after proposal creation. Proposers signatures are considered as yes votes in this case.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L218-L239

It's expecting to fail if metadata length is greater than some `MaxMetadataLength`.

## Msg/Vote

A new vote can be created with the `MsgVote`, given a proposal id, a voter address, a choice (yes, no, veto or abstain) and some optional metadata bytes.
An optional `Exec` value can be provided to try to execute the proposal immediately after voting.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L248-L265

It's expecting to fail if metadata length is greater than some `MaxMetadataLength`.

## Msg/Exec

A proposal can be executed with the `MsgExec`.

+++ https://github.com/cosmos/cosmos-sdk/blob/6f58963e7f6ce820e9b33f02f06f7b96f6d2e347/proto/cosmos/group/v1beta1/tx.proto#L270-L278

The messages that are part of this proposal won't be executed if:
- the group has been modified before tally.
- the group account has been modified before tally.
- the proposal has not been accepted.
- the proposal status is not closed.
- the proposal has already been successfully executed.
56 changes: 56 additions & 0 deletions x/group/spec/04_events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!--
order: 4
-->

# Events

The group module emits the following events:

## EventCreateGroup

| Type | Attribute Key | Attribute Value |
|---------------------------------------|---------------|---------------------------------------|
| message | action | /cosmos.group.v1beta1.Msg/CreateGroup |
| cosmos.group.v1beta1.EventCreateGroup | group_id | {groupId} |

## EventUpdateGroup

| Type | Attribute Key | Attribute Value |
|---------------------------------------|---------------|-----------------------------------------------------------------|
| message | action | /cosmos.group.v1beta1.Msg/UpdateGroup{Admin\|Metadata\|Members} |
| cosmos.group.v1beta1.EventUpdateGroup | group_id | {groupId} |

## EventCreateGroupAccount

| Type | Attribute Key | Attribute Value |
|----------------------------------------------|---------------|----------------------------------------------|
| message | action | /cosmos.group.v1beta1.Msg/CreateGroupAccount |
| cosmos.group.v1beta1.EventCreateGroupAccount | address | {groupAccountAddress} |

## EventUpdateGroupAccount

| Type | Attribute Key | Attribute Value |
|----------------------------------------------|---------------|-------------------------------------------------------------------------------|
| message | action | /cosmos.group.v1beta1.Msg/UpdateGroupAccount{Admin\|Metadata\|DecisionPolicy} |
| cosmos.group.v1beta1.EventUpdateGroupAccount | address | {groupAccountAddress} |

## EventCreateProposal

| Type | Attribute Key | Attribute Value |
|------------------------------------------|---------------|------------------------------------------|
| message | action | /cosmos.group.v1beta1.Msg/CreateProposal |
| cosmos.group.v1beta1.EventCreateProposal | proposal_id | {proposalId} |

## EventVote

| Type | Attribute Key | Attribute Value |
|--------------------------------|---------------|--------------------------------|
| message | action | /cosmos.group.v1beta1.Msg/Vote |
| cosmos.group.v1beta1.EventVote | proposal_id | {proposalId} |

## EventExec

| Type | Attribute Key | Attribute Value |
|--------------------------------|---------------|--------------------------------|
| message | action | /cosmos.group.v1beta1.Msg/Exec |
| cosmos.group.v1beta1.EventExec | proposal_id | {proposalId} |
Loading

0 comments on commit 7521bcc

Please sign in to comment.