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, &currentVersion)
    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  }