This repository was archived by the owner on Jul 8, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.go
More file actions
122 lines (98 loc) · 2.71 KB
/
Copy pathmain.go
File metadata and controls
122 lines (98 loc) · 2.71 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
package main
import (
"context"
"encoding/json"
"flag"
"log"
"os"
"os/exec"
"os/signal"
"regexp"
"strconv"
"sync"
"syscall"
)
var blanceRegex = regexp.MustCompile(`balance: (\d+\.\d+)`)
type Cfg struct {
PactusWalletExecPath string `json:"pactus_wallet_exec_path"`
WalletPath string `json:"wallet_path"`
WalletAddress string `json:"wallet_address"`
Amount float64 `json:"amount"`
Validators []Validator `json:"validators"`
}
type Validator struct {
Address string `json:"address"`
Pub string `json:"pub"`
}
func main() {
cfgPath := flag.String("config", "./cfg.json", "config file path")
password := flag.String("password", "", "pactus wallet password")
rpc := flag.String("server", "", "custom node rpc")
total := flag.Bool("total", false, "determine that all balance of account will be staked")
flag.Parse()
b, err := os.ReadFile(*cfgPath)
if err != nil {
log.Fatal(err)
}
var cfg Cfg
if err := json.Unmarshal(b, &cfg); err != nil {
log.Fatal(err)
}
amount := strconv.FormatFloat(cfg.Amount, 'g', -1, 64)
if *total {
args := make([]string, 0)
args = append(args, "address", "balance", cfg.WalletAddress)
out, err := exec.Command(cfg.PactusWalletExecPath, args...).Output()
if err != nil {
log.Fatalf("err: %s, msg: %s", err.Error(), string(out))
}
match := blanceRegex.FindStringSubmatch(string(out))
if len(match) > 1 {
amount = match[1]
} else {
log.Fatalf("err: can't find the address balance, msg: %s", string(out))
}
}
var wg sync.WaitGroup
ctx, cancel := context.WithCancel(context.Background())
defer func() {
os.Exit(0)
}()
for _, val := range cfg.Validators {
args := make([]string, 0)
args = append(args, "--path", cfg.WalletPath, "tx", "bond")
if len(*password) != 0 {
args = append(args, "-p", *password)
}
args = append(args, cfg.WalletAddress, "--no-confirm", "--pub", val.Pub, val.Address, amount)
if len(*rpc) != 0 {
args = append(args, "--server", *rpc)
}
wg.Add(1)
go runCmd(ctx, cfg.PactusWalletExecPath, val.Address, &wg, args...)
}
go func() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
select {
case s := <-interrupt:
cancel()
log.Printf("staker canceled by user, %s", s.String())
}
}()
wg.Wait()
}
func runCmd(ctx context.Context, pactusWalletExecPath, validator string, wg *sync.WaitGroup, args ...string) {
defer wg.Done()
select {
case <-ctx.Done():
return
default:
out, err := exec.CommandContext(ctx, pactusWalletExecPath, args...).Output()
if err != nil {
log.Printf("validator: %s err: %s, msg: %s", validator, err.Error(), string(out))
return
}
log.Println(string(out))
}
}