forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: Add docs for group module (cosmos#10800)
## 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
1 parent
59793e6
commit 7521bcc
Showing
6 changed files
with
1,821 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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} | |
Oops, something went wrong.