From 1a7b4b12efc7c5c632b22523ed09685069eca50e Mon Sep 17 00:00:00 2001 From: evlekht Date: Fri, 30 Jun 2023 16:23:26 +0400 Subject: [PATCH] wip --- .../dao/camino_change_base_fee_proposal.go | 28 +++++++++++++++---- vms/platformvm/dao/camino_proposal.go | 12 ++++++-- vms/platformvm/txs/executor/camino_dao.go | 4 +-- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/vms/platformvm/dao/camino_change_base_fee_proposal.go b/vms/platformvm/dao/camino_change_base_fee_proposal.go index a89d7fda5341..115c68292e5b 100644 --- a/vms/platformvm/dao/camino_change_base_fee_proposal.go +++ b/vms/platformvm/dao/camino_change_base_fee_proposal.go @@ -55,23 +55,39 @@ func (p *ChangeBaseFeeProposal) Visit(visitor Visitor) error { return visitor.ChangeBaseFeeProposal(p) } +func (p *ChangeBaseFeeProposal) canBeExecuted(proposalWithVotes *ProposalWithVotes) bool { + _, weight, err := p.Result(proposalWithVotes.Votes) + return err == nil && weight > proposalWithVotes.SuccessThreshold() +} + // Votes must be valid for this proposal, could panic otherwise. -func (p *ChangeBaseFeeProposal) Result(votes []VoteWithAddr) (any, error) { // TODO@ optimize +func (p *ChangeBaseFeeProposal) Result(votes []VoteWithAddr) (uint64, uint32, error) { // TODO@ optimize if len(votes) == 0 { - return nil, errNoVotes + return 0, 0, errNoVotes } - optionWeights := make([]int, len(p.FeeOptions)) + uncertain := false + optionWeights := make([]uint32, len(p.FeeOptions)) mostVotedOptionIndex := uint32(0) + for i := range votes { vote, ok := votes[i].Vote.(*SimpleVote) if !ok { - return nil, errWrongVoteType + return 0, 0, errWrongVoteType } optionWeights[vote.OptionIndex]++ - if optionWeights[vote.OptionIndex] > optionWeights[mostVotedOptionIndex] { + if vote.OptionIndex != mostVotedOptionIndex && + optionWeights[vote.OptionIndex] == optionWeights[mostVotedOptionIndex] { + uncertain = true + } else if optionWeights[vote.OptionIndex] > optionWeights[mostVotedOptionIndex] { mostVotedOptionIndex = vote.OptionIndex + uncertain = false } } - return p.FeeOptions[mostVotedOptionIndex], nil + + if uncertain { + return 0, 0, errUncertainResult + } + + return p.FeeOptions[mostVotedOptionIndex], optionWeights[mostVotedOptionIndex], nil } diff --git a/vms/platformvm/dao/camino_proposal.go b/vms/platformvm/dao/camino_proposal.go index 3d7dd55e8e04..68da27d986d2 100644 --- a/vms/platformvm/dao/camino_proposal.go +++ b/vms/platformvm/dao/camino_proposal.go @@ -16,6 +16,7 @@ const MaxProposalSize = 2048 // TODO@ var ( errEndNotAfterStart = errors.New("proposal end-time is not after start-time") errNoVotes = errors.New("no votes") + errUncertainResult = errors.New("uncertain result") ) type Visitor interface { @@ -29,8 +30,9 @@ type Proposal interface { StartTime() time.Time EndTime() time.Time IsActiveAt(time time.Time) bool - Visit(visitor Visitor) error - Result([]VoteWithAddr) (any, error) + Visit(Visitor) error + + canBeExecuted(*ProposalWithVotes) bool } type ProposalWithVotes struct { @@ -39,6 +41,10 @@ type ProposalWithVotes struct { Votes []VoteWithAddr `serialize:"true"` // TODO@ optimize } +func (p *ProposalWithVotes) SuccessThreshold() uint32 { + return uint32(len(p.AllowedVoters) / 2) +} + func (p *ProposalWithVotes) CanBeVotedBy(voterAddr ids.ShortID) bool { // TODO@ optimize for _, allowedVoterAddress := range p.AllowedVoters { if allowedVoterAddress == voterAddr { @@ -58,7 +64,7 @@ func (p *ProposalWithVotes) WasVotedBy(voterAddr ids.ShortID) bool { // TODO@ op } func (p *ProposalWithVotes) CanBeExecuted() bool { - return false // TODO@ + return p.Proposal.canBeExecuted(p) } // Will return modified proposal with added vote, original proposal will not be modified! diff --git a/vms/platformvm/txs/executor/camino_dao.go b/vms/platformvm/txs/executor/camino_dao.go index 7276f9d2eeae..c1e00ee2959d 100644 --- a/vms/platformvm/txs/executor/camino_dao.go +++ b/vms/platformvm/txs/executor/camino_dao.go @@ -81,10 +81,10 @@ func (e *proposalVerifier) ChangeBaseFeeProposal(*dao.ChangeBaseFeeProposal) err } func (e *proposalExecutor) ChangeBaseFeeProposal(proposal *dao.ChangeBaseFeeProposal) error { - result, err := proposal.Result(e.proposalWithVotes.Votes) + newBaseFee, _, err := proposal.Result(e.proposalWithVotes.Votes) if err != nil { return err } - e.state.SetBaseFee(result.(uint64)) + e.state.SetBaseFee(newBaseFee) return nil }