-
Notifications
You must be signed in to change notification settings - Fork 319
/
candidate_activate.go
152 lines (134 loc) · 3.99 KB
/
candidate_activate.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package action
import (
"bytes"
"math/big"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/core/types"
"github.com/iotexproject/iotex-proto/golang/iotextypes"
"github.com/pkg/errors"
"github.com/iotexproject/iotex-core/pkg/version"
)
const (
// CandidateActivateBaseIntrinsicGas represents the base intrinsic gas for CandidateActivate
CandidateActivateBaseIntrinsicGas = uint64(10000)
// TODO: move all parts of staking abi to a unified file
candidateActivateInterfaceABI = `[
{
"inputs": [
{
"internalType": "uint64",
"name": "bucketIndex",
"type": "uint64"
}
],
"name": "candidateActivate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]`
)
var (
candidateActivateMethod abi.Method
)
// CandidateActivate is the action to update a candidate's bucket
type CandidateActivate struct {
AbstractAction
// bucketID is the bucket index want to be changed to
bucketID uint64
}
func init() {
candidateActivateInterface, err := abi.JSON(strings.NewReader(candidateActivateInterfaceABI))
if err != nil {
panic(err)
}
var ok bool
candidateActivateMethod, ok = candidateActivateInterface.Methods["candidateActivate"]
if !ok {
panic("fail to load the candidateActivate method")
}
}
// BucketID returns the bucket index want to be changed to
func (cr *CandidateActivate) BucketID() uint64 { return cr.bucketID }
// IntrinsicGas returns the intrinsic gas of a CandidateRegister
func (cr *CandidateActivate) IntrinsicGas() (uint64, error) {
return CandidateActivateBaseIntrinsicGas, nil
}
// Cost returns the total cost of a CandidateRegister
func (cr *CandidateActivate) Cost() (*big.Int, error) {
intrinsicGas, err := cr.IntrinsicGas()
if err != nil {
return nil, errors.Wrap(err, "failed to get intrinsic gas for the CandidateRegister creates")
}
fee := big.NewInt(0).Mul(cr.GasPrice(), big.NewInt(0).SetUint64(intrinsicGas))
return fee, nil
}
// Proto converts CandidateActivate to protobuf's Action
func (cr *CandidateActivate) Proto() *iotextypes.CandidateActivate {
return &iotextypes.CandidateActivate{
BucketIndex: cr.bucketID,
}
}
// LoadProto converts a protobuf's Action to CandidateActivate
func (cr *CandidateActivate) LoadProto(pbAct *iotextypes.CandidateActivate) error {
if pbAct == nil {
return ErrNilProto
}
cr.bucketID = pbAct.GetBucketIndex()
return nil
}
func (cr *CandidateActivate) encodeABIBinary() ([]byte, error) {
data, err := candidateActivateMethod.Inputs.Pack(cr.bucketID)
if err != nil {
return nil, err
}
return append(candidateActivateMethod.ID, data...), nil
}
// ToEthTx returns an Ethereum transaction which corresponds to this action
func (cr *CandidateActivate) ToEthTx(_ uint32) (*types.Transaction, error) {
data, err := cr.encodeABIBinary()
if err != nil {
return nil, err
}
return types.NewTx(&types.LegacyTx{
Nonce: cr.Nonce(),
GasPrice: cr.GasPrice(),
Gas: cr.GasLimit(),
To: &_stakingProtocolEthAddr,
Value: big.NewInt(0),
Data: data,
}), nil
}
// NewCandidateActivate returns a CandidateActivate action
func NewCandidateActivate(nonce, gasLimit uint64, gasPrice *big.Int, bucketID uint64) *CandidateActivate {
return &CandidateActivate{
AbstractAction: AbstractAction{
version: version.ProtocolVersion,
nonce: nonce,
gasLimit: gasLimit,
gasPrice: gasPrice,
},
bucketID: bucketID,
}
}
// NewCandidateActivateFromABIBinary parses the smart contract input and creates an action
func NewCandidateActivateFromABIBinary(data []byte) (*CandidateActivate, error) {
var (
paramsMap = map[string]any{}
cr CandidateActivate
)
// sanity check
if len(data) <= 4 || !bytes.Equal(candidateActivateMethod.ID, data[:4]) {
return nil, errDecodeFailure
}
if err := candidateActivateMethod.Inputs.UnpackIntoMap(paramsMap, data[4:]); err != nil {
return nil, err
}
bucketID, ok := paramsMap["bucketIndex"].(uint64)
if !ok {
return nil, errDecodeFailure
}
cr.bucketID = bucketID
return &cr, nil
}