github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/staking/keeper/proxy.go (about) 1 package keeper 2 3 import ( 4 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 5 "github.com/fibonacci-chain/fbc/x/staking/types" 6 ) 7 8 // ClearProxy clears the ProxyAddress on the delegator who has bound 9 func (k Keeper) ClearProxy(ctx sdk.Context, proxyAddr sdk.AccAddress) { 10 k.IterateProxy(ctx, proxyAddr, true, func(_ int64, delAddr, _ sdk.AccAddress) (stop bool) { 11 delegator, found := k.GetDelegator(ctx, delAddr) 12 if found { 13 delegator.UnbindProxy() 14 k.SetDelegator(ctx, delegator) 15 } 16 return false 17 }) 18 } 19 20 // SetProxyBinding sets or deletes the key of proxy relationship 21 func (k Keeper) SetProxyBinding(ctx sdk.Context, proxyAddress, delegatorAddress sdk.AccAddress, isRemove bool) { 22 store := ctx.KVStore(k.storeKey) 23 key := types.GetProxyDelegatorKey(proxyAddress, delegatorAddress) 24 25 if isRemove { 26 store.Delete(key) 27 } else { 28 store.Set(key, []byte("")) 29 } 30 } 31 32 // IterateProxy iterates all the info between delegator and its proxy 33 func (k Keeper) IterateProxy(ctx sdk.Context, proxyAddr sdk.AccAddress, isClear bool, 34 fn func(index int64, delAddr, proxyAddr sdk.AccAddress) (stop bool)) { 35 store := ctx.KVStore(k.storeKey) 36 iterator := sdk.KVStorePrefixIterator(store, types.GetProxyDelegatorKey(proxyAddr, []byte{})) 37 defer iterator.Close() 38 39 index := sdk.AddrLen + 1 40 for i := int64(0); iterator.Valid(); iterator.Next() { 41 key := iterator.Key() 42 if stop := fn(i, key[index:], key[1:index]); stop { 43 break 44 } 45 if isClear { 46 store.Delete(key) 47 } 48 i++ 49 } 50 } 51 52 // UpdateShares withdraws and adds shares continuously on the same validator set with different amount of shares 53 func (k Keeper) UpdateShares(ctx sdk.Context, delAddr sdk.AccAddress, tokens sdk.Dec) error { 54 // get last validators that were added shares to and existing in the store 55 vals, lastShares := k.GetLastValsAddedSharesExisted(ctx, delAddr) 56 if vals == nil { 57 // if the delegator never adds shares, just pass 58 return nil 59 } 60 delegatorValAddresses := vals.ToValAddresses() 61 // withdraw delegation rewards, increments period, remove delegator starting info 62 k.BeforeDelegationSharesModified(ctx, delAddr, delegatorValAddresses) 63 64 lenVals := len(vals) 65 shares, sdkErr := calculateWeight(ctx.BlockTime().Unix(), tokens) 66 if sdkErr != nil { 67 return sdkErr 68 } 69 70 delegator, found := k.GetDelegator(ctx, delAddr) 71 if !found { 72 return types.ErrNoDelegatorExisted(delAddr.String()) 73 } 74 75 for i := 0; i < lenVals; i++ { 76 if vals[i].MinSelfDelegation.IsZero() { 77 return types.ErrAddSharesToDismission(vals[i].OperatorAddress.String()) 78 } 79 80 // 1.delete related store 81 k.DeleteValidatorByPowerIndex(ctx, vals[i]) 82 83 // 2.update shares 84 k.SetShares(ctx, delAddr, vals[i].OperatorAddress, shares) 85 86 // 3.update validator 87 vals[i].DelegatorShares = vals[i].DelegatorShares.Sub(lastShares).Add(shares) 88 k.SetValidator(ctx, vals[i]) 89 k.SetValidatorByPowerIndex(ctx, vals[i]) 90 } 91 92 // update the delegator struct 93 delegator.Shares = shares 94 k.SetDelegator(ctx, delegator) 95 96 // initialize starting info for a new delegation 97 k.AfterDelegationModified(ctx, delegator.DelegatorAddress, delegatorValAddresses) 98 99 return nil 100 } 101 102 // AddSharesToValidators adds shares to validators and return the amount of the shares 103 func (k Keeper) AddSharesToValidators(ctx sdk.Context, delAddr sdk.AccAddress, vals types.Validators, tokens sdk.Dec) ( 104 shares types.Shares, sdkErr error) { 105 lenVals := len(vals) 106 shares, sdkErr = calculateWeight(ctx.BlockTime().Unix(), tokens) 107 if sdkErr != nil { 108 return 109 } 110 for i := 0; i < lenVals; i++ { 111 k.addShares(ctx, delAddr, vals[i], shares) 112 } 113 return 114 } 115 116 // WithdrawLastShares withdraws the shares last time from the validators 117 func (k Keeper) WithdrawLastShares(ctx sdk.Context, delAddr sdk.AccAddress, lastValsAddedSharesTo types.Validators, 118 lastShares types.Shares) { 119 lenLastVals := len(lastValsAddedSharesTo) 120 if lenLastVals > 0 { 121 // withdraw delegation rewards, remove delegator starting info 122 k.BeforeDelegationSharesModified(ctx, delAddr, lastValsAddedSharesTo.ToValAddresses()) 123 } 124 125 for i := 0; i < lenLastVals; i++ { 126 k.withdrawShares(ctx, delAddr, lastValsAddedSharesTo[i], lastShares) 127 } 128 } 129 130 func (k Keeper) withdrawShares(ctx sdk.Context, delAddr sdk.AccAddress, val types.Validator, shares types.Shares) { 131 // 1.delete shares entity 132 k.DeleteShares(ctx, val.OperatorAddress, delAddr) 133 134 // 2.update validator entity 135 k.DeleteValidatorByPowerIndex(ctx, val) 136 137 // 3.update validator's shares 138 val.DelegatorShares = val.GetDelegatorShares().Sub(shares) 139 140 // 3.check whether the validator should be removed 141 if val.IsUnbonded() && val.GetMinSelfDelegation().IsZero() && val.GetDelegatorShares().IsZero() { 142 k.RemoveValidator(ctx, val.OperatorAddress) 143 return 144 } 145 146 k.SetValidator(ctx, val) 147 k.SetValidatorByPowerIndex(ctx, val) 148 } 149 150 func (k Keeper) addShares(ctx sdk.Context, delAddr sdk.AccAddress, val types.Validator, shares types.Shares) { 151 // 1.update shares entity 152 k.SetShares(ctx, delAddr, val.OperatorAddress, shares) 153 154 // 2.update validator entity 155 k.DeleteValidatorByPowerIndex(ctx, val) 156 val.DelegatorShares = val.GetDelegatorShares().Add(shares) 157 k.SetValidator(ctx, val) 158 k.SetValidatorByPowerIndex(ctx, val) 159 } 160 161 // GetLastValsAddedSharesExisted gets last validators that the delegator added shares to last time 162 func (k Keeper) GetLastValsAddedSharesExisted(ctx sdk.Context, delAddr sdk.AccAddress) (types.Validators, types.Shares) { 163 // 1.get delegator entity 164 delegator, found := k.GetDelegator(ctx, delAddr) 165 166 // if not found 167 if !found { 168 return nil, sdk.ZeroDec() 169 } 170 171 // 2.get validators that were added shares to and existing in the store 172 lenVals := len(delegator.ValidatorAddresses) 173 var vals types.Validators 174 for i := 0; i < lenVals; i++ { 175 val, found := k.GetValidator(ctx, delegator.ValidatorAddresses[i]) 176 if found { 177 // the validator that were added shares to hasn't been removed 178 vals = append(vals, val) 179 } 180 } 181 182 return vals, delegator.Shares 183 } 184 185 // GetValidatorsToAddShares gets the validators from their validator addresses 186 func (k Keeper) GetValidatorsToAddShares(ctx sdk.Context, valAddrs []sdk.ValAddress) (types.Validators, error) { 187 lenVals := len(valAddrs) 188 vals := make(types.Validators, lenVals) 189 for i := 0; i < lenVals; i++ { 190 val, found := k.GetValidator(ctx, valAddrs[i]) 191 if found { 192 // get the validator hasn't been removed 193 vals[i] = val 194 } else { 195 return nil, types.ErrNoValidatorFound(valAddrs[i].String()) 196 } 197 } 198 199 return vals, nil 200 }