github.com/Finschia/finschia-sdk@v0.49.1/x/fbridge/keeper/keeper.go (about) 1 package keeper 2 3 import ( 4 "encoding/binary" 5 "errors" 6 "fmt" 7 8 "github.com/Finschia/ostracon/libs/log" 9 10 "github.com/Finschia/finschia-sdk/codec" 11 sdk "github.com/Finschia/finschia-sdk/types" 12 "github.com/Finschia/finschia-sdk/x/fbridge/types" 13 ) 14 15 type Keeper struct { 16 storeKey sdk.StoreKey 17 memKey sdk.StoreKey 18 cdc codec.BinaryCodec 19 authKeeper types.AccountKeeper 20 bankKeeper types.BankKeeper 21 22 // authority can give a role to a specific address like guardian 23 authority string 24 } 25 26 func NewKeeper( 27 cdc codec.BinaryCodec, 28 key, memKey sdk.StoreKey, 29 authKeeper types.AccountKeeper, 30 bankKeeper types.BankKeeper, 31 authority string, 32 ) Keeper { 33 if addr := authKeeper.GetModuleAddress(types.ModuleName); addr == nil { 34 panic(errors.New("fbridge module account has not been set")) 35 } 36 37 found := false 38 for _, addr := range types.AuthorityCandiates() { 39 if authority == addr.String() { 40 found = true 41 break 42 } 43 } 44 45 if !found { 46 panic("x/bridge authority must be the gov or foundation module account") 47 } 48 49 return Keeper{ 50 storeKey: key, 51 memKey: memKey, 52 cdc: cdc, 53 authKeeper: authKeeper, 54 bankKeeper: bankKeeper, 55 authority: authority, 56 } 57 } 58 59 func (k Keeper) Logger(ctx sdk.Context) log.Logger { 60 return ctx.Logger().With("module", "x/"+types.ModuleName) 61 } 62 63 func (k Keeper) InitMemStore(ctx sdk.Context) { 64 memStore := ctx.KVStore(k.memKey) 65 memStoreType := memStore.GetStoreType() 66 if memStoreType != sdk.StoreTypeMemory { 67 panic(fmt.Sprintf("invalid memory store type; got %s, expected: %s", memStoreType, sdk.StoreTypeMemory)) 68 } 69 70 // create context with no block gas meter to ensure we do not consume gas during local initialization logic. 71 noGasCtx := ctx.WithBlockGasMeter(sdk.NewInfiniteGasMeter()) 72 73 roleMetadata := types.RoleMetadata{} 74 if !k.IsInitialized(noGasCtx) { 75 for _, pair := range k.GetRolePairs(noGasCtx) { 76 switch pair.Role { 77 case types.RoleGuardian: 78 roleMetadata.Guardian++ 79 case types.RoleOperator: 80 roleMetadata.Operator++ 81 case types.RoleJudge: 82 roleMetadata.Judge++ 83 } 84 } 85 k.setRoleMetadata(noGasCtx, roleMetadata) 86 87 nInactive := uint64(0) 88 for _, bs := range k.GetBridgeSwitches(ctx) { 89 if bs.Status == types.StatusInactive { 90 nInactive++ 91 } 92 } 93 k.setBridgeInactiveCounter(noGasCtx, nInactive) 94 95 memStore := noGasCtx.KVStore(k.memKey) 96 memStore.Set(types.KeyMemInitialized, []byte{1}) 97 } 98 } 99 100 // IsInitialized returns true if the keeper is properly initialized, and false otherwise. 101 func (k Keeper) IsInitialized(ctx sdk.Context) bool { 102 memStore := ctx.KVStore(k.memKey) 103 return memStore.Get(types.KeyMemInitialized) != nil 104 } 105 106 func (k Keeper) GetAuthority() string { 107 return k.authority 108 } 109 110 func (k Keeper) IsBridgeHalted(ctx sdk.Context) bool { 111 return k.GetBridgeStatus(ctx) == types.StatusInactive 112 } 113 114 func (k Keeper) setRoleMetadata(ctx sdk.Context, data types.RoleMetadata) { 115 memStore := ctx.KVStore(k.memKey) 116 bz := k.cdc.MustMarshal(&data) 117 memStore.Set(types.KeyMemRoleMetadata, bz) 118 } 119 120 func (k Keeper) GetRoleMetadata(ctx sdk.Context) types.RoleMetadata { 121 memStore := ctx.KVStore(k.memKey) 122 data := types.RoleMetadata{} 123 bz := memStore.Get(types.KeyMemRoleMetadata) 124 if bz == nil { 125 return types.RoleMetadata{} 126 } 127 k.cdc.MustUnmarshal(bz, &data) 128 return data 129 } 130 131 func (k Keeper) GetBridgeStatus(ctx sdk.Context) types.BridgeStatus { 132 roleMeta := k.GetRoleMetadata(ctx) 133 if roleMeta.Guardian != 0 { 134 bsMeta := k.GetBridgeStatusMetadata(ctx) 135 if types.CheckTrustLevelThreshold(roleMeta.Guardian, bsMeta.Inactive, k.GetParams(ctx).GuardianTrustLevel) { 136 return types.StatusInactive 137 } 138 139 return types.StatusActive 140 } 141 142 return types.StatusInactive 143 } 144 145 func (k Keeper) setBridgeInactiveCounter(ctx sdk.Context, nInactive uint64) { 146 memStore := ctx.KVStore(k.memKey) 147 bz := make([]byte, 8) 148 binary.BigEndian.PutUint64(bz, nInactive) 149 memStore.Set(types.KeyMemBridgeInactiveCounter, bz) 150 } 151 152 func (k Keeper) GetBridgeInactiveCounter(ctx sdk.Context) uint64 { 153 memStore := ctx.KVStore(k.memKey) 154 bz := memStore.Get(types.KeyMemBridgeInactiveCounter) 155 if bz == nil { 156 panic("bridge inactive counter must be set at initialization") 157 } 158 159 return binary.BigEndian.Uint64(bz) 160 } 161 162 func (k Keeper) GetBridgeStatusMetadata(ctx sdk.Context) types.BridgeStatusMetadata { 163 bsMeta := types.BridgeStatusMetadata{} 164 bsMeta.Inactive = k.GetBridgeInactiveCounter(ctx) 165 bsMeta.Active = k.GetRoleMetadata(ctx).Guardian - bsMeta.Inactive 166 return bsMeta 167 }