github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/common/proto/keeper.go (about) 1 package proto 2 3 import ( 4 "fmt" 5 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 6 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 7 ) 8 9 // ProtocolDefinition is the struct of app-upgrade detail info 10 type ProtocolDefinition struct { 11 Version uint64 `json:"version"` 12 Software string `json:"software"` 13 Height uint64 `json:"height"` 14 Threshold sdk.Dec `json:"threshold"` 15 } 16 17 // NewProtocolDefinition creates a new instance of ProtocolDefinition 18 func NewProtocolDefinition(version uint64, software string, height uint64, threshold sdk.Dec) ProtocolDefinition { 19 return ProtocolDefinition{ 20 version, 21 software, 22 height, 23 threshold, 24 } 25 } 26 27 // AppUpgradeConfig is the struct of app-upgrade-specific params 28 type AppUpgradeConfig struct { 29 ProposalID uint64 `json:"proposal_id"` 30 ProtocolDef ProtocolDefinition `json:"protocol_def"` 31 } 32 33 // NewAppUpgradeConfig creates a new instance of AppUpgradeConfig 34 func NewAppUpgradeConfig(proposalID uint64, protocolDef ProtocolDefinition) AppUpgradeConfig { 35 return AppUpgradeConfig{ 36 proposalID, 37 protocolDef, 38 } 39 } 40 41 // DefaultUpgradeConfig returns a default AppUpgradeConfig object 42 func DefaultUpgradeConfig(software string) AppUpgradeConfig { 43 return AppUpgradeConfig{ 44 ProposalID: uint64(0), 45 ProtocolDef: NewProtocolDefinition(uint64(0), software, uint64(1), sdk.NewDecWithPrec(9, 1)), 46 } 47 } 48 49 // VersionKeeper shows the expected behaviour of a version keeper 50 type VersionKeeper interface { 51 GetCurrentVersionByStore(store sdk.KVStore) uint64 52 GetUpgradeConfigByStore(store sdk.KVStore) (upgradeConfig AppUpgradeConfig, found bool) 53 } 54 55 // ProtocolKeeper is designed for a protocol controller 56 type ProtocolKeeper struct { 57 storeKey sdk.StoreKey 58 cdc *codec.Codec 59 } 60 61 // NewProtocolKeeper creates a new instance of ProtocolKeeper 62 func NewProtocolKeeper(key sdk.StoreKey) ProtocolKeeper { 63 return ProtocolKeeper{key, cdc} 64 } 65 66 // GetCurrentVersionByStore gets the current version of protocol from store 67 func (pk ProtocolKeeper) GetCurrentVersionByStore(store sdk.KVStore) uint64 { 68 bz := store.Get(currentVersionKey) 69 if bz == nil { 70 return 0 71 } 72 var currentVersion uint64 73 pk.cdc.MustUnmarshalBinaryLengthPrefixed(bz, ¤tVersion) 74 return currentVersion 75 } 76 77 // GetCurrentVersion gets the current version from context 78 func (pk ProtocolKeeper) GetCurrentVersion(ctx sdk.Context) uint64 { 79 store := ctx.KVStore(pk.storeKey) 80 return pk.GetCurrentVersionByStore(store) 81 } 82 83 // GetUpgradeConfigByStore gets the upgrade config from store 84 func (pk ProtocolKeeper) GetUpgradeConfigByStore(store sdk.KVStore) (upgradeConfig AppUpgradeConfig, found bool) { 85 bz := store.Get(upgradeConfigKey) 86 if bz == nil { 87 return upgradeConfig, false 88 } 89 pk.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &upgradeConfig) 90 return upgradeConfig, true 91 } 92 93 // SetCurrentVersion sets current version 94 func (pk ProtocolKeeper) SetCurrentVersion(ctx sdk.Context, currentVersion uint64) { 95 store := ctx.KVStore(pk.storeKey) 96 bz := pk.cdc.MustMarshalBinaryLengthPrefixed(currentVersion) 97 store.Set(currentVersionKey, bz) 98 } 99 100 // GetLastFailedVersion gets last failed version 101 func (pk ProtocolKeeper) GetLastFailedVersion(ctx sdk.Context) uint64 { 102 store := ctx.KVStore(pk.storeKey) 103 bz := store.Get(lastFailedVersionKey) 104 if bz == nil { 105 return 0 // default value 106 } 107 var lastFailedVersion uint64 108 pk.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &lastFailedVersion) 109 return lastFailedVersion 110 } 111 112 // SetLastFailedVersion sets last failed version 113 func (pk ProtocolKeeper) SetLastFailedVersion(ctx sdk.Context, lastFailedVersion uint64) { 114 store := ctx.KVStore(pk.storeKey) 115 bz := pk.cdc.MustMarshalBinaryLengthPrefixed(lastFailedVersion) 116 store.Set(lastFailedVersionKey, bz) 117 } 118 119 // GetUpgradeConfig gets upgrade config 120 func (pk ProtocolKeeper) GetUpgradeConfig(ctx sdk.Context) (upgradeConfig AppUpgradeConfig, found bool) { 121 store := ctx.KVStore(pk.storeKey) 122 bz := store.Get(upgradeConfigKey) 123 if bz == nil { 124 return upgradeConfig, false 125 } 126 pk.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &upgradeConfig) 127 return upgradeConfig, true 128 } 129 130 // SetUpgradeConfig sets upgrade config 131 func (pk ProtocolKeeper) SetUpgradeConfig(ctx sdk.Context, upgradeConfig AppUpgradeConfig) { 132 store := ctx.KVStore(pk.storeKey) 133 bz := pk.cdc.MustMarshalBinaryLengthPrefixed(upgradeConfig) 134 store.Set(upgradeConfigKey, bz) 135 } 136 137 // ClearUpgradeConfig removes the upgrade config in the store 138 func (pk ProtocolKeeper) ClearUpgradeConfig(ctx sdk.Context) { 139 store := ctx.KVStore(pk.storeKey) 140 store.Delete(upgradeConfigKey) 141 } 142 143 // IsValidVersion checks whether the version is available 144 func (pk ProtocolKeeper) IsValidVersion(ctx sdk.Context, version uint64) bool { 145 currentVersion := pk.GetCurrentVersion(ctx) 146 lastFailedVersion := pk.GetLastFailedVersion(ctx) 147 return isValidVersion(currentVersion, lastFailedVersion, version) 148 } 149 150 // rule: new version should be currentVersion+1 or lastFailedVersion or lastFailedVersion+1 151 func isValidVersion(currentVersion uint64, lastFailedVersion uint64, version uint64) bool { 152 if currentVersion >= lastFailedVersion { 153 return currentVersion+1 == version 154 } 155 return lastFailedVersion == version || lastFailedVersion+1 == version 156 157 } 158 159 // String returns a human readable string representation of AppUpgradeConfig 160 func (auc AppUpgradeConfig) String() string { 161 return fmt.Sprintf(`AppUpgradeConfig: 162 ProposalID: %d 163 ProtocolDefinition: %v 164 `, 165 auc.ProposalID, auc.ProtocolDef) 166 }