Skip to content

Commit 42aa2c5

Browse files
authored
Merge branch 'master' into security/upgrade-critical-dependencies
2 parents e01da2b + 825d826 commit 42aa2c5

28 files changed

+2172
-235
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ coverage.txt
4040
*.log
4141
.editorconfig
4242

43+
.aicontext

action/action.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func FloorDataGas(data []byte) (uint64, error) {
131131
// IsSystemAction determine whether input action belongs to system action
132132
func IsSystemAction(act *SealedEnvelope) bool {
133133
switch act.Action().(type) {
134-
case *GrantReward, *PutPollResult:
134+
case *GrantReward, *PutPollResult, *ScheduleCandidateDeactivation:
135135
return true
136136
default:
137137
return false

action/candidate_activate.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ var (
1717
_ EthCompatibleAction = (*CandidateActivate)(nil)
1818
)
1919

20-
// CandidateActivate is the action to update a candidate's bucket
20+
// CandidateActivate is the action to activate a candidate
2121
type CandidateActivate struct {
2222
stake_common
2323
// bucketID is the bucket index want to be changed to
@@ -42,7 +42,7 @@ func NewCandidateActivate(bucketID uint64) *CandidateActivate {
4242
// BucketID returns the bucket index want to be changed to
4343
func (cr *CandidateActivate) BucketID() uint64 { return cr.bucketID }
4444

45-
// IntrinsicGas returns the intrinsic gas of a CandidateRegister
45+
// IntrinsicGas returns the intrinsic gas of a CandidateActivate
4646
func (cr *CandidateActivate) IntrinsicGas() (uint64, error) {
4747
return CandidateActivateBaseIntrinsicGas, nil
4848
}

action/candidate_deactivate.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package action
2+
3+
import (
4+
"bytes"
5+
6+
"github.com/ethereum/go-ethereum/accounts/abi"
7+
"github.com/iotexproject/iotex-proto/golang/iotextypes"
8+
"github.com/pkg/errors"
9+
)
10+
11+
const (
12+
// CandidateDeactivateBaseIntrinsicGas represents the base intrinsic gas for CandidateActivate
13+
CandidateDeactivateBaseIntrinsicGas = uint64(10000)
14+
15+
// CandidateDeactivateOpRequest is an operation to request deactivation
16+
CandidateDeactivateOpRequest = iota
17+
// CandidateDeactivateOpConfirm is an operation to confirm deactivation
18+
CandidateDeactivateOpConfirm
19+
)
20+
21+
var (
22+
requestCandidateDeactivationMethod abi.Method
23+
cancelCandidateDeactivationMethod abi.Method
24+
confirmCandidateDeactivationMethod abi.Method
25+
_ EthCompatibleAction = (*CandidateDeactivate)(nil)
26+
)
27+
28+
type (
29+
// CandidateDeactivateOp is operation type of candidate deactivation
30+
CandidateDeactivateOp uint8
31+
// CandidateDeactivate is the action to deactivate a candidate
32+
CandidateDeactivate struct {
33+
stake_common
34+
op CandidateDeactivateOp
35+
}
36+
)
37+
38+
func init() {
39+
var ok bool
40+
methods := NativeStakingContractABI().Methods
41+
requestCandidateDeactivationMethod, ok = methods["requestCandidateDeactivation"]
42+
if !ok {
43+
panic("fail to load the requestCandidateDeactivation method")
44+
}
45+
cancelCandidateDeactivationMethod, ok = methods["cancelCandidateDeactivation"]
46+
if !ok {
47+
panic("fail to load the cancelCandidateDeactivation method")
48+
}
49+
}
50+
51+
// NewCandidateDeactivate returns a CandidateDeactivate action
52+
func NewCandidateDeactivate() *CandidateDeactivate {
53+
return &CandidateDeactivate{}
54+
}
55+
56+
// IntrinsicGas returns the intrinsic gas of a CandidateDeactivate
57+
func (cd *CandidateDeactivate) IntrinsicGas() (uint64, error) {
58+
return CandidateActivateBaseIntrinsicGas, nil
59+
}
60+
61+
func (cd *CandidateDeactivate) SanityCheck() error {
62+
return nil
63+
}
64+
65+
func (cd *CandidateDeactivate) FillAction(act *iotextypes.ActionCore) {
66+
act.Action = &iotextypes.ActionCore_CandidateDeactivate{CandidateDeactivate: cd.Proto()}
67+
}
68+
69+
func (cd *CandidateDeactivate) Op() CandidateDeactivateOp {
70+
return cd.op
71+
}
72+
73+
// Proto converts CandidateDeactivate to protobuf's Action
74+
func (cd *CandidateDeactivate) Proto() *iotextypes.CandidateDeactivate {
75+
return &iotextypes.CandidateDeactivate{
76+
Op: uint32(cd.op),
77+
}
78+
}
79+
80+
// LoadProto converts a protobuf's Action to CandidateDeactivate
81+
func (cd *CandidateDeactivate) LoadProto(pbAct *iotextypes.CandidateDeactivate) error {
82+
if pbAct == nil {
83+
return ErrNilProto
84+
}
85+
cd.op = CandidateDeactivateOp(pbAct.GetOp())
86+
return nil
87+
}
88+
89+
// EthData returns the ABI-encoded data for converting to eth tx
90+
func (cd *CandidateDeactivate) EthData() ([]byte, error) {
91+
var method abi.Method
92+
switch cd.op {
93+
case CandidateDeactivateOpRequest:
94+
method = requestCandidateDeactivationMethod
95+
case CandidateDeactivateOpConfirm:
96+
method = confirmCandidateDeactivationMethod
97+
default:
98+
return nil, errors.New("invalid operation")
99+
}
100+
data, err := method.Inputs.Pack()
101+
if err != nil {
102+
return nil, err
103+
}
104+
return append(method.ID, data...), nil
105+
}
106+
107+
// NewCandidateDeactivateFromABIBinary parses the smart contract input and creates an action
108+
func NewCandidateDeactivateFromABIBinary(data []byte) (*CandidateDeactivate, error) {
109+
var cd CandidateDeactivate
110+
// sanity check
111+
switch {
112+
case len(data) <= 4:
113+
return nil, errDecodeFailure
114+
case bytes.Equal(requestCandidateDeactivationMethod.ID, data[:4]):
115+
cd.op = CandidateDeactivateOpRequest
116+
case bytes.Equal(confirmCandidateDeactivationMethod.ID, data[:4]):
117+
cd.op = CandidateDeactivateOpConfirm
118+
default:
119+
return nil, errDecodeFailure
120+
}
121+
122+
return &cd, nil
123+
}

action/candidate_register.go

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,14 @@ const (
3030

3131
var (
3232
// _candidateRegisterInterface is the interface of the abi encoding of stake action
33-
_candidateRegisterMethod abi.Method
34-
_candidateRegisterWithBLSMethod abi.Method
35-
_candidateRegisteredEvent abi.Event
36-
_stakedEvent abi.Event
37-
_candidateActivatedEvent abi.Event
33+
_candidateRegisterMethod abi.Method
34+
_candidateRegisterWithBLSMethod abi.Method
35+
_candidateRegisteredEvent abi.Event
36+
_stakedEvent abi.Event
37+
_candidateActivatedEvent abi.Event
38+
_candidateDeactivationRequestedEvent abi.Event
39+
_candidateDeactivationScheduledEvent abi.Event
40+
_candidateDeactivatedEvent abi.Event
3841

3942
// ErrInvalidAmount represents that amount is 0 or negative
4043
ErrInvalidAmount = errors.New("invalid amount")
@@ -89,6 +92,18 @@ func init() {
8992
if !ok {
9093
panic("fail to load the event")
9194
}
95+
_candidateDeactivationRequestedEvent, ok = abi.Events["CandidateDeactivationRequested"]
96+
if !ok {
97+
panic("fail to load the event")
98+
}
99+
_candidateDeactivationScheduledEvent, ok = abi.Events["CandidateDeactivationScheduled"]
100+
if !ok {
101+
panic("fail to load the event")
102+
}
103+
_candidateDeactivatedEvent, ok = abi.Events["CandidateDeactivated"]
104+
if !ok {
105+
panic("fail to load the event")
106+
}
92107
}
93108

94109
// NewCandidateRegister creates a CandidateRegister instance
@@ -426,6 +441,42 @@ func PackCandidateActivatedEvent(
426441
return topics, data, nil
427442
}
428443

444+
// PackCandidateDeactivationRequestedEvent packs the CandidateDeactivationRequested event
445+
func PackCandidateDeactivationRequestedEvent(candidate address.Address) (Topics, []byte, error) {
446+
data, err := _candidateDeactivationRequestedEvent.Inputs.NonIndexed().Pack()
447+
if err != nil {
448+
return nil, nil, errors.Wrap(err, "failed to pack CandidateDeactivationRequested event")
449+
}
450+
topics := make(Topics, 2)
451+
topics[0] = hash.Hash256(_candidateDeactivationRequestedEvent.ID)
452+
topics[1] = hash.BytesToHash256(candidate.Bytes())
453+
return topics, data, nil
454+
}
455+
456+
// PackCandidateDeactivationScheduledEvent packs the CandidateDeactivationScheduled event
457+
func PackCandidateDeactivationScheduledEvent(candidate address.Address, blkHeight uint64) (Topics, []byte, error) {
458+
data, err := _candidateDeactivationScheduledEvent.Inputs.NonIndexed().Pack(blkHeight)
459+
if err != nil {
460+
return nil, nil, errors.Wrap(err, "failed to pack ScheduleCandidateDeactivation event")
461+
}
462+
topics := make(Topics, 2)
463+
topics[0] = hash.Hash256(_candidateDeactivationScheduledEvent.ID)
464+
topics[1] = hash.BytesToHash256(candidate.Bytes())
465+
return topics, data, nil
466+
}
467+
468+
// PackCandidateDeactivatedEvent packs the CandidateDeactivated event
469+
func PackCandidateDeactivatedEvent(candidate address.Address) (Topics, []byte, error) {
470+
data, err := _candidateDeactivatedEvent.Inputs.NonIndexed().Pack()
471+
if err != nil {
472+
return nil, nil, errors.Wrap(err, "failed to pack CandidateDeactivated event")
473+
}
474+
topics := make(Topics, 2)
475+
topics[0] = hash.Hash256(_candidateDeactivatedEvent.ID)
476+
topics[1] = hash.BytesToHash256(candidate.Bytes())
477+
return topics, data, nil
478+
}
479+
429480
// NewCandidateRegisterFromABIBinary decodes data into CandidateRegister action
430481
func NewCandidateRegisterFromABIBinary(data []byte, value *big.Int) (*CandidateRegister, error) {
431482
var (

action/candidateregister_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,16 @@ func TestStakingEvent(t *testing.T) {
275275
require.NoError(err)
276276
checkActivatedEvent(require, topics, data, cand, bktIdx)
277277
})
278+
t.Run("deactivate", func(t *testing.T) {
279+
topics, data, err := PackCandidateDeactivationRequestedEvent(cand)
280+
require.NoError(err)
281+
paramsNonIndexed, err := _candidateDeactivationRequestedEvent.Inputs.Unpack(data)
282+
require.NoError(err)
283+
require.Equal(0, len(paramsNonIndexed))
284+
require.Equal(2, len(topics))
285+
require.Equal(hash.Hash256(_candidateDeactivationRequestedEvent.ID), topics[0])
286+
require.Equal(hash.BytesToHash256(cand.Bytes()), topics[1])
287+
})
278288
t.Run("update", func(t *testing.T) {
279289
topics, data, err := PackCandidateUpdatedEvent(cand, operator, owner, name, reward, blsPubKey)
280290
require.NoError(err)

action/native_staking_contract_abi.json

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,51 @@
1818
"name": "CandidateActivated",
1919
"type": "event"
2020
},
21+
{
22+
"anonymous": false,
23+
"inputs": [
24+
{
25+
"indexed": true,
26+
"internalType": "address",
27+
"name": "candidate",
28+
"type": "address"
29+
}
30+
],
31+
"name": "CandidateDeactivationRequested",
32+
"type": "event"
33+
},
34+
{
35+
"anonymous": false,
36+
"inputs": [
37+
{
38+
"indexed": true,
39+
"internalType": "address",
40+
"name": "candidate",
41+
"type": "address"
42+
},
43+
{
44+
"indexed": false,
45+
"internalType": "uint64",
46+
"name": "blockNumber",
47+
"type": "uint64"
48+
}
49+
],
50+
"name": "CandidateDeactivationScheduled",
51+
"type": "event"
52+
},
53+
{
54+
"anonymous": false,
55+
"inputs": [
56+
{
57+
"indexed": true,
58+
"internalType": "address",
59+
"name": "candidate",
60+
"type": "address"
61+
}
62+
],
63+
"name": "CandidateDeactivated",
64+
"type": "event"
65+
},
2166
{
2267
"anonymous": false,
2368
"inputs": [
@@ -160,6 +205,20 @@
160205
"stateMutability": "nonpayable",
161206
"type": "function"
162207
},
208+
{
209+
"inputs": [],
210+
"name": "requestCandidateDeactivation",
211+
"outputs": [],
212+
"stateMutability": "nonpayable",
213+
"type": "function"
214+
},
215+
{
216+
"inputs": [],
217+
"name": "cancelCandidateDeactivation",
218+
"outputs": [],
219+
"stateMutability": "nonpayable",
220+
"type": "function"
221+
},
163222
{
164223
"inputs": [
165224
{

action/protocol/context.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ type (
167167
CandidateBLSPublicKeyNotCopied bool
168168
OnlyOwnerCanUpdateBLSPublicKey bool
169169
PrePectraEVM bool
170+
NoCandidateExitQueue bool
170171
}
171172

172173
// FeatureWithHeightCtx provides feature check functions.
@@ -338,6 +339,7 @@ func WithFeatureCtx(ctx context.Context) context.Context {
338339
CandidateBLSPublicKeyNotCopied: !g.IsXinguBeta(height),
339340
OnlyOwnerCanUpdateBLSPublicKey: !g.IsToBeEnabled(height),
340341
PrePectraEVM: !g.IsToBeEnabled(height),
342+
NoCandidateExitQueue: !g.IsToBeEnabled(height),
341343
},
342344
)
343345
}

0 commit comments

Comments
 (0)