-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(x/accounts): On-chain multisig #19988
Changes from 26 commits
882fb6e
2e349fb
17cd92e
a99e516
8d18378
52c42e4
e027903
de459bb
7c3b59c
2983fa6
2f204ff
a7b8661
b374ec5
2431bd9
ef2303b
cab1923
8cd1447
4018918
5117ed9
2b89d30
fba4307
ac97d6c
746f61a
7375fc1
0cdcc2c
b57d3a1
5ba3d59
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,153 @@ | ||||||||||||||||||||||||||||||||||||||||||||
# Multisig Accounts | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
* [State](#state) | ||||||||||||||||||||||||||||||||||||||||||||
* [Config](#config) | ||||||||||||||||||||||||||||||||||||||||||||
* [Proposal](#proposal) | ||||||||||||||||||||||||||||||||||||||||||||
* [Members](#members) | ||||||||||||||||||||||||||||||||||||||||||||
* [Methods](#methods) | ||||||||||||||||||||||||||||||||||||||||||||
* [MsgInit](#msginit) | ||||||||||||||||||||||||||||||||||||||||||||
* [MsgUpdateConfig](#msgupdateconfig) | ||||||||||||||||||||||||||||||||||||||||||||
* [MsgCreateProposal](#msgcreateproposal) | ||||||||||||||||||||||||||||||||||||||||||||
* [MsgVote](#msgvote) | ||||||||||||||||||||||||||||||||||||||||||||
* [MsgExecuteProposal](#msgexecuteproposal) | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+9
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation of list items is inconsistent with Markdown standards. - * [MsgInit](#msginit)
- * [MsgUpdateConfig](#msgupdateconfig)
- * [MsgCreateProposal](#msgcreateproposal)
- * [MsgVote](#msgvote)
- * [MsgExecuteProposal](#msgexecuteproposal)
+ * [MsgInit](#msginit)
+ * [MsgUpdateConfig](#msgupdateconfig)
+ * [MsgCreateProposal](#msgcreateproposal)
+ * [MsgVote](#msgvote)
+ * [MsgExecuteProposal](#msgexecuteproposal) Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
The x/accounts/defaults/multisig module provides the implementation for multisig accounts within the x/accounts module. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
## State | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
The multisig account keeps its members as a map of addresses and weights (`<[]byte, uint64>`), a config struct, a map of proposals and a map of votes. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
```go | ||||||||||||||||||||||||||||||||||||||||||||
type Account struct { | ||||||||||||||||||||||||||||||||||||||||||||
Members collections.Map[[]byte, uint64] | ||||||||||||||||||||||||||||||||||||||||||||
Sequence collections.Sequence | ||||||||||||||||||||||||||||||||||||||||||||
Config collections.Item[v1.Config] | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
addrCodec address.Codec | ||||||||||||||||||||||||||||||||||||||||||||
headerService header.Service | ||||||||||||||||||||||||||||||||||||||||||||
eventService event.Service | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Proposals collections.Map[uint64, v1.Proposal] | ||||||||||||||||||||||||||||||||||||||||||||
Votes collections.Map[collections.Pair[uint64, []byte], int32] // key: proposalID + voter address | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+23
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace hard tabs with spaces to maintain consistency in indentation. - Members collections.Map[[]byte, uint64]
- Sequence collections.Sequence
- Config collections.Item[v1.Config]
- addrCodec address.Codec
- headerService header.Service
- eventService event.Service
- Proposals collections.Map[uint64, v1.Proposal]
- Votes collections.Map[collections.Pair[uint64, []byte], int32] // key: proposalID + voter address
+ Members collections.Map[[]byte, uint64]
+ Sequence collections.Sequence
+ Config collections.Item[v1.Config]
+ addrCodec address.Codec
+ headerService header.Service
+ eventService event.Service
+ Proposals collections.Map[uint64, v1.Proposal]
+ Votes collections.Map[collections.Pair[uint64, []byte], int32] // key: proposalID + voter address Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
### Config | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
The config contains the basic rules defining how the multisig will work. All of these fields can be modified afterwards by calling [MsgUpdateConfig](#msgupdateconfig). | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider using "afterward" instead of "afterwards" to align with American English conventions. - All of these fields can be modified afterwards by calling [MsgUpdateConfig](#msgupdateconfig).
+ All of these fields can be modified afterward by calling [MsgUpdateConfig](#msgupdateconfig). Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
```protobuf | ||||||||||||||||||||||||||||||||||||||||||||
message Config { | ||||||||||||||||||||||||||||||||||||||||||||
int64 threshold = 1; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
int64 quorum = 2; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
// voting_period is the duration in seconds for the voting period. | ||||||||||||||||||||||||||||||||||||||||||||
int64 voting_period = 3; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
// revote defines if members can change their vote. | ||||||||||||||||||||||||||||||||||||||||||||
bool revote = 4; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
// early_execution defines if the multisig can be executed before the voting period ends. | ||||||||||||||||||||||||||||||||||||||||||||
bool early_execution = 5; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
### Proposal | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
The proposal contains the title, summary, messages and the status of the proposal. The messages are stored as `google.protobuf.Any` to allow for any type of message to be stored. | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a space after the period for better readability. - The proposal contains the title, summary, messages and the status of the proposal. The messages are stored as `google.protobuf.Any` to allow for any type of message to be stored.
+ The proposal contains the title, summary, messages and the status of the proposal. The messages are stored as `google.protobuf.Any` to allow for any type of message to be stored. Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
```protobuf | ||||||||||||||||||||||||||||||||||||||||||||
message Proposal { | ||||||||||||||||||||||||||||||||||||||||||||
string title = 1; | ||||||||||||||||||||||||||||||||||||||||||||
string summary = 2; | ||||||||||||||||||||||||||||||||||||||||||||
repeated google.protobuf.Any messages = 3; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
// if true, the proposal will execute as soon as the quorum is reached (last voter will execute). | ||||||||||||||||||||||||||||||||||||||||||||
bool execute = 4; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
// voting_period_end will be set by the account when the proposal is created. | ||||||||||||||||||||||||||||||||||||||||||||
int64 voting_period_end = 5; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
ProposalStatus status = 6; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
### Members | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Members are stored as a map of addresses and weights. The weight is used to determine the voting power of the member. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
## Methods | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
### MsgInit | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
The `MsgInit` message initializes a multisig account with the given members and config. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
```protobuf | ||||||||||||||||||||||||||||||||||||||||||||
message MsgInit { | ||||||||||||||||||||||||||||||||||||||||||||
repeated Member members = 1; | ||||||||||||||||||||||||||||||||||||||||||||
Config Config = 2; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
### MsgUpdateConfig | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
The `MsgUpdateConfig` message updates the config of the multisig account. Only the members that are changing are required, and if their weight is 0, they are removed. If the config is nil, then it will not be updated. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
```protobuf | ||||||||||||||||||||||||||||||||||||||||||||
message MsgUpdateConfig { | ||||||||||||||||||||||||||||||||||||||||||||
// only the members that are changing are required, if their weight is 0, they are removed. | ||||||||||||||||||||||||||||||||||||||||||||
repeated Member update_members = 1; | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
// not all fields from Config can be changed | ||||||||||||||||||||||||||||||||||||||||||||
Config Config = 2; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
### MsgCreateProposal | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
Only a member can create a proposal. The proposal will be stored in the account and the members will be able to vote on it. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
If a voting period is not set, the proposal will be created using the voting period from the config. If the proposal has a voting period, it will be used instead. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
```protobuf | ||||||||||||||||||||||||||||||||||||||||||||
message MsgCreateProposal { | ||||||||||||||||||||||||||||||||||||||||||||
Proposal proposal = 1; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
### MsgVote | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
The `MsgVote` message allows a member to vote on a proposal. The vote can be either `Yes`, `No` or `Abstain`. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
```protobuf | ||||||||||||||||||||||||||||||||||||||||||||
message MsgVote { | ||||||||||||||||||||||||||||||||||||||||||||
uint64 proposal_id = 1; | ||||||||||||||||||||||||||||||||||||||||||||
VoteOption vote = 2; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
// VoteOption enumerates the valid vote options for a given proposal. | ||||||||||||||||||||||||||||||||||||||||||||
enum VoteOption { | ||||||||||||||||||||||||||||||||||||||||||||
// VOTE_OPTION_UNSPECIFIED defines a no-op vote option. | ||||||||||||||||||||||||||||||||||||||||||||
VOTE_OPTION_UNSPECIFIED = 0; | ||||||||||||||||||||||||||||||||||||||||||||
// VOTE_OPTION_YES defines the yes proposal vote option. | ||||||||||||||||||||||||||||||||||||||||||||
VOTE_OPTION_YES = 1; | ||||||||||||||||||||||||||||||||||||||||||||
// VOTE_OPTION_ABSTAIN defines the abstain proposal vote option. | ||||||||||||||||||||||||||||||||||||||||||||
VOTE_OPTION_ABSTAIN = 2; | ||||||||||||||||||||||||||||||||||||||||||||
// VOTE_OPTION_NO defines the no proposal vote option. | ||||||||||||||||||||||||||||||||||||||||||||
VOTE_OPTION_NO = 3; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
### MsgExecuteProposal | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
The `MsgExecuteProposal` message allows a member to execute a proposal. The proposal must have reached the quorum and the voting period must have ended. | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
```protobuf | ||||||||||||||||||||||||||||||||||||||||||||
message MsgExecuteProposal { | ||||||||||||||||||||||||||||||||||||||||||||
uint64 proposal_id = 1; | ||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure the file ends with a single newline character. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the markdown link syntax.
Committable suggestion