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  }