-
Notifications
You must be signed in to change notification settings - Fork 143
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: voting contract #62
Conversation
Your Render PR Server URL is https://nomicon-pr-62.onrender.com. Follow its progress at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80. |
Your Render PR Server at https://nomicon-pr-62.onrender.com is now live! View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80. |
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.
I think having separate Poll
and Proposal
is not required and adds to complexity.
Thinking from a high level design, what are the minimum API that is needed to accomplish any action?
Let's say we merge Poll
and Proposal
into one. Let's call it Proposal
.
You need the following properties:
- human readable description
- machine readable description (or metadata). This is needed for other contracts relaying on this contract.
- expiration height. This should be optional, since some proposals don't have to expire ever.
- votes or result.
- Maybe you want to have a majority fraction. E.g. 1/2, or 2/3
The rest can be built outside of this contract.
I assume there 2 use-cases right now:
- unlock transfers
- no expiration
- no metadata needed
- need to know the timestamp when it's resolved
- may need 1/2
- network upgrade
- has expiration
- has metadata with the block number to shutdown
- there can be multiple proposals like this
- may need 2/3
@evgenykuzyakov Two questions:
|
If we decide that each proposal is independent, then each proposal can either be accepted or expire. For transfers, you should get to the state where transfers can expire. For network upgrades, we can have a separate contract that tracks current poll by having a list of proposals.
Might need to limit who can create proposals through whitelist. Then network upgrade contract will be able to create proposals. |
@evgenykuzyakov I see. That is an interesting approach. So pretty much you can vote on both "unlocking transfer at height 10000" and "unlocking transfer at height 1000" with all your stake. It definitely simplifies things a lot but at the same time it feels a bit weird... |
I think that will result in bad UX. You have to go to one contract to create a proposal and another to actually vote on it. |
What does this mean? |
Sorry. I meant you should NOT get to the state where transfers vote can expire. |
Update: discussed with @evgenykuzyakov offline. We decide that:
|
Your Render PR Server at https://nomicon-pr-62.onrender.com is now live! View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80. |
Your Render PR Server at https://nomicon-pr-62.onrender.com is now live! View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80. |
Your Render PR Server at https://nomicon-pr-62.onrender.com is now live! View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80. |
The voting contract has the following methods to allow creation of polls and proposals, as well as voting for proposals. | ||
|
||
```rust | ||
impl Poll { |
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.
Need a method get the result
Randomly landed here: does this mean NEAR will also have on-chain governance? Who could make such proposals? If it's any NEAR account it will probably be useful to add some deposit to the contract that might be burned/given to the community pool or whatever to prevent spam |
Yes as I said in the proposal this will be the first step towards on-chain governance. The current plan is that anyone can make proposals, but as you point out, we need some economics around that to prevent attacks. That part is not finalized yet and I'll update the proposal when I flesh out the details a bit more. |
Your Render PR Server at https://nomicon-pr-62.onrender.com is now live! View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80. |
Your Render PR Server at https://nomicon-pr-62.onrender.com is now live! View it on your dashboard at https://dashboard.render.com/static/srv-bqo93jrl66gn0u9nvn80. |
Expose validator information as host functions: ``` validator_stake(account_id_len: u64, account_id_ptr: u64, stake_ptr: u64) -> [] total_validator_stake(stake_ptr: u64) -> [] ``` so that voting contract can calculate the weight of each vote. Resolves #2475. Implements the runtime change specified in near/NEPs#62
Posting my comment from here near/core-contracts#6 (comment): So I thought we are going to do next thing:
Why 4 epochs? Because we want to allow delegates to switch their validators if they don't think the validator they are delegating right now represents them. Why 2 weeks? Because transfer unlock will require various parties to be prepared for it (wallets, possible exchange listings, users, financial participants, etc). Giving them a specific timeline heads up is important. Also if this vote happens right after Phase 1 is done, at least there are couple of weeks between those two events (this is also needed for some internal timelines). |
@ilblackdragon this voting contract design is not specific to voting for unlocking transfer. I am not sure how to best reconcile this suggestion with the general template. |
Give me an example usage of general template? E.g. I'm not sure why would general template not follow the same rules without understanding where else are you planning to use this general template? |
@ilblackdragon the spec for the next version of the protocol for example. I was concerned with this part
I am not sure whether you are talking about proposals in general or proposals in one specific contract. Also 2 weeks seem specific to the concerns of unlocking transfers as well. |
This can be done on the receiving part. The lockup contracts can use timestamp +2weeks. |
Fine with moving 2 weeks into lockups. |
accounts: Map<AccountId, Balance>, | ||
/// Next proposal id. | ||
next_proposal_id: ProposalId, | ||
/// Threshold for closing the poll, i.e, if the ratio of stake on a certain proposal over total stake reaches |
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.
do we also want to have a minumum amount of stake as well?
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.
We can
} | ||
``` | ||
Here `metadata` is the json serialized content of the proposal. For example, if the poll is about when the network upgrade | ||
should happen, `metadata` will be something like `{"height": 10000}`. Validators can vote on multiple different proposals |
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.
if the proposals are about height - then if I vote for height 10000, I also vote for all heights above it.
So it's a bit unclear how here multiple voting will work, given need to apply full stake on all of them.
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.
multiple voting will work
The rule is that the sum of your voted stake cannot exceed your current stake.
```rust | ||
fn resolve_proposal(&mut self, proposal_id: ProposalId) { | ||
// if the epoch height has changed, then | ||
// for each vote in the proposal, its stake is changed to orginal_stake * current_total_account_stake / previous_total_account_stake. |
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.
hm, this is incorrect?
let's say everyone received 10k of rewards, and one validator withdrew 10k from their acount.
total stake didn't change, but that validators stake reduced.
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.
total stake didn't change
Why? with reward the total stake increases
one validator withdrew 10k from their account
Stake doesn't get returned immediately so I don't think there is a problem.
/// All proposals for this poll. | ||
proposals: Map<ProposalId, Proposal>, | ||
/// Accounts that have participated in this poll and the corresponding stake voted. | ||
accounts: Map<AccountId, Balance>, |
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.
sounds like this should be fraction of their stake, because stake is changing constantly.
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.
Isn't it the same thing? If we store fractions here we need the actual stake to compute whether a proposal should be finalized and to update it when a validator changes their vote.
@bowenwang1996 I am closing this NEP as it seems that |
This NEP describes the voting contract we need for various governance related activities, such as when to reset the network and when to unlock token transfer. There has been some preliminary work around the contract implementation near/core-contracts#6 and necessary protocol changes near/nearcore#2504.