-
Notifications
You must be signed in to change notification settings - Fork 163
Expand file tree
/
Copy pathdissolve.go
More file actions
153 lines (130 loc) · 4.48 KB
/
dissolve.go
File metadata and controls
153 lines (130 loc) · 4.48 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
package minipool
import (
"bytes"
"fmt"
"github.com/ethereum/go-ethereum/common"
rocketpoolapi "github.com/rocket-pool/rocketpool-go/rocketpool"
"github.com/rocket-pool/rocketpool-go/types"
"github.com/rocket-pool/rocketpool-go/utils/eth"
"github.com/urfave/cli"
"github.com/rocket-pool/smartnode/shared/services/gas"
"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"
)
func dissolveMinipools(c *cli.Context) error {
// Get RP client
rp, err := rocketpool.NewClientFromCtx(c).WithReady()
if err != nil {
return err
}
defer rp.Close()
// Get minipool statuses
status, err := rp.MinipoolStatus()
if err != nil {
return err
}
// Get initialized minipools
initializedMinipools := []api.MinipoolDetails{}
for _, minipool := range status.Minipools {
if minipool.Status.Status == types.Initialized {
initializedMinipools = append(initializedMinipools, minipool)
}
}
// Check for initialized minipools
if len(initializedMinipools) == 0 {
fmt.Println("No minipools can be dissolved.")
return nil
}
// Get selected minipools
var selectedMinipools []api.MinipoolDetails
if c.String("minipool") == "" {
// Prompt for minipool selection
options := make([]string, len(initializedMinipools)+1)
options[0] = "All available minipools"
for mi, minipool := range initializedMinipools {
options[mi+1] = fmt.Sprintf("%s (%.6f ETH deposited)", minipool.Address.Hex(), math.RoundDown(eth.WeiToEth(minipool.Node.DepositBalance), 6))
}
selected, _ := cliutils.Select("Please select a minipool to dissolve:", options)
// Get minipools
if selected == 0 {
selectedMinipools = initializedMinipools
} else {
selectedMinipools = []api.MinipoolDetails{initializedMinipools[selected-1]}
}
} else {
// Get matching minipools
if c.String("minipool") == "all" {
selectedMinipools = initializedMinipools
} else {
selectedAddress := common.HexToAddress(c.String("minipool"))
for _, minipool := range initializedMinipools {
if bytes.Equal(minipool.Address.Bytes(), selectedAddress.Bytes()) {
selectedMinipools = []api.MinipoolDetails{minipool}
break
}
}
if selectedMinipools == nil {
return fmt.Errorf("The minipool %s is not available for dissolving.", selectedAddress.Hex())
}
}
}
// Get the total gas limit estimate
var totalGas uint64 = 0
var totalSafeGas uint64 = 0
var gasInfo rocketpoolapi.GasInfo
for _, minipool := range selectedMinipools {
canResponse, err := rp.CanDissolveMinipool(minipool.Address)
if err != nil {
fmt.Printf("WARNING: Couldn't get gas price for dissolve transaction (%s)", err)
break
} else {
gasInfo = canResponse.GasInfo
totalGas += canResponse.GasInfo.EstGasLimit
totalSafeGas += canResponse.GasInfo.SafeGasLimit
}
}
gasInfo.EstGasLimit = totalGas
gasInfo.SafeGasLimit = totalSafeGas
// Assign max fees
err = gas.AssignMaxFeeAndLimit(gasInfo, rp, c.Bool("yes"))
if err != nil {
return err
}
// Prompt for confirmation
if !(c.Bool("yes") || cliutils.Confirm(fmt.Sprintf("Are you sure you want to dissolve %d minipool(s)? This action cannot be undone!", len(selectedMinipools)))) {
fmt.Println("Cancelled.")
return nil
}
// Dissolve and close minipools
for _, minipool := range selectedMinipools {
response, err := rp.DissolveMinipool(minipool.Address)
if err != nil {
fmt.Printf("Could not dissolve minipool %s: %s.\n", minipool.Address.Hex(), err)
continue
}
fmt.Printf("Dissolving minipool %s...\n", minipool.Address.Hex())
cliutils.PrintTransactionHash(rp, response.TxHash)
if _, err = rp.WaitForTransaction(response.TxHash); err != nil {
fmt.Printf("Could not dissolve minipool %s: %s.\n", minipool.Address.Hex(), err)
continue
} else {
fmt.Printf("Successfully dissolved minipool %s.\n", minipool.Address.Hex())
}
closeResponse, err := rp.CloseMinipool(minipool.Address)
if err != nil {
fmt.Printf("Could not close minipool %s: %s.\n", minipool.Address.Hex(), err)
continue
}
fmt.Printf("Closing minipool %s...\n", minipool.Address.Hex())
cliutils.PrintTransactionHash(rp, closeResponse.TxHash)
if _, err = rp.WaitForTransaction(closeResponse.TxHash); err != nil {
fmt.Printf("Could not close minipool %s: %s.\n", minipool.Address.Hex(), err)
} else {
fmt.Printf("Successfully closed minipool %s.\n", minipool.Address.Hex())
}
}
// Return
return nil
}