github.com/iotexproject/iotex-core@v1.14.1-rc1/action/protocol/staking/read_state.go (about) 1 // Copyright (c) 2020 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package staking 7 8 import ( 9 "context" 10 "math/big" 11 12 "github.com/iotexproject/iotex-proto/golang/iotextypes" 13 "github.com/pkg/errors" 14 15 "github.com/iotexproject/iotex-core/action/protocol" 16 "github.com/iotexproject/iotex-core/state" 17 ) 18 19 func toIoTeXTypesVoteBucketList(sr protocol.StateReader, buckets []*VoteBucket) (*iotextypes.VoteBucketList, error) { 20 esr := NewEndorsementStateReader(sr) 21 res := iotextypes.VoteBucketList{ 22 Buckets: make([]*iotextypes.VoteBucket, 0, len(buckets)), 23 } 24 for _, b := range buckets { 25 typBucket, err := b.toIoTeXTypes() 26 if err != nil { 27 return nil, err 28 } 29 // fill in the endorsement 30 if b.isNative() { 31 endorsement, err := esr.Get(b.Index) 32 switch errors.Cause(err) { 33 case nil: 34 typBucket.EndorsementExpireBlockHeight = endorsement.ExpireHeight 35 case state.ErrStateNotExist: 36 default: 37 return nil, err 38 } 39 } 40 res.Buckets = append(res.Buckets, typBucket) 41 } 42 return &res, nil 43 } 44 45 func getPageOfArray[T any](array []T, offset, limit int) []T { 46 var res []T 47 if offset >= len(array) { 48 return res 49 } 50 array = array[offset:] 51 if limit > len(array) { 52 limit = len(array) 53 } 54 res = make([]T, 0, limit) 55 for i := 0; i < limit; i++ { 56 res = append(res, array[i]) 57 } 58 return res 59 } 60 61 func getPageOfBuckets(buckets []*VoteBucket, offset, limit int) []*VoteBucket { 62 return getPageOfArray(buckets, offset, limit) 63 } 64 65 func toIoTeXTypesCandidateListV2(candidates CandidateList) *iotextypes.CandidateListV2 { 66 res := iotextypes.CandidateListV2{ 67 Candidates: make([]*iotextypes.CandidateV2, 0, len(candidates)), 68 } 69 for _, c := range candidates { 70 res.Candidates = append(res.Candidates, c.toIoTeXTypes()) 71 } 72 return &res 73 } 74 75 func getPageOfCandidates(candidates CandidateList, offset, limit int) CandidateList { 76 return getPageOfArray(candidates, offset, limit) 77 } 78 79 func getTotalStakedAmount(ctx context.Context, csr CandidateStateReader) (*big.Int, uint64, error) { 80 featureCtx := protocol.MustGetFeatureWithHeightCtx(ctx) 81 if featureCtx.ReadStateFromDB(csr.Height()) { 82 // after Greenland, read state from db 83 var total totalAmount 84 h, err := csr.SR().State(&total, protocol.NamespaceOption(_stakingNameSpace), protocol.KeyOption(_bucketPoolAddrKey)) 85 if err != nil { 86 return nil, h, err 87 } 88 return total.amount, h, nil 89 } 90 91 // otherwise read from bucket pool 92 return csr.TotalStakedAmount(), csr.Height(), nil 93 } 94 95 func getActiveBucketsCount(ctx context.Context, csr CandidateStateReader) (uint64, uint64, error) { 96 featureCtx := protocol.MustGetFeatureWithHeightCtx(ctx) 97 if featureCtx.ReadStateFromDB(csr.Height()) { 98 // after Greenland, read state from db 99 var total totalAmount 100 h, err := csr.SR().State(&total, protocol.NamespaceOption(_stakingNameSpace), protocol.KeyOption(_bucketPoolAddrKey)) 101 if err != nil { 102 return 0, h, err 103 } 104 return total.count, h, nil 105 } 106 // otherwise read from bucket pool 107 return csr.ActiveBucketsCount(), csr.Height(), nil 108 }