github.com/InjectiveLabs/sdk-go@v1.53.0/chain/exchange/types/key.go (about)

     1  package types
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"math/big"
     7  	"strings"
     8  
     9  	"cosmossdk.io/math"
    10  	sdk "github.com/cosmos/cosmos-sdk/types"
    11  	"github.com/ethereum/go-ethereum/common"
    12  	"github.com/shopspring/decimal"
    13  )
    14  
    15  const (
    16  	// module name
    17  	ModuleName = "exchange"
    18  
    19  	// StoreKey to be used when creating the KVStore
    20  	StoreKey  = ModuleName
    21  	TStoreKey = "transient_exchange"
    22  )
    23  const PriceDecimalPlaces = 18
    24  const DefaultQueryOrderbookLimit uint64 = 20
    25  const Uint64BytesLen = 8
    26  
    27  var (
    28  	// Keys for store prefixes
    29  	DepositsPrefix                       = []byte{0x01} // prefix for each key to a Deposit
    30  	SubaccountTradeNoncePrefix           = []byte{0x02} // prefix for each key to a Subaccount Trade Nonce
    31  	SubaccountOrderbookMetadataPrefix    = []byte{0x03} // prefix for each key to a Subaccount Orderbook Metadata
    32  	SubaccountOrderPrefix                = []byte{0x04} // prefix for each key to a Subaccount derivative limit Order
    33  	SubaccountMarketOrderIndicatorPrefix = []byte{0x05} // prefix for each key to a Subaccount market order indicator
    34  	SubaccountLimitOrderIndicatorPrefix  = []byte{0x06} // prefix for each key to a Subaccount limit order indicator
    35  	SpotExchangeEnabledKey               = []byte{0x07} // key for whether spot exchange is enabled
    36  	DerivativeExchangeEnabledKey         = []byte{0x08} // key for whether derivative exchange is enabled
    37  	MarketHistoricalTradeRecordsPrefix   = []byte{0x09} // prefix for each key to a market's historical trade records
    38  	OrderbookSequencePrefix              = []byte{0x0a} // prefix for each key to a market's orderbook sequence
    39  	SubaccountMarketVolumePrefix         = []byte{0x0b} // prefix for each key to the aggregate volume for a subaccount in a market
    40  	MarketVolumePrefix                   = []byte{0x0c} // prefix for each key to the aggregate volume for a market
    41  	ParamsKey                            = []byte{0x0d} // prefix for module params
    42  	SubaccountCidPrefix                  = []byte{0x0e} // prefix for each
    43  
    44  	DenomDecimalsPrefix              = []byte{0x10} // prefix for denom decimals
    45  	SpotMarketsPrefix                = []byte{0x11} // prefix for each key to a spot market by (isEnabled, marketID)
    46  	SpotLimitOrdersPrefix            = []byte{0x12} // prefix for each key to a spot order, by (marketID, direction, price level, order hash)
    47  	SpotMarketOrdersPrefix           = []byte{0x13} // prefix for each key to a spot order, by (marketID, direction, price level, order hash)
    48  	SpotLimitOrdersIndexPrefix       = []byte{0x14} // prefix for each key to a spot order index, by (marketID, direction, subaccountID, order hash)
    49  	SpotMarketOrderIndicatorPrefix   = []byte{0x15} // prefix for each key to a spot market order indicator, by marketID and direction
    50  	SpotMarketParamUpdateScheduleKey = []byte{0x16} // prefix for a key to save scheduled spot market params update
    51  	SpotMarketForceCloseInfoKey      = []byte{0x17} // prefix for a key to save scheduled spot market closures
    52  	SpotOrderbookLevelsPrefix        = []byte{0x18} // prefix for each key to the spot orderbook for a given marketID and direction
    53  
    54  	DerivativeMarketPrefix                     = []byte{0x21} // prefix for each key to a derivative market by (isEnabled, marketID)
    55  	DerivativeLimitOrdersPrefix                = []byte{0x22} // prefix for each key to a derivative limit order, by (marketID, direction, price level, order hash)
    56  	DerivativeMarketOrdersPrefix               = []byte{0x23} // prefix for each key to a derivative order, by (marketID, direction, price level, order hash)
    57  	DerivativeLimitOrdersIndexPrefix           = []byte{0x24} // prefix for each key to a derivative order index, by (marketID, direction, subaccountID, order hash)
    58  	DerivativeLimitOrderIndicatorPrefix        = []byte{0x25} // prefix for each key to a derivative limit order indicator, by marketID and direction
    59  	DerivativeMarketOrderIndicatorPrefix       = []byte{0x26} // prefix for each key to a derivative market order indicator, by marketID and direction
    60  	DerivativePositionsPrefix                  = []byte{0x27} // prefix for each key to a Position
    61  	DerivativeMarketParamUpdateScheduleKey     = []byte{0x28} // prefix for a key to save scheduled derivative market params update
    62  	DerivativeMarketScheduledSettlementInfo    = []byte{0x29} // prefix for a key to save scheduled derivative market settlements
    63  	DerivativePositionModifiedSubaccountPrefix = []byte{0x2a} // prefix for a key to save a list of subaccountIDs by marketID
    64  	DerivativeOrderbookLevelsPrefix            = []byte{0x2b} // prefix for each key to the derivative orderbook for a given marketID and direction
    65  
    66  	PerpetualMarketFundingPrefix             = []byte{0x31} // prefix for each key to a perpetual market's funding state
    67  	PerpetualMarketInfoPrefix                = []byte{0x32} // prefix for each key to a perpetual market's market info
    68  	ExpiryFuturesMarketInfoPrefix            = []byte{0x33} // prefix for each key to a expiry futures market's market info
    69  	ExpiryFuturesMarketInfoByTimestampPrefix = []byte{0x34} // prefix for each index key to a expiry futures market's market info
    70  
    71  	IsFirstFeeCycleFinishedKey = []byte{0x3c} // key to the fee discount is first cycle finished
    72  
    73  	TradingRewardCampaignInfoKey                  = []byte{0x40} // key to the TradingRewardCampaignInfo
    74  	TradingRewardMarketQualificationPrefix        = []byte{0x41} // prefix for each key to a market's qualification/disqualification status
    75  	TradingRewardMarketPointsMultiplierPrefix     = []byte{0x42} // prefix for each key to a market's Volume Multiplier
    76  	TradingRewardCampaignRewardPoolPrefix         = []byte{0x43} // prefix for each key to a campaign's reward pool
    77  	TradingRewardCurrentCampaignEndTimeKey        = []byte{0x44} // key to the current campaign's end time
    78  	TradingRewardCampaignTotalPointsKey           = []byte{0x45} // key to the total trading reward points for the current campaign
    79  	TradingRewardAccountPointsPrefix              = []byte{0x46} // prefix for each key to an account's current campaign reward points
    80  	TradingRewardCampaignRewardPendingPoolPrefix  = []byte{0x47} // prefix for each key to a campaign's reward pending pool
    81  	TradingRewardAccountPendingPointsPrefix       = []byte{0x48} // prefix for each key to an account's current campaign reward points
    82  	TradingRewardCampaignTotalPendingPointsPrefix = []byte{0x49} // prefix to the total trading reward points for the current campaign
    83  
    84  	FeeDiscountMarketQualificationPrefix = []byte{0x50} // prefix for each key to a market's qualification/disqualification status
    85  	FeeDiscountBucketCountKey            = []byte{0x51} // key to the fee discount bucket count
    86  	FeeDiscountBucketDurationKey         = []byte{0x52} // key to the fee discount bucket duration
    87  	FeeDiscountCurrentBucketStartTimeKey = []byte{0x53} // key to the current bucket start timestamp
    88  	FeeDiscountScheduleKey               = []byte{0x54} // key to the fee discount schedule
    89  
    90  	FeeDiscountAccountTierPrefix                  = []byte{0x56} // prefix to each account's fee discount tier and TTL timestamp
    91  	FeeDiscountBucketAccountVolumePrefix          = []byte{0x57} // prefix to each account's volume for a given bucket
    92  	FeeDiscountAccountPastBucketTotalVolumePrefix = []byte{0x58} // prefix to each account's total past bucket volume amount FeeDiscountAccountIndicatorPrefix
    93  	FeeDiscountAccountOrderIndicatorPrefix        = []byte{0x59} // prefix to each account's transient indicator if the account has placed an order that block that is relevant for fee discounts
    94  
    95  	IsOptedOutOfRewardsPrefix = []byte{0x60} // prefix to each account's address key
    96  
    97  	BinaryOptionsMarketPrefix                    = []byte{0x61} // prefix for each key to a binary options market by (isEnabled, marketID)
    98  	BinaryOptionsMarketExpiryTimestampPrefix     = []byte{0x62} // prefix for each key to a binary options marketID by expiration timestamp
    99  	BinaryOptionsMarketSettlementTimestampPrefix = []byte{0x63} // prefix for each key to a binary options marketID by settlement timestamp
   100  	BinaryOptionsMarketSettlementSchedulePrefix  = []byte{0x64} // prefix for a key to save scheduled binary options marketID for settlement
   101  	BinaryOptionsMarketParamUpdateSchedulePrefix = []byte{0x65} // prefix for a key to save scheduled binary options market params update
   102  
   103  	SpotConditionalMarketOrdersPrefix            = []byte{0x70} // prefix for a key to save conditional spot market orders: marketID + direction + triggerPrice + orderHash ⇒ spotMarketOrder
   104  	SpotConditionalMarketOrdersIndexPrefix       = []byte{0x71} // prefix for a key to save conditional spot market orders index: marketID + direction + subaccountID + orderHash ⇒ triggerPrice
   105  	SpotConditionalLimitOrdersPrefix             = []byte{0x72} // prefix for a key to save conditional spot limit orders: marketID + direction + triggerPrice + orderHash ⇒ spotLimitOrder
   106  	SpotConditionalLimitOrdersIndexPrefix        = []byte{0x73} // prefix for a key to save conditional spot limit orders index: marketID + direction + subaccountID + orderHash ⇒ triggerPrice
   107  	DerivativeConditionalMarketOrdersPrefix      = []byte{0x74} // prefix for a key to save conditional derivative market orders: marketID + direction + triggerPrice + orderHash ⇒ derivativeMarketOrder
   108  	DerivativeConditionalMarketOrdersIndexPrefix = []byte{0x75} // prefix for a key to save conditional derivative market orders index: marketID + direction + subaccountID + orderHash ⇒ triggerPrice
   109  	DerivativeConditionalLimitOrdersPrefix       = []byte{0x76} // prefix for a key to save conditional derivative limit orders: marketID + direction + triggerPrice + orderHash ⇒ derivativeLimitOrder
   110  	DerivativeConditionalLimitOrdersIndexPrefix  = []byte{0x77} // prefix for a key to save conditional derivative limit orders index: marketID + direction + subaccountID + orderHash ⇒ triggerPrice
   111  	ConditionalOrderInvalidationFlagPrefix       = []byte{0x78} // prefix for a key to save flags to invalidate conditional orders
   112  
   113  	AtomicMarketOrderTakerFeeMultiplierKey = []byte{0x79} // key to store individual market atomic take fee multiplier
   114  
   115  	GrantAuthorizationsPrefix            = []byte{0x80} // prefix to store individual stake grants by (granter, grantee)
   116  	TotalGrantAmountPrefix               = []byte{0x81} // prefix to store the total granted amount by granter
   117  	LastGranterDelegationCheckTimePrefix = []byte{0x82} // prefix to store the last timestamp that the granter's delegations were checked
   118  	ActiveGrantPrefix                    = []byte{0x83} // prefix to store the grantee's active grant
   119  )
   120  
   121  func GetSubaccountCidKey(subaccountID common.Hash, cid string) []byte {
   122  	return append(SubaccountCidPrefix, append(subaccountID.Bytes(), cid...)...)
   123  }
   124  
   125  func ParseMarketDirectionAndOrderHashFromSubaccountCidValue(key []byte) (marketID common.Hash, direction byte, orderHash common.Hash) {
   126  	marketID = common.BytesToHash(key[:common.HashLength])
   127  	direction = key[common.HashLength]
   128  	orderHash = common.BytesToHash(key[common.HashLength+1:])
   129  	return marketID, direction, orderHash
   130  }
   131  
   132  // GetFeeDiscountAccountVolumeInBucketKey provides the key for the account's volume in the given bucket
   133  func GetFeeDiscountAccountVolumeInBucketKey(bucketStartTimestamp int64, account sdk.AccAddress) []byte {
   134  	timeBz := sdk.Uint64ToBigEndian(uint64(bucketStartTimestamp))
   135  	accountBz := account.Bytes()
   136  
   137  	buf := make([]byte, 0, len(FeeDiscountBucketAccountVolumePrefix)+len(timeBz)+len(accountBz))
   138  	buf = append(buf, FeeDiscountBucketAccountVolumePrefix...)
   139  	buf = append(buf, timeBz...)
   140  	buf = append(buf, accountBz...)
   141  	return buf
   142  }
   143  
   144  func ParseFeeDiscountBucketAccountVolumeIteratorKey(key []byte) (bucketStartTimestamp int64, account sdk.AccAddress) {
   145  	timeBz := key[:Uint64BytesLen]
   146  	accountBz := key[Uint64BytesLen:]
   147  	return int64(sdk.BigEndianToUint64(timeBz)), sdk.AccAddress(accountBz)
   148  }
   149  
   150  func ParseTradingRewardAccountPendingPointsKey(key []byte) (bucketStartTimestamp int64, account sdk.AccAddress) {
   151  	timeBz := key[:Uint64BytesLen]
   152  	accountBz := key[Uint64BytesLen:]
   153  	return int64(sdk.BigEndianToUint64(timeBz)), sdk.AccAddress(accountBz)
   154  }
   155  
   156  // GetFeeDiscountPastBucketAccountVolumeKey provides the key for the account's total past bucket volume.
   157  func GetFeeDiscountPastBucketAccountVolumeKey(account sdk.AccAddress) []byte {
   158  	accountBz := account.Bytes()
   159  	return append(FeeDiscountAccountPastBucketTotalVolumePrefix, accountBz...)
   160  }
   161  
   162  // GetFeeDiscountAccountOrderIndicatorKey provides the key for the transient indicator if the account has placed an order that block
   163  func GetFeeDiscountAccountOrderIndicatorKey(account sdk.AccAddress) []byte {
   164  	accountBz := account.Bytes()
   165  	return append(FeeDiscountAccountOrderIndicatorPrefix, accountBz...)
   166  }
   167  
   168  // GetFeeDiscountAccountTierKey provides the key for the account's fee discount tier.
   169  func GetFeeDiscountAccountTierKey(account sdk.AccAddress) []byte {
   170  	accountBz := account.Bytes()
   171  
   172  	buf := make([]byte, 0, len(FeeDiscountAccountTierPrefix)+len(accountBz))
   173  	buf = append(buf, FeeDiscountAccountTierPrefix...)
   174  	buf = append(buf, accountBz...)
   175  	return buf
   176  }
   177  
   178  // GetIsOptedOutOfRewardsKey provides the key for the opted out rewards address
   179  func GetIsOptedOutOfRewardsKey(account sdk.AccAddress) []byte {
   180  	accountBz := account.Bytes()
   181  
   182  	buf := make([]byte, 0, len(IsOptedOutOfRewardsPrefix)+len(accountBz))
   183  	buf = append(buf, IsOptedOutOfRewardsPrefix...)
   184  	buf = append(buf, accountBz...)
   185  	return buf
   186  }
   187  
   188  // GetFeeDiscountMarketQualificationKey provides the key for the market fee discount qualification status
   189  func GetFeeDiscountMarketQualificationKey(marketID common.Hash) []byte {
   190  	return append(FeeDiscountMarketQualificationPrefix, marketID.Bytes()...)
   191  }
   192  
   193  // GetCampaignRewardPoolKey provides the key for a reward pool for a given start time
   194  func GetCampaignRewardPoolKey(startTimestamp int64) []byte {
   195  	return append(TradingRewardCampaignRewardPoolPrefix, sdk.Uint64ToBigEndian(uint64(startTimestamp))...)
   196  }
   197  
   198  // GetCampaignRewardPendingPoolKey provides the key for a pending reward pool for a given start time
   199  func GetCampaignRewardPendingPoolKey(startTimestamp int64) []byte {
   200  	return append(TradingRewardCampaignRewardPendingPoolPrefix, sdk.Uint64ToBigEndian(uint64(startTimestamp))...)
   201  }
   202  
   203  // GetCampaignMarketQualificationKey provides the key for the market trading rewards qualification status
   204  func GetCampaignMarketQualificationKey(marketID common.Hash) []byte {
   205  	return append(TradingRewardMarketQualificationPrefix, marketID.Bytes()...)
   206  }
   207  
   208  // GetTradingRewardsMarketPointsMultiplierKey provides the key for the market trading rewards multiplier
   209  func GetTradingRewardsMarketPointsMultiplierKey(marketID common.Hash) []byte {
   210  	return append(TradingRewardMarketPointsMultiplierPrefix, marketID.Bytes()...)
   211  }
   212  
   213  // GetTradingRewardAccountPointsKey provides the key for the account's trading rewards points.
   214  func GetTradingRewardAccountPointsKey(account sdk.AccAddress) []byte {
   215  	return append(TradingRewardAccountPointsPrefix, account.Bytes()...)
   216  }
   217  
   218  // GetTradingRewardAccountPendingPointsPrefix provides the prefix for the account's trading rewards pending points.
   219  func GetTradingRewardAccountPendingPointsPrefix(pendingPoolStartTimestamp int64) []byte {
   220  	return append(TradingRewardAccountPendingPointsPrefix, sdk.Uint64ToBigEndian(uint64(pendingPoolStartTimestamp))...)
   221  }
   222  
   223  // GetTradingRewardAccountPendingPointsKey provides the key for the account's trading rewards pending points.
   224  func GetTradingRewardAccountPendingPointsKey(account sdk.AccAddress, pendingPoolStartTimestamp int64) []byte {
   225  	return append(append(TradingRewardAccountPendingPointsPrefix, sdk.Uint64ToBigEndian(uint64(pendingPoolStartTimestamp))...), account.Bytes()...)
   226  }
   227  
   228  // GetTradingRewardTotalPendingPointsKey provides the key for the total pending trading rewards points.
   229  func GetTradingRewardTotalPendingPointsKey(pendingPoolStartTimestamp int64) []byte {
   230  	return append(TradingRewardCampaignTotalPendingPointsPrefix, sdk.Uint64ToBigEndian(uint64(pendingPoolStartTimestamp))...)
   231  }
   232  
   233  // GetTradingRewardAccountPendingPointsStartTimestamp provides the start timestamp of the pending points pool.
   234  func GetTradingRewardAccountPendingPointsStartTimestamp(pendingPoolStartTimestamp []byte) int64 {
   235  	return int64(sdk.BigEndianToUint64(pendingPoolStartTimestamp))
   236  }
   237  
   238  // GetDepositKey provides the key to obtain a given subaccount's deposits for a given denom
   239  func GetDepositKey(subaccountID common.Hash, denom string) []byte {
   240  	return append(GetDepositKeyPrefixBySubaccountID(subaccountID), []byte(denom)...)
   241  }
   242  
   243  func GetDepositKeyPrefixBySubaccountID(subaccountID common.Hash) []byte {
   244  	return append(DepositsPrefix, subaccountID.Bytes()...)
   245  }
   246  
   247  func ParseDepositStoreKey(key []byte) (subaccountID common.Hash, denom string) {
   248  	subaccountEndIdx := common.HashLength
   249  	subaccountID = common.BytesToHash(key[:subaccountEndIdx])
   250  	denom = string(key[subaccountEndIdx:])
   251  	return subaccountID, denom
   252  }
   253  
   254  // ParseDepositTransientStoreKey parses the deposit transient store key.
   255  func ParseDepositTransientStoreKey(prefix, key []byte) (subaccountID common.Hash, denom string) {
   256  	return ParseDepositStoreKey(key[len(prefix):])
   257  }
   258  
   259  // GetSubaccountTradeNonceKey provides the prefix to obtain a given subaccount's trade nonce.
   260  func GetSubaccountTradeNonceKey(subaccountID common.Hash) []byte {
   261  	return append(SubaccountTradeNoncePrefix, subaccountID.Bytes()...)
   262  }
   263  
   264  func GetSubaccountOrderbookMetadataKey(marketID, subaccountID common.Hash, isBuy bool) []byte {
   265  	return append(SubaccountOrderbookMetadataPrefix, GetSubaccountOrderSuffix(marketID, subaccountID, isBuy)...)
   266  }
   267  
   268  func GetSubaccountMarketOrderIndicatorKey(marketID, subaccountID common.Hash) []byte {
   269  	return append(SubaccountMarketOrderIndicatorPrefix, MarketSubaccountInfix(marketID, subaccountID)...)
   270  }
   271  
   272  func GetSubaccountLimitOrderIndicatorKey(marketID, subaccountID common.Hash) []byte {
   273  	return append(SubaccountLimitOrderIndicatorPrefix, MarketSubaccountInfix(marketID, subaccountID)...)
   274  }
   275  
   276  func GetSubaccountOrderSuffix(marketID, subaccountID common.Hash, isBuy bool) []byte {
   277  	return append(MarketSubaccountInfix(marketID, subaccountID), getBoolPrefix(isBuy)...)
   278  }
   279  
   280  func GetSubaccountOrderKey(marketID, subaccountID common.Hash, isBuy bool, price math.LegacyDec, orderHash common.Hash) []byte {
   281  	// TODO use copy for greater efficiency
   282  	return append(append(GetSubaccountOrderPrefixByMarketSubaccountDirection(marketID, subaccountID, isBuy), []byte(GetPaddedPrice(price))...), orderHash.Bytes()...)
   283  }
   284  
   285  func GetSubaccountOrderIterationKey(price math.LegacyDec, orderHash common.Hash) []byte {
   286  	return append([]byte(GetPaddedPrice(price)), orderHash.Bytes()...)
   287  }
   288  
   289  func GetSubaccountOrderPrefixByMarketSubaccountDirection(marketID, subaccountID common.Hash, isBuy bool) []byte {
   290  	return append(SubaccountOrderPrefix, append(MarketSubaccountInfix(marketID, subaccountID), getBoolPrefix(isBuy)...)...)
   291  }
   292  
   293  func GetSubaccountMarketVolumeKey(subaccountID, marketID common.Hash) []byte {
   294  	return append(SubaccountMarketVolumePrefix, SubaccountMarketInfix(subaccountID, marketID)...)
   295  }
   296  
   297  func GetMarketVolumeKey(marketID common.Hash) []byte {
   298  	return append(MarketVolumePrefix, marketID.Bytes()...)
   299  }
   300  
   301  func GetSpotMarketKey(isEnabled bool) []byte {
   302  	return append(SpotMarketsPrefix, getBoolPrefix(isEnabled)...)
   303  }
   304  
   305  func GetSpotMarketTransientMarketsKey(marketID common.Hash, isBuy bool) []byte {
   306  	return append(SpotMarketsPrefix, MarketDirectionPrefix(marketID, isBuy)...)
   307  }
   308  
   309  func GetDerivativeLimitTransientMarketsKeyPrefix(marketID common.Hash, isBuy bool) []byte {
   310  	return append(DerivativeLimitOrderIndicatorPrefix, MarketDirectionPrefix(marketID, isBuy)...)
   311  }
   312  
   313  func GetDerivativeMarketTransientMarketsKey(marketID common.Hash, isBuy bool) []byte {
   314  	return append(DerivativeMarketOrderIndicatorPrefix, MarketDirectionPrefix(marketID, isBuy)...)
   315  }
   316  
   317  func GetPaddedPrice(price math.LegacyDec) string {
   318  	dec := decimal.NewFromBigInt(price.BigInt(), -18).StringFixed(PriceDecimalPlaces)
   319  	return getPaddedPriceFromString(dec)
   320  }
   321  
   322  func getPaddedPriceFromString(price string) string {
   323  	components := strings.Split(price, ".")
   324  	naturalPart, decimalPart := components[0], components[1]
   325  	return fmt.Sprintf("%032s.%s", naturalPart, decimalPart)
   326  }
   327  
   328  func GetPriceFromPaddedPrice(paddedPrice string) math.LegacyDec {
   329  	priceString := strings.Trim(paddedPrice, "0")
   330  	// remove the "." if there's no decimal component
   331  	priceString = strings.TrimSuffix(priceString, ".")
   332  	// edge case when no natural component, prepend 0
   333  	if strings.HasPrefix(priceString, ".") {
   334  		priceString = "0" + priceString
   335  	}
   336  	return math.LegacyMustNewDecFromStr(priceString)
   337  }
   338  
   339  func GetLimitOrderByPriceKeyPrefix(marketID common.Hash, isBuy bool, price math.LegacyDec, orderHash common.Hash) []byte {
   340  	return GetOrderByPriceKeyPrefix(marketID, isBuy, price, orderHash)
   341  }
   342  
   343  func GetSpotLimitOrderIndexPrefix(marketID common.Hash, isBuy bool, subaccountID common.Hash) []byte {
   344  	return append(SpotLimitOrdersIndexPrefix, GetLimitOrderIndexSubaccountPrefix(marketID, isBuy, subaccountID)...)
   345  }
   346  
   347  func GetSpotLimitOrderIndexByAccountAddressPrefix(marketID common.Hash, isBuy bool, account sdk.AccAddress) []byte {
   348  	return append(SpotLimitOrdersIndexPrefix, GetLimitOrderIndexAccountAddressPrefix(marketID, isBuy, account)...)
   349  }
   350  
   351  func GetDerivativeLimitOrderIndexPrefix(marketID common.Hash, isBuy bool, subaccountID common.Hash) []byte {
   352  	return append(DerivativeLimitOrdersIndexPrefix, GetLimitOrderIndexSubaccountPrefix(marketID, isBuy, subaccountID)...)
   353  }
   354  
   355  func GetDerivativeLimitOrderIndexByAccountAddressPrefix(marketID common.Hash, isBuy bool, account sdk.AccAddress) []byte {
   356  	return append(DerivativeLimitOrdersIndexPrefix, GetLimitOrderIndexAccountAddressPrefix(marketID, isBuy, account)...)
   357  }
   358  
   359  func GetLimitOrderIndexKey(marketID common.Hash, isBuy bool, subaccountID, orderHash common.Hash) []byte {
   360  	return append(GetLimitOrderIndexSubaccountPrefix(marketID, isBuy, subaccountID), orderHash.Bytes()...)
   361  }
   362  
   363  func GetTransientLimitOrderIndexIteratorPrefix(marketID common.Hash, isBuy bool, subaccountID common.Hash) []byte {
   364  	return append(SpotLimitOrdersIndexPrefix, GetLimitOrderIndexSubaccountPrefix(marketID, isBuy, subaccountID)...)
   365  }
   366  
   367  // GetLimitOrderIndexSubaccountPrefix returns a prefix containing marketID + isBuy + subaccountID
   368  func GetLimitOrderIndexSubaccountPrefix(marketID common.Hash, isBuy bool, subaccountID common.Hash) []byte {
   369  	return append(MarketDirectionPrefix(marketID, isBuy), subaccountID.Bytes()...)
   370  }
   371  
   372  // GetLimitOrderIndexAccountAddressPrefix returns a prefix containing marketID + isBuy + account
   373  func GetLimitOrderIndexAccountAddressPrefix(marketID common.Hash, isBuy bool, account sdk.AccAddress) []byte {
   374  	return append(MarketDirectionPrefix(marketID, isBuy), account.Bytes()...)
   375  }
   376  
   377  func GetOrderByPriceKeyPrefix(marketID common.Hash, isBuy bool, price math.LegacyDec, orderHash common.Hash) []byte {
   378  	return append(append(MarketDirectionPrefix(marketID, isBuy), []byte(GetPaddedPrice(price))...), orderHash.Bytes()...)
   379  }
   380  
   381  func GetOrderByStringPriceKeyPrefix(marketID common.Hash, isBuy bool, price string, orderHash common.Hash) []byte {
   382  	return append(append(MarketDirectionPrefix(marketID, isBuy), []byte(getPaddedPriceFromString(price))...), orderHash.Bytes()...)
   383  }
   384  
   385  func GetConditionalOrderByTriggerPriceKeyPrefix(marketID common.Hash, isHigher bool, triggerPrice math.LegacyDec, orderHash common.Hash) []byte {
   386  	return append(append(MarketDirectionPrefix(marketID, isHigher), []byte(GetPaddedPrice(triggerPrice))...), orderHash.Bytes()...)
   387  }
   388  
   389  // SpotMarketDirectionPriceHashPrefix turns a marketID + direction + price + order hash to prefix used to get a spot order from the store.
   390  func SpotMarketDirectionPriceHashPrefix(marketID common.Hash, isBuy bool, price math.LegacyDec, orderHash common.Hash) []byte {
   391  	return append(append(MarketDirectionPrefix(marketID, isBuy), []byte(GetPaddedPrice(price))...), orderHash.Bytes()...)
   392  }
   393  
   394  func GetDerivativeMarketPrefix(isEnabled bool) []byte {
   395  	return append(DerivativeMarketPrefix, getBoolPrefix(isEnabled)...)
   396  }
   397  
   398  func GetBinaryOptionsMarketPrefix(isEnabled bool) []byte {
   399  	return append(BinaryOptionsMarketPrefix, getBoolPrefix(isEnabled)...)
   400  }
   401  
   402  func GetBinaryOptionsMarketKey(isEnabled bool, marketID common.Hash) []byte {
   403  	return append(GetBinaryOptionsMarketPrefix(isEnabled), marketID.Bytes()...)
   404  }
   405  
   406  func getBoolPrefix(isEnabled bool) []byte {
   407  	isEnabledByte := byte(0)
   408  	if isEnabled {
   409  		isEnabledByte = TrueByte
   410  	}
   411  	return []byte{isEnabledByte}
   412  }
   413  
   414  // OrdersByMarketDirectionPriceOrderHashPrefix turns a marketID + direction + price + order hash to prefix used to get an order from the store.
   415  func OrdersByMarketDirectionPriceOrderHashPrefix(marketID, orderHash common.Hash, price *big.Int, isLong bool) []byte {
   416  	return append(ordersByMarketDirectionPricePrefix(marketID, price, isLong), orderHash.Bytes()...)
   417  }
   418  
   419  // orderIndexByMarketDirectionSubaccountPrefix allows to obtain prefix of exchange against a particular marketID, direction and price
   420  func ordersByMarketDirectionPricePrefix(marketID common.Hash, price *big.Int, isLong bool) []byte {
   421  	return append(MarketDirectionPrefix(marketID, isLong), common.LeftPadBytes(price.Bytes(), 32)...)
   422  }
   423  
   424  // OrderIndexByMarketDirectionSubaccountOrderHashPrefix turns a marketID + direction + subaccountID + order hash to prefix used to get an order from the store.
   425  func OrderIndexByMarketDirectionSubaccountOrderHashPrefix(marketID common.Hash, isLong bool, subaccountID, orderHash common.Hash) []byte {
   426  	return append(OrderIndexByMarketDirectionSubaccountPrefix(marketID, subaccountID, isLong), orderHash.Bytes()...)
   427  }
   428  
   429  // OrderIndexByMarketDirectionSubaccountPrefix allows to obtain prefix of exchange against a particular marketID, subaccountID and direction
   430  func OrderIndexByMarketDirectionSubaccountPrefix(marketID, subaccountID common.Hash, isLong bool) []byte {
   431  	return append(MarketDirectionPrefix(marketID, isLong), subaccountID.Bytes()...)
   432  }
   433  
   434  const TrueByte byte = byte(1)
   435  const FalseByte byte = byte(0)
   436  
   437  func IsTrueByte(bz []byte) bool {
   438  	return bytes.Equal(bz, []byte{TrueByte})
   439  }
   440  
   441  // MarketDirectionPrefix allows to obtain prefix against a particular marketID, direction
   442  func MarketDirectionPrefix(marketID common.Hash, isLong bool) []byte {
   443  	direction := byte(0)
   444  	if isLong {
   445  		direction = TrueByte
   446  	}
   447  	return append(marketID.Bytes(), direction)
   448  }
   449  
   450  // GetMarketIdDirectionFromTransientKey parses the marketID and direction from a transient Key.
   451  func GetMarketIdDirectionFromTransientKey(key []byte) (marketID common.Hash, isBuy bool) {
   452  	marketID = common.BytesToHash(key[:common.HashLength])
   453  	isBuyByte := key[common.HashLength]
   454  	return marketID, isBuyByte == TrueByte
   455  }
   456  
   457  // MarketSubaccountInfix provides the infix given a marketID and subaccountID
   458  func MarketSubaccountInfix(marketID, subaccountID common.Hash) []byte {
   459  	return append(marketID.Bytes(), subaccountID.Bytes()...)
   460  }
   461  
   462  // SubaccountMarketInfix provides the infix given a subaccountID and marketID
   463  func SubaccountMarketInfix(subaccountID, marketID common.Hash) []byte {
   464  	return append(subaccountID.Bytes(), marketID.Bytes()...)
   465  }
   466  
   467  // PositionIndexBySubaccountMarketPrefix provides the prefix key to obtain a position key for a given market and subaccount
   468  func PositionIndexBySubaccountMarketPrefix(subaccountID, marketID common.Hash) []byte {
   469  	return append(subaccountID.Bytes(), marketID.Bytes()...)
   470  }
   471  
   472  func ParsePositionTransientStoreKey(key []byte) (marketID, subaccountID common.Hash) {
   473  	prefixLen := len(DerivativePositionsPrefix)
   474  	marketIDEndIdx := common.HashLength + prefixLen
   475  	marketID = common.BytesToHash(key[prefixLen:marketIDEndIdx])
   476  	subaccountID = common.BytesToHash(key[marketIDEndIdx : marketIDEndIdx+common.HashLength])
   477  	return marketID, subaccountID
   478  }
   479  
   480  func ParseMarketIDSubaccountIDDirectionSuffix(keySuffix []byte) (marketID, subaccountID common.Hash, isBuy bool) {
   481  	marketIDEndIdx := common.HashLength
   482  	marketID = common.BytesToHash(keySuffix[:marketIDEndIdx])
   483  	subaccountID = common.BytesToHash(keySuffix[marketIDEndIdx : marketIDEndIdx+common.HashLength])
   484  	isBuy = keySuffix[len(keySuffix)-1] == 1
   485  	return marketID, subaccountID, isBuy
   486  }
   487  
   488  func GetSubaccountAndMarketIDFromPositionKey(key []byte) (subaccountID, marketID common.Hash) {
   489  	subaccountOffsetLen := common.HashLength
   490  	marketID = common.BytesToHash(key[:subaccountOffsetLen])
   491  	subaccountID = common.BytesToHash(key[subaccountOffsetLen : subaccountOffsetLen+common.HashLength])
   492  
   493  	return subaccountID, marketID
   494  }
   495  
   496  func GetSubaccountIDFromPositionKey(key []byte) (subaccountID common.Hash) {
   497  	subaccountOffsetLen := common.HashLength
   498  	subaccountID = common.BytesToHash(key[:subaccountOffsetLen])
   499  
   500  	return subaccountID
   501  }
   502  
   503  func GetExpiryFuturesMarketInfoByTimestampKey(timestamp int64, marketID common.Hash) []byte {
   504  	return append(ExpiryFuturesMarketInfoByTimestampPrefix, append(sdk.Uint64ToBigEndian(uint64(timestamp)), marketID.Bytes()...)...)
   505  }
   506  
   507  func GetBinaryOptionsMarketExpiryTimestampKey(timestamp int64, marketID common.Hash) []byte {
   508  	return append(BinaryOptionsMarketExpiryTimestampPrefix, append(sdk.Uint64ToBigEndian(uint64(timestamp)), marketID.Bytes()...)...)
   509  }
   510  
   511  func GetBinaryOptionsMarketSettlementTimestampKey(timestamp int64, marketID common.Hash) []byte {
   512  	return append(BinaryOptionsMarketSettlementTimestampPrefix, append(sdk.Uint64ToBigEndian(uint64(timestamp)), marketID.Bytes()...)...)
   513  }
   514  
   515  func GetMarketHistoricalTradeRecordsKey(marketID common.Hash) []byte {
   516  	return append(MarketHistoricalTradeRecordsPrefix, marketID.Bytes()...)
   517  }
   518  
   519  func GetDenomDecimalsKey(denom string) []byte {
   520  	return append(DenomDecimalsPrefix, []byte(denom)...)
   521  }
   522  
   523  func GetSpotOrderbookLevelsKey(marketID common.Hash, isBuy bool) []byte {
   524  	return append(SpotOrderbookLevelsPrefix, MarketDirectionPrefix(marketID, isBuy)...)
   525  }
   526  func GetSpotOrderbookLevelsForPriceKey(marketID common.Hash, isBuy bool, price math.LegacyDec) []byte {
   527  	return append(GetSpotOrderbookLevelsKey(marketID, isBuy), GetPaddedPrice(price)...)
   528  }
   529  func GetDerivativeOrderbookLevelsKey(marketID common.Hash, isBuy bool) []byte {
   530  	return append(DerivativeOrderbookLevelsPrefix, MarketDirectionPrefix(marketID, isBuy)...)
   531  }
   532  func GetDerivativeOrderbookLevelsForPriceKey(marketID common.Hash, isBuy bool, price math.LegacyDec) []byte {
   533  	return append(GetDerivativeOrderbookLevelsKey(marketID, isBuy), GetPaddedPrice(price)...)
   534  }
   535  
   536  func GetGrantAuthorizationKey(granter, grantee sdk.AccAddress) []byte {
   537  	return append(GrantAuthorizationsPrefix, append(granter.Bytes(), grantee.Bytes()...)...)
   538  }
   539  
   540  func GetGrantAuthorizationIteratorPrefix(granter sdk.AccAddress) []byte {
   541  	return append(GrantAuthorizationsPrefix, granter.Bytes()...)
   542  }
   543  
   544  func GetTotalGrantAmountKey(granter sdk.AccAddress) []byte {
   545  	return append(TotalGrantAmountPrefix, granter.Bytes()...)
   546  }
   547  
   548  func GetActiveGrantKey(grantee sdk.AccAddress) []byte {
   549  	return append(ActiveGrantPrefix, grantee.Bytes()...)
   550  }
   551  
   552  func GetLastValidGrantDelegationCheckTimeKey(granter sdk.AccAddress) []byte {
   553  	return append(LastGranterDelegationCheckTimePrefix, granter.Bytes()...)
   554  }