github.com/Finschia/finschia-sdk@v0.48.1/x/foundation/keeper/internal/censorship.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 "github.com/Finschia/finschia-sdk/x/foundation" 7 ) 8 9 func (k Keeper) GetCensorship(ctx sdk.Context, msgTypeURL string) (*foundation.Censorship, error) { 10 store := ctx.KVStore(k.storeKey) 11 key := censorshipKey(msgTypeURL) 12 bz := store.Get(key) 13 if bz == nil { 14 return nil, sdkerrors.ErrNotFound.Wrap("censorship not found") 15 } 16 17 var censorship foundation.Censorship 18 k.cdc.MustUnmarshal(bz, &censorship) 19 20 return &censorship, nil 21 } 22 23 func (k Keeper) UpdateCensorship(ctx sdk.Context, censorship foundation.Censorship) error { 24 url := censorship.MsgTypeUrl 25 26 oldCensorship, err := k.GetCensorship(ctx, url) 27 if err != nil { 28 return err 29 } 30 31 newAuthority := censorship.Authority 32 oldAuthority := oldCensorship.Authority 33 if newAuthority >= oldAuthority { 34 return sdkerrors.ErrInvalidRequest.Wrapf("bad transition; %s -> %s over %s", oldAuthority, newAuthority, url) 35 } 36 37 // clean up relevant authorizations 38 if newAuthority == foundation.CensorshipAuthorityUnspecified { 39 k.pruneAuthorizations(ctx, url) 40 } 41 42 k.SetCensorship(ctx, censorship) 43 44 return nil 45 } 46 47 func (k Keeper) SetCensorship(ctx sdk.Context, censorship foundation.Censorship) { 48 store := ctx.KVStore(k.storeKey) 49 key := censorshipKey(censorship.MsgTypeUrl) 50 51 if censorship.Authority == foundation.CensorshipAuthorityUnspecified { 52 store.Delete(key) 53 return 54 } 55 56 bz := k.cdc.MustMarshal(&censorship) 57 store.Set(key, bz) 58 } 59 60 func (k Keeper) iterateCensorships(ctx sdk.Context, fn func(censorship foundation.Censorship) (stop bool)) { 61 store := ctx.KVStore(k.storeKey) 62 iterator := sdk.KVStorePrefixIterator(store, censorshipKeyPrefix) 63 defer iterator.Close() 64 65 for ; iterator.Valid(); iterator.Next() { 66 var censorship foundation.Censorship 67 k.cdc.MustUnmarshal(iterator.Value(), &censorship) 68 69 if stop := fn(censorship); stop { 70 break 71 } 72 } 73 } 74 75 func (k Keeper) Grant(ctx sdk.Context, grantee sdk.AccAddress, authorization foundation.Authorization) error { 76 msgTypeURL := authorization.MsgTypeURL() 77 if !k.IsCensoredMessage(ctx, msgTypeURL) { 78 return sdkerrors.ErrInvalidRequest.Wrapf("%s is not being censored", msgTypeURL) 79 } 80 81 if _, err := k.GetAuthorization(ctx, grantee, msgTypeURL); err == nil { 82 return sdkerrors.ErrInvalidRequest.Wrapf("authorization for %s already exists", msgTypeURL) 83 } 84 85 k.setAuthorization(ctx, grantee, authorization) 86 87 any, err := foundation.SetAuthorization(authorization) 88 if err != nil { 89 return err 90 } 91 92 if err := ctx.EventManager().EmitTypedEvent(&foundation.EventGrant{ 93 Grantee: grantee.String(), 94 Authorization: any, 95 }); err != nil { 96 panic(err) 97 } 98 99 return nil 100 } 101 102 func (k Keeper) Revoke(ctx sdk.Context, grantee sdk.AccAddress, msgTypeURL string) error { 103 if _, err := k.GetAuthorization(ctx, grantee, msgTypeURL); err != nil { 104 return err 105 } 106 k.deleteAuthorization(ctx, grantee, msgTypeURL) 107 108 if err := ctx.EventManager().EmitTypedEvent(&foundation.EventRevoke{ 109 Grantee: grantee.String(), 110 MsgTypeUrl: msgTypeURL, 111 }); err != nil { 112 panic(err) 113 } 114 115 return nil 116 } 117 118 func (k Keeper) pruneAuthorizations(ctx sdk.Context, msgTypeURL string) { 119 var pruning []foundation.GrantAuthorization 120 k.iterateAuthorizations(ctx, func(grantee sdk.AccAddress, authorization foundation.Authorization) (stop bool) { 121 if authorization.MsgTypeURL() == msgTypeURL { 122 grant := foundation.GrantAuthorization{ 123 Grantee: grantee.String(), 124 }.WithAuthorization(authorization) 125 126 pruning = append(pruning, *grant) 127 } 128 return false 129 }) 130 131 for _, grant := range pruning { 132 k.deleteAuthorization(ctx, sdk.MustAccAddressFromBech32(grant.Grantee), grant.GetAuthorization().MsgTypeURL()) 133 } 134 } 135 136 func (k Keeper) GetAuthorization(ctx sdk.Context, grantee sdk.AccAddress, msgTypeURL string) (foundation.Authorization, error) { 137 store := ctx.KVStore(k.storeKey) 138 key := grantKey(grantee, msgTypeURL) 139 bz := store.Get(key) 140 if bz == nil { 141 return nil, sdkerrors.ErrUnauthorized.Wrap("authorization not found") 142 } 143 144 var auth foundation.Authorization 145 if err := k.cdc.UnmarshalInterface(bz, &auth); err != nil { 146 panic(err) 147 } 148 149 return auth, nil 150 } 151 152 func (k Keeper) setAuthorization(ctx sdk.Context, grantee sdk.AccAddress, authorization foundation.Authorization) { 153 store := ctx.KVStore(k.storeKey) 154 key := grantKey(grantee, authorization.MsgTypeURL()) 155 156 bz, err := k.cdc.MarshalInterface(authorization) 157 if err != nil { 158 panic(err) 159 } 160 store.Set(key, bz) 161 } 162 163 func (k Keeper) deleteAuthorization(ctx sdk.Context, grantee sdk.AccAddress, msgTypeURL string) { 164 store := ctx.KVStore(k.storeKey) 165 key := grantKey(grantee, msgTypeURL) 166 store.Delete(key) 167 } 168 169 func (k Keeper) Accept(ctx sdk.Context, grantee sdk.AccAddress, msg sdk.Msg) error { 170 msgTypeURL := sdk.MsgTypeURL(msg) 171 172 // check whether the msg is being censored 173 if !k.IsCensoredMessage(ctx, msgTypeURL) { 174 return nil 175 } 176 177 authorization, err := k.GetAuthorization(ctx, grantee, msgTypeURL) 178 if err != nil { 179 return err 180 } 181 182 resp, err := authorization.Accept(ctx, msg) 183 if err != nil { 184 return err 185 } 186 187 if resp.Delete { 188 k.deleteAuthorization(ctx, grantee, msgTypeURL) 189 } else if resp.Updated != nil { 190 k.setAuthorization(ctx, grantee, resp.Updated) 191 } 192 193 if !resp.Accept { 194 return sdkerrors.ErrUnauthorized 195 } 196 197 return nil 198 } 199 200 func (k Keeper) iterateAuthorizations(ctx sdk.Context, fn func(grantee sdk.AccAddress, authorization foundation.Authorization) (stop bool)) { 201 k.iterateAuthorizationsImpl(ctx, grantKeyPrefix, fn) 202 } 203 204 func (k Keeper) iterateAuthorizationsImpl(ctx sdk.Context, prefix []byte, fn func(grantee sdk.AccAddress, authorization foundation.Authorization) (stop bool)) { 205 store := ctx.KVStore(k.storeKey) 206 iterator := sdk.KVStorePrefixIterator(store, prefix) 207 defer iterator.Close() 208 209 for ; iterator.Valid(); iterator.Next() { 210 var authorization foundation.Authorization 211 if err := k.cdc.UnmarshalInterface(iterator.Value(), &authorization); err != nil { 212 panic(err) 213 } 214 215 grantee, _ := splitGrantKey(iterator.Key()) 216 if stop := fn(grantee, authorization); stop { 217 break 218 } 219 } 220 }