github.com/Finschia/finschia-sdk@v0.48.1/x/foundation/keeper/internal/member.go (about) 1 package internal 2 3 import ( 4 sdk "github.com/Finschia/finschia-sdk/types" 5 sdkerrors "github.com/Finschia/finschia-sdk/types/errors" 6 authtypes "github.com/Finschia/finschia-sdk/x/auth/types" 7 "github.com/Finschia/finschia-sdk/x/foundation" 8 govtypes "github.com/Finschia/finschia-sdk/x/gov/types" 9 ) 10 11 func validateMetadata(metadata string, config foundation.Config) error { 12 if len(metadata) > int(config.MaxMetadataLen) { 13 return sdkerrors.ErrInvalidRequest.Wrap("metadata is too large") 14 } 15 16 return nil 17 } 18 19 func (k Keeper) UpdateDecisionPolicy(ctx sdk.Context, policy foundation.DecisionPolicy) error { 20 info := k.GetFoundationInfo(ctx) 21 if err := info.SetDecisionPolicy(policy); err != nil { 22 return err 23 } 24 info.Version++ 25 k.SetFoundationInfo(ctx, info) 26 27 if err := policy.Validate(info, k.config); err != nil { 28 return err 29 } 30 31 // invalidate active proposals 32 k.abortOldProposals(ctx) 33 34 return nil 35 } 36 37 func (k Keeper) GetFoundationInfo(ctx sdk.Context) foundation.FoundationInfo { 38 store := ctx.KVStore(k.storeKey) 39 bz := store.Get(foundationInfoKey) 40 if len(bz) == 0 { 41 panic("the foundation info must have been registered") 42 } 43 44 var info foundation.FoundationInfo 45 k.cdc.MustUnmarshal(bz, &info) 46 return info 47 } 48 49 func (k Keeper) SetFoundationInfo(ctx sdk.Context, info foundation.FoundationInfo) { 50 store := ctx.KVStore(k.storeKey) 51 bz := k.cdc.MustMarshal(&info) 52 store.Set(foundationInfoKey, bz) 53 } 54 55 func (k Keeper) UpdateMembers(ctx sdk.Context, members []foundation.MemberRequest) error { 56 weightUpdate := sdk.ZeroDec() 57 for _, request := range members { 58 new := foundation.Member{ 59 Address: request.Address, 60 Metadata: request.Metadata, 61 AddedAt: ctx.BlockTime(), 62 } 63 if err := new.ValidateBasic(); err != nil { 64 panic(err) 65 } 66 if err := validateMetadata(new.Metadata, k.config); err != nil { 67 return err 68 } 69 70 addr := sdk.MustAccAddressFromBech32(new.Address) 71 old, err := k.GetMember(ctx, addr) 72 if err != nil && request.Remove { // the member must exist 73 return err 74 } 75 if err == nil { // overwrite 76 weightUpdate = weightUpdate.Sub(sdk.OneDec()) 77 new.AddedAt = old.AddedAt 78 } 79 80 if request.Remove { 81 k.deleteMember(ctx, addr) 82 } else { 83 weightUpdate = weightUpdate.Add(sdk.OneDec()) 84 k.SetMember(ctx, new) 85 } 86 } 87 88 info := k.GetFoundationInfo(ctx) 89 info.TotalWeight = info.TotalWeight.Add(weightUpdate) 90 info.Version++ 91 k.SetFoundationInfo(ctx, info) 92 93 if err := info.GetDecisionPolicy().Validate(info, k.config); err != nil { 94 return err 95 } 96 97 // invalidate active proposals 98 k.abortOldProposals(ctx) 99 100 return nil 101 } 102 103 func (k Keeper) GetMember(ctx sdk.Context, address sdk.AccAddress) (*foundation.Member, error) { 104 store := ctx.KVStore(k.storeKey) 105 key := memberKey(address) 106 bz := store.Get(key) 107 if len(bz) == 0 { 108 return nil, sdkerrors.ErrNotFound.Wrapf("No such member: %s", address) 109 } 110 111 var member foundation.Member 112 k.cdc.MustUnmarshal(bz, &member) 113 114 return &member, nil 115 } 116 117 func (k Keeper) SetMember(ctx sdk.Context, member foundation.Member) { 118 store := ctx.KVStore(k.storeKey) 119 addr := sdk.MustAccAddressFromBech32(member.Address) 120 key := memberKey(addr) 121 122 bz := k.cdc.MustMarshal(&member) 123 store.Set(key, bz) 124 } 125 126 func (k Keeper) deleteMember(ctx sdk.Context, address sdk.AccAddress) { 127 store := ctx.KVStore(k.storeKey) 128 key := memberKey(address) 129 store.Delete(key) 130 } 131 132 func (k Keeper) iterateMembers(ctx sdk.Context, fn func(member foundation.Member) (stop bool)) { 133 store := ctx.KVStore(k.storeKey) 134 prefix := memberKeyPrefix 135 iterator := sdk.KVStorePrefixIterator(store, prefix) 136 defer iterator.Close() 137 138 for ; iterator.Valid(); iterator.Next() { 139 var member foundation.Member 140 k.cdc.MustUnmarshal(iterator.Value(), &member) 141 if stop := fn(member); stop { 142 break 143 } 144 } 145 } 146 147 func (k Keeper) GetMembers(ctx sdk.Context) []foundation.Member { 148 var members []foundation.Member 149 k.iterateMembers(ctx, func(member foundation.Member) (stop bool) { 150 members = append(members, member) 151 return false 152 }) 153 154 return members 155 } 156 157 func (k Keeper) validateAuthority(authority string) error { 158 if authority != k.authority { 159 return sdkerrors.ErrUnauthorized.Wrapf("invalid authority; expected %s, got %s", k.authority, authority) 160 } 161 162 return nil 163 } 164 165 func (k Keeper) validateCensorshipAuthority(ctx sdk.Context, msgTypeURL string, authority string) error { 166 censorship, err := k.GetCensorship(ctx, msgTypeURL) 167 if err != nil { 168 return err 169 } 170 171 authorityAddrs := map[foundation.CensorshipAuthority]string{ 172 foundation.CensorshipAuthorityGovernance: authtypes.NewModuleAddress(govtypes.ModuleName).String(), 173 foundation.CensorshipAuthorityFoundation: k.authority, 174 } 175 if expected := authorityAddrs[censorship.Authority]; authority != expected { 176 return sdkerrors.ErrUnauthorized.Wrapf("invalid authority; expected %s, got %s", expected, authority) 177 } 178 179 return nil 180 } 181 182 func (k Keeper) validateMembers(ctx sdk.Context, members []string) error { 183 for _, member := range members { 184 addr := sdk.MustAccAddressFromBech32(member) 185 if _, err := k.GetMember(ctx, addr); err != nil { 186 return sdkerrors.ErrUnauthorized.Wrapf("%s is not a member", member) 187 } 188 } 189 190 return nil 191 }