/
withdraw.go
131 lines (104 loc) · 3.25 KB
/
withdraw.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
129
130
131
package withdraw
import (
"fmt"
"time"
"github.com/spf13/cobra"
"github.com/umbracle/ethgo"
"github.com/0xPolygon/polygon-edge/command"
"github.com/0xPolygon/polygon-edge/command/bridge/common"
"github.com/0xPolygon/polygon-edge/command/helper"
"github.com/0xPolygon/polygon-edge/command/polybftsecrets"
rootHelper "github.com/0xPolygon/polygon-edge/command/rootchain/helper"
sidechainHelper "github.com/0xPolygon/polygon-edge/command/sidechain"
"github.com/0xPolygon/polygon-edge/consensus/polybft/contractsapi"
"github.com/0xPolygon/polygon-edge/contracts"
"github.com/0xPolygon/polygon-edge/txrelayer"
"github.com/0xPolygon/polygon-edge/types"
)
var params withdrawParams
func GetCommand() *cobra.Command {
unstakeCmd := &cobra.Command{
Use: "withdraw-child",
Short: "Withdraws pending withdrawals on child chain for given validator",
PreRunE: runPreRun,
RunE: runCommand,
}
helper.RegisterJSONRPCFlag(unstakeCmd)
setFlags(unstakeCmd)
return unstakeCmd
}
func setFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(
¶ms.accountDir,
polybftsecrets.AccountDirFlag,
"",
polybftsecrets.AccountDirFlagDesc,
)
cmd.Flags().StringVar(
¶ms.accountConfig,
polybftsecrets.AccountConfigFlag,
"",
polybftsecrets.AccountConfigFlagDesc,
)
cmd.MarkFlagsMutuallyExclusive(polybftsecrets.AccountDirFlag, polybftsecrets.AccountConfigFlag)
}
func runPreRun(cmd *cobra.Command, _ []string) error {
params.jsonRPC = helper.GetJSONRPCAddress(cmd)
return params.validateFlags()
}
func runCommand(cmd *cobra.Command, _ []string) error {
outputter := command.InitializeOutputter(cmd)
defer outputter.WriteOutput()
validatorAccount, err := sidechainHelper.GetAccount(params.accountDir, params.accountConfig)
if err != nil {
return err
}
txRelayer, err := txrelayer.NewTxRelayer(txrelayer.WithIPAddress(params.jsonRPC),
txrelayer.WithReceiptTimeout(150*time.Millisecond))
if err != nil {
return err
}
encoded, err := contractsapi.ValidatorSet.Abi.Methods["withdraw"].Encode([]interface{}{})
if err != nil {
return err
}
receiver := (*ethgo.Address)(&contracts.ValidatorSetContract)
txn := rootHelper.CreateTransaction(validatorAccount.Ecdsa.Address(), receiver, encoded, nil, false)
receipt, err := txRelayer.SendTransaction(txn, validatorAccount.Ecdsa)
if err != nil {
return err
}
if receipt.Status != uint64(types.ReceiptSuccess) {
return fmt.Errorf("withdraw transaction failed on block: %d", receipt.BlockNumber)
}
var (
withdrawalEvent contractsapi.WithdrawalEvent
foundLog bool
)
// check the logs to check for the result
for _, log := range receipt.Logs {
doesMatch, err := withdrawalEvent.ParseLog(log)
if err != nil {
return err
}
if doesMatch {
foundLog = true
break
}
}
if !foundLog {
return fmt.Errorf("could not find an appropriate log in receipt that withdraw happened on ValidatorSet")
}
exitEventIDs, err := common.ExtractExitEventIDs(receipt)
if err != nil {
return fmt.Errorf("withdrawal failed: %w", err)
}
outputter.WriteCommandResult(
&withdrawResult{
ValidatorAddress: validatorAccount.Ecdsa.Address().String(),
Amount: withdrawalEvent.Amount,
ExitEventIDs: exitEventIDs,
BlockNumber: receipt.BlockNumber,
})
return nil
}