-
Notifications
You must be signed in to change notification settings - Fork 134
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
Voting contract #6
Conversation
voting-contract/src/lib.rs
Outdated
|
||
#[derive(BorshDeserialize, BorshSerialize)] | ||
pub struct AccountVotes { | ||
votes: HashMap<ProposalId, 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.
This has to be Map
otherwise it'll be too slow. Take a look at fungible-token
example to see how to handle inner maps.
voting-contract/src/lib.rs
Outdated
} | ||
} | ||
|
||
pub fn withdraw(&mut self, proposal_id: ProposalId, stake: 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.
I think you don't need to withdraw. Just set use vote
with stake = 0
voting-contract/src/lib.rs
Outdated
pub struct Votes { | ||
proposals: Map<ProposalId, Proposal>, | ||
next_proposal_index: ProposalId, | ||
proposed_heights: BTreeMap<BlockHeight, ProposalId>, |
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 don't think you need BTreeMap for proposals. It all can be done offline and later the contract can be notified.
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.
Not sure what you mean. This is done so that it is easy to remove expired 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.
I suggest simplify this contract and don't keep things sorted internally. We can also don't need to automatically resolve proposals when the new vote arrives. Instead we can add a method resolve
that takes a proposal ID. And it tries to resolve a given proposal. This way the contract internally doesn't have to garbage collect expired proposals, but instead rely on someone calling resolve
on a given proposal.
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.
Okay sounds good.
voting-contract/src/lib.rs
Outdated
|
||
#[near_bindgen] | ||
#[derive(BorshDeserialize, BorshSerialize)] | ||
pub struct Votes { |
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 would suggest to restructure this contract per Proposal.
The contract should have a top-level map of proposals. When a proposal is resolved, you can remove all voting information, because it's now irrelevant from the Proposal. But you still have to keep the proposal.
When proposal expires, you can also remove voting information relevant to the expired proposal.
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.
What do you mean by "proposal is resolved"
voting-contract/src/lib.rs
Outdated
#[derive(BorshDeserialize, BorshSerialize, Eq, PartialEq, Debug, Serialize)] | ||
pub struct Proposal { | ||
/// Proposed height to reset the network. | ||
proposed_height: BlockHeight, |
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 thought it's a generic contract, and not specific to network resets.
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.
So I am slightly confused about that. Do we want to write a general contract that can be used for multiple things? Then we need to encode the actual object that is proposed in some way.
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.
Good point. We may want to include binary metadata: Vec<u8>
field to every proposal, which will keep the required information in a serialized form.
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.
@evgenykuzyakov so you want to have one contract that simultaneous hold different types of votes. That seems a bit strange to me and I would like to have one contract per voting, i.e, there will be one contract deployed for network reset height, another one for unlocking.
@@ -0,0 +1,21 @@ | |||
MIT License |
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, should we have one license file for the whole repo instead of per each project?
also you can use https://github.com/near/near-api-js/blob/master/LICENSE and https://github.com/near/near-api-js/blob/master/LICENSE-APACHE for dual licensing.
|
||
The purpose of this contract is for people to vote on the next reset height for the network that the | ||
contract is deployed on. Anyone can submit a proposal but only stakeholders can vote. Once over 2/3 of total | ||
stake in an epoch has voted on a proposal, the proposed height becomes final and the voting is closed. |
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.
So I thought we are going to do next thing:
- Proposal are sent with date of unlock all the time, there is a window to vote for proposal is time to unlock - 2 weeks - 4 epochs
- Validators vote for proposals as they see fit until voting is allowed: either yay or nay
- Proposal voting locks for 4 epochs and at that point we evaluate who voted for it, and what is their stake. If 66% of total stake voted -> proceed on 2 week waiting period before unlocking.
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.
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.
Why do we need 2 week waiting period?
Are you commenting on upgradability or transfers vote?
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.
Let's move this discussion to near/NEPs#62
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.
Moved there.
Other version is already. |
Initial version of voting contract that allows people to vote on the next network reset height. TODO: add more testing and finish exposing necessary host functions near/nearcore#2475