Skip to content

Commit

Permalink
[staking] Handling CandidateActivate Action (#4011)
Browse files Browse the repository at this point in the history
  • Loading branch information
envestcc authored Jan 18, 2024
1 parent dbd7a5b commit d4ba76e
Show file tree
Hide file tree
Showing 3 changed files with 532 additions and 0 deletions.
94 changes: 94 additions & 0 deletions action/protocol/staking/handler_candidate_selfstake.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package staking

import (
"context"
"math"

"github.com/iotexproject/iotex-proto/golang/iotextypes"
"github.com/pkg/errors"

"github.com/iotexproject/iotex-core/action"
"github.com/iotexproject/iotex-core/action/protocol"
"github.com/iotexproject/iotex-core/pkg/util/byteutil"
)

const (
handleCandidateActivate = "candidateActivate"

candidateNoSelfStakeBucketIndex = math.MaxUint64
)

func (p *Protocol) handleCandidateActivate(ctx context.Context, act *action.CandidateActivate, csm CandidateStateManager,
) (*receiptLog, []*action.TransactionLog, error) {
actCtx := protocol.MustGetActionCtx(ctx)
featureCtx := protocol.MustGetFeatureCtx(ctx)
log := newReceiptLog(p.addr.String(), handleCandidateActivate, featureCtx.NewStakingReceiptFormat)

bucket, rErr := p.fetchBucket(csm, act.BucketID())
if rErr != nil {
return log, nil, rErr
}
// caller must be the owner of a candidate
cand := csm.GetByOwner(actCtx.Caller)
if cand == nil {
return log, nil, errCandNotExist
}

if err := p.validateBucketSelfStake(ctx, csm, NewEndorsementStateManager(csm.SM()), bucket, cand); err != nil {
return log, nil, err
}

log.AddTopics(byteutil.Uint64ToBytesBigEndian(bucket.Index), bucket.Candidate.Bytes())
// convert previous self-stake bucket to vote bucket
if cand.SelfStake.Sign() > 0 {
prevBucket, err := p.fetchBucket(csm, cand.SelfStakeBucketIdx)
if err != nil {
return log, nil, err
}
if err := cand.SubVote(p.calculateVoteWeight(prevBucket, true)); err != nil {
return log, nil, err
}
if err := cand.AddVote(p.calculateVoteWeight(prevBucket, false)); err != nil {
return log, nil, err
}
}

// convert vote bucket to self-stake bucket
cand.SelfStakeBucketIdx = bucket.Index
cand.SelfStake.SetBytes(bucket.StakedAmount.Bytes())
if err := cand.SubVote(p.calculateVoteWeight(bucket, false)); err != nil {
return log, nil, err
}
if err := cand.AddVote(p.calculateVoteWeight(bucket, true)); err != nil {
return log, nil, err
}

if err := csm.Upsert(cand); err != nil {
return log, nil, csmErrorToHandleError(cand.Owner.String(), err)
}
return log, nil, nil
}

func (p *Protocol) validateBucketSelfStake(ctx context.Context, csm CandidateStateManager, esm *EndorsementStateManager, bucket *VoteBucket, cand *Candidate) ReceiptError {
blkCtx := protocol.MustGetBlockCtx(ctx)
if err := validateBucketMinAmount(bucket, p.config.RegistrationConsts.MinSelfStake); err != nil {
return err
}
if err := validateBucketStake(bucket, true); err != nil {
return err
}
if err := validateBucketSelfStake(csm, bucket, false); err != nil {
return err
}
if err := validateBucketCandidate(bucket, cand.Owner); err != nil {
return err
}
if validateBucketOwner(bucket, cand.Owner) != nil &&
validateBucketEndorsement(esm, bucket, true, blkCtx.BlockHeight) != nil {
return &handleError{
err: errors.New("bucket is not a self-owned or endorsed bucket"),
failureStatus: iotextypes.ReceiptStatus_ErrUnauthorizedOperator,
}
}
return nil
}
Loading

0 comments on commit d4ba76e

Please sign in to comment.