-
Notifications
You must be signed in to change notification settings - Fork 8
/
chainview.go
128 lines (115 loc) · 3.79 KB
/
chainview.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package mainchain
import (
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
)
type ValidatorInfo struct {
StakingPool *big.Int
MinSelfStake *big.Int
CommissionRate *big.Int
RateLockEndTime *big.Int
}
type ParamProposal struct {
Proposer Addr
Deposit *big.Int
VoteDeadline *big.Int
Record *big.Int
NewValue *big.Int
Status uint8
}
// return validators, totalStakes, quorumStakes
func (ethClient *EthClient) GetValidators() (map[Addr]*ValidatorInfo, *big.Int, *big.Int, error) {
maxValidatorNum, err := ethClient.GetUIntValue(MaxValidatorNum)
if err != nil {
return nil, nil, nil, fmt.Errorf("Get maxValidatorNum err: %w", err)
}
validators := make(map[Addr]*ValidatorInfo)
totalStakes := new(big.Int)
var i uint64
for i = 0; i < maxValidatorNum.Uint64(); i++ {
addr, err2 := ethClient.DPoS.ValidatorSet(&bind.CallOpts{}, big.NewInt(int64(i)))
if err2 != nil {
return nil, nil, nil, fmt.Errorf("Get validator %d err: %w", i, err2)
}
if addr != ZeroAddr {
info, err3 := ethClient.DPoS.GetCandidateInfo(&bind.CallOpts{}, addr)
if err3 != nil {
return nil, nil, nil, fmt.Errorf("Get validator %x info err: %w", addr, err3)
}
validators[addr] = &ValidatorInfo{
StakingPool: info.StakingPool,
MinSelfStake: info.MinSelfStake,
CommissionRate: info.CommissionRate,
RateLockEndTime: info.RateLockEndTime,
}
totalStakes = totalStakes.Add(totalStakes, info.StakingPool)
}
}
quorumStakes := new(big.Int).Mul(totalStakes, big.NewInt(2))
quorumStakes = quorumStakes.Quo(quorumStakes, big.NewInt(3))
quorumStakes = quorumStakes.Add(quorumStakes, big.NewInt(1))
return validators, totalStakes, quorumStakes, nil
}
// return checkedStakes, totalStakes, quorumStakes
func (ethClient *EthClient) CheckVotingPower(addrs []Addr) (*big.Int, *big.Int, *big.Int, error) {
validators, totalStakes, quorumStakes, err := ethClient.GetValidators()
if err != nil {
return nil, nil, nil, err
}
checked := make(map[Addr]bool)
checkedStakes := new(big.Int)
for _, addr := range addrs {
if checked[addr] {
continue
}
validator, exist := validators[addr]
if exist {
checkedStakes = checkedStakes.Add(checkedStakes, validator.StakingPool)
}
checked[addr] = true
}
return checkedStakes, totalStakes, quorumStakes, nil
}
func (ethClient *EthClient) GetParamProposal(id int64) (*ParamProposal, error) {
res, err := ethClient.DPoS.ParamProposals(&bind.CallOpts{}, big.NewInt(id))
if err != nil {
return nil, err
}
return &ParamProposal{
Proposer: res.Proposer,
Deposit: res.Deposit,
VoteDeadline: res.VoteDeadline,
Record: res.Record,
NewValue: res.NewValue,
Status: res.Status,
}, nil
}
func (ethClient *EthClient) GetParamProposalVote(id int64, voter Addr) (uint8, error) {
return ethClient.DPoS.GetParamProposalVote(&bind.CallOpts{}, big.NewInt(id), voter)
}
func (ethClient *EthClient) GetParamProposalVotes(id int64) (
yesVoters []Addr, noVoters []Addr, yesStakes, totalStakes, quorumStakes *big.Int, err error) {
var validators map[Addr]*ValidatorInfo
validators, totalStakes, quorumStakes, err = ethClient.GetValidators()
if err != nil {
return nil, nil, nil, nil, nil, err
}
yesStakes = new(big.Int)
for addr, val := range validators {
vote, err2 := ethClient.GetParamProposalVote(id, addr)
if err2 != nil {
return nil, nil, nil, nil, nil, err2
}
if vote == VoteYes {
yesStakes = yesStakes.Add(yesStakes, val.StakingPool)
yesVoters = append(yesVoters, addr)
} else if vote == VoteNo {
noVoters = append(noVoters, addr)
}
}
return yesVoters, noVoters, yesStakes, totalStakes, quorumStakes, nil
}
func (ethClient *EthClient) GetUIntValue(paramId uint64) (*big.Int, error) {
return ethClient.DPoS.GetUIntValue(&bind.CallOpts{}, big.NewInt(int64(paramId)))
}