## Description ref: #11955 - [x] Reverts the documentation updates about middlewares (#11918, #11445 and part of #11860). - [x] Adds explanation about post-handlers --- ### 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... - [x] 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 - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/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 - [x] reviewed "Files changed" and left comments if necessary - [x] 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)
7.2 KiB
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 policy account could be an administrator of a group, and that the administrator doesn't necessarily have to be a member of the group.
Group Policy
A group policy is an account associated with a group and a decision policy.
Group policies 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 policy for a given group,
and then to create separate group policies 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, as well as the rules that dictate whether a proposal should pass or not based on its tally outcome.
All decision policies generally would have a mininum execution period and a maximum voting window. The minimum execution period is the minimum amount of time that must pass after submission in order for a proposal to potentially be executed, and it may be set to 0. The maximum voting window is the maximum time after submission that a proposal may be voted on before it is tallied.
The chain developer also defines an app-wide maximum execution period, which is the maximum amount of time after a proposal's voting period end where users are allowed to execute a proposal.
The current group module comes shipped with two decision policies: threshold
and percentage. Any chain developer can extend upon these two, by creating
custom decision policies, as long as they adhere to the DecisionPolicy
interface:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/x/group/types.go#L27-L41
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.
Percentage decision policy
A percentage decision policy is similar to a threshold decision policy, except that the threshold is not defined as a constant weight, but as a percentage. It's more suited for groups where the group members' weights can be updated, as the percentage threshold stays the same, and doesn't depend on how those member weights get updated.
Proposal
Any member(s) of a group can submit a proposal for a group policy 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 take the four choices into account. Votes can contain some optional metadata. In the current implementation, the voting window begins as soon as a proposal is submitted, and the end is defined by the group policy's decision policy.
Withdrawing Proposals
Proposals can be withdrawn any time before the voting period end, either by the
admin of the group policy or by one of the proposers. Once withdrawn, it is
marked as PROPOSAL_STATUS_WITHDRAWN, and no more voting or execution is
allowed on it.
Aborted Proposals
If the group policy is updated during the voting period of the proposal, then
the proposal is marked as PROPOSAL_STATUS_ABORTED, and no more voting or
execution is allowed on it. This is because the group policy defines the rules
of proposal voting and execution, so if those rules change during the lifecycle
of a proposal, then the proposal should be marked as stale.
Tallying
Tallying is the counting of all votes on a proposal. It happens only once in the lifecycle of a proposal, but can be triggered by two factors, whichever happens first:
- either someone tries to execute the proposal (see next section), which can
happen on a
Msg/Exectransaction, or aMsg/{SubmitProposal,Vote}transaction with theExecfield set. When a proposal execution is attempted, a tally is done first to make sure the proposal passes. - or on
EndBlockwhen the proposal's voting period end just passed.
If the tally result passes the decision policy's rules, then the proposal is
marked as PROPOSAL_STATUS_ACCEPTED, or else it is marked as
PROPOSAL_STATUS_REJECTED. In any case, no more voting is allowed anymore, and the tally
result is persisted to state in the proposal's FinalTallyResult.
Executing Proposals
Proposals are executed only when the tallying is done, and the group account's
decision policy allows the proposal to pass based on the tally outcome. They
are marked by the status PROPOSAL_STATUS_ACCEPTED. Execution must happen
before a duration of MaxExecutionPeriod (set by the chain developer) after
each proposal's voting period end.
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. Any user (not only the
group members) can execute proposals that have been accepted, and execution fees are
paid by the proposal executor.
It's also possible to try to execute a proposal immediately on creation or on
new votes using the Exec field of Msg/SubmitProposal and Msg/Vote requests.
In the former case, proposers signatures are considered as yes votes.
In these cases, if the proposal can't be executed (i.e. it didn't pass the
decision policy's rules), it will still be opened for new votes and
could be tallied and executed later on.
A successful proposal execution will have its ExecutorResult marked as
PROPOSAL_EXECUTOR_RESULT_SUCCESS. The proposal will be automatically pruned
after execution. On the other hand, a failed proposal execution will be marked
as PROPOSAL_EXECUTOR_RESULT_FAILURE. Such a proposal can be re-executed
multiple times, until it expires after MaxExecutionPeriod after voting period
end.
Pruning
Proposals and votes are automatically pruned to avoid state bloat.
Votes are pruned:
- either after a successful tally, i.e. a tally whose result passes the decision
policy's rules, which can be trigged by a
Msg/Execor aMsg/{SubmitProposal,Vote}with theExecfield set, - or on
EndBlockright after the proposal's voting period end. This applies to proposals with statusabortedorwithdrawntoo.
whichever happens first.
Proposals are pruned:
- on
EndBlockwhose proposal status iswithdrawnorabortedon proposal's voting period end before tallying, - and either after a successful proposal execution,
- or on
EndBlockright after the proposal'svoting_period_end+max_execution_period(defined as an app-wide configuration) is passed,
whichever happens first.