-
Notifications
You must be signed in to change notification settings - Fork 169
Expand file tree
/
Copy pathstatus.go
More file actions
211 lines (178 loc) · 7.56 KB
/
status.go
File metadata and controls
211 lines (178 loc) · 7.56 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
package pdao
import (
"errors"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/urfave/cli"
"github.com/rocket-pool/smartnode/bindings/types"
"github.com/rocket-pool/smartnode/bindings/utils/eth"
"github.com/rocket-pool/smartnode/bindings/utils/strings"
"github.com/rocket-pool/smartnode/shared/services/rocketpool"
"github.com/rocket-pool/smartnode/shared/types/api"
cliutils "github.com/rocket-pool/smartnode/shared/utils/cli"
"github.com/rocket-pool/smartnode/shared/utils/math"
)
const (
colorBlue string = "\033[36m"
colorReset string = "\033[0m"
colorGreen string = "\033[32m"
signallingAddressLink string = "https://docs.rocketpool.net/guides/houston/participate#setting-your-snapshot-signalling-address"
challengeLink string = "https://docs.rocketpool.net/guides/houston/pdao#challenge-process"
)
func getStatus(c *cli.Context) error {
// Get RP client
rp := rocketpool.NewClientFromCtx(c)
defer rp.Close()
// Get wallet status
walletStatus, err := rp.WalletStatus()
if err != nil {
return err
}
// Get the config
cfg, isNew, err := rp.LoadConfig()
if err != nil {
return fmt.Errorf("Error loading configuration: %w", err)
}
// Print what network we're on
err = cliutils.PrintNetwork(cfg.GetNetwork(), isNew)
if err != nil {
return err
}
// rp.PDAOStatus() will fail with an error, but we can short-circuit it here.
if !walletStatus.WalletInitialized {
return errors.New("The node wallet is not initialized.")
}
// Get PDAO status at the latest block
response, err := rp.PDAOStatus()
if err != nil {
return err
}
// Get Protocol DAO proposals
allProposals, err := rp.PDAOProposals()
if err != nil {
return err
}
// Get protocol DAO proposals
claimableBondsResponse, err := rp.PDAOGetClaimableBonds()
if err != nil {
return fmt.Errorf("error checking for claimable bonds: %w", err)
}
claimableBonds := claimableBondsResponse.ClaimableBonds
// Signalling Status
fmt.Printf("%s=== Signalling on Snapshot ===%s\n", colorGreen, colorReset)
blankAddress := common.Address{}
if response.SignallingAddress == blankAddress {
fmt.Printf("The node does not currently have a snapshot signalling address set.\nTo learn more about snapshot signalling, please visit %s.\n", signallingAddressLink)
} else {
fmt.Printf("The node has a signalling address of %s%s%s which can represent it when voting on Rocket Pool Snapshot governance proposals.", colorBlue, response.SignallingAddressFormatted, colorReset)
fmt.Println()
}
if response.SnapshotResponse.Error != "" {
fmt.Printf("Unable to fetch latest voting information from snapshot.org: %s\n", response.SnapshotResponse.Error)
} else {
voteCount := response.SnapshotResponse.VoteCount()
if len(response.SnapshotResponse.ActiveSnapshotProposals) == 0 {
fmt.Print("Rocket Pool has no Snapshot governance proposals being voted on.\n")
} else {
fmt.Printf("Rocket Pool has %d Snapshot governance proposal(s) being voted on. You have voted on %d of those. See details using 'rocketpool network dao-proposals'.\n", len(response.SnapshotResponse.ActiveSnapshotProposals), voteCount)
}
fmt.Println("")
}
// Onchain Voting Status
fmt.Printf("%s=== Onchain Voting ===%s\n", colorGreen, colorReset)
if response.OnchainVotingDelegate == blankAddress {
fmt.Println("The node doesn't have a delegate, which means it can vote directly on onchain proposals after it initializes voting.")
} else if response.OnchainVotingDelegate == response.AccountAddress {
fmt.Println("The node doesn't have a delegate, which means it can vote directly on onchain proposals. You can have another node represent you by running `rocketpool p svd <address>`.")
} else {
fmt.Printf("The node has a voting delegate of %s%s%s which can represent it when voting on Rocket Pool onchain governance proposals.\n", colorBlue, response.OnchainVotingDelegateFormatted, colorReset)
}
fmt.Printf("The node's local voting power: %.10f\n", eth.WeiToEth(response.VotingPower))
if response.IsNodeRegistered {
fmt.Printf("Total voting power delegated to the node: %.10f\n", eth.WeiToEth(response.TotalDelegatedVp))
} else {
fmt.Print("The node must register using 'rocketpool node register' to be eligible to receive delegated voting power.\n")
}
fmt.Printf("Network total initialized voting power: %.10f\n", eth.WeiToEth(response.SumVotingPower))
fmt.Println("")
// Claimable Bonds Status:
fmt.Printf("%s=== Claimable RPL Bonds ===%s\n", colorGreen, colorReset)
if response.IsRPLLockingAllowed {
fmt.Print("The node is allowed to lock RPL to create governance proposals/challenges.\n")
if response.NodeRPLLocked.Cmp(big.NewInt(0)) != 0 {
fmt.Printf("The node currently has %.6f RPL locked.\n",
math.RoundDown(eth.WeiToEth(response.NodeRPLLocked), 6))
}
} else {
fmt.Print("The node is NOT allowed to lock RPL to create governance proposals/challenges. Use 'rocketpool node allow-rpl-locking, to allow RPL locking.\n")
}
if len(claimableBonds) == 0 {
fmt.Println("You do not have any unlockable bonds or claimable rewards.")
} else {
fmt.Println("The node has unlockable bonds or claimable rewards available. Use 'rocketpool pdao claim-bonds' to view and claim.")
}
fmt.Println("")
// Check if PDAO proposal checking duty is enabled
fmt.Printf("%s=== PDAO Proposal Checking Duty ===%s\n", colorGreen, colorReset)
// Make sure the user opted into this duty
if response.VerifyEnabled {
fmt.Println("The node has PDAO proposal checking duties enabled. It will periodically check for proposals to challenge.")
} else {
fmt.Printf("The node does not have PDAO proposal checking duties enabled (See %s to learn more about this duty).", challengeLink)
fmt.Println("")
}
fmt.Println("")
// Claimable Bonds Status:
fmt.Printf("%s=== Pending, Active and Succeeded Proposals ===%s\n", colorGreen, colorReset)
// Get proposals by state
stateProposals := map[string][]api.PDAOProposalWithNodeVoteDirection{}
for _, proposal := range allProposals.Proposals {
stateName := types.ProtocolDaoProposalStates[proposal.State]
if _, ok := stateProposals[stateName]; !ok {
stateProposals[stateName] = []api.PDAOProposalWithNodeVoteDirection{}
}
stateProposals[stateName] = append(stateProposals[stateName], proposal)
}
// Proposal states print order
proposalStates := []string{"Pending", "Active (Phase 1)", "Active (Phase 2)", "Succeeded"}
proposalStateInputs := []string{"pending", "phase1", "phase2", "succeeded"}
// Print & return
count := 0
succeededExists := false
for i, stateName := range proposalStates {
proposals, ok := stateProposals[stateName]
if !ok {
continue
}
// Check filter
if filterProposalState(proposalStateInputs[i], "") {
continue
}
// Print message for Succeeded Proposals
if stateName == "Succeeded" {
succeededExists = true
fmt.Printf("%sThe following proposal(s) have succeeded and are waiting to be executed. Use `rocketpool pdao proposals execute` to execute.%s\n\n", colorBlue, colorReset)
}
// Proposal state count
fmt.Printf("%d %s proposal(s):\n", len(proposals), stateName)
fmt.Println("")
// Proposals
for _, proposal := range proposals {
if len(proposal.Message) > 200 {
proposal.Message = proposal.Message[:200]
}
proposal.Message = strings.Sanitize(proposal.Message)
fmt.Printf("%d: %s - Proposed by: %s\n", proposal.ID, proposal.Message, proposal.ProposerAddress)
}
count += len(proposals)
fmt.Println()
}
if count == 0 {
fmt.Println("There are no onchain proposals open for voting.")
}
if !succeededExists {
fmt.Println("There are no proposals waiting to be executed.")
}
return nil
}