Skip to content

Commit

Permalink
docs: add oracle specs (#553)
Browse files Browse the repository at this point in the history
  • Loading branch information
cosmic-vagabond authored Jun 7, 2024
1 parent c6bce8f commit fc0ee22
Show file tree
Hide file tree
Showing 6 changed files with 930 additions and 0 deletions.
7 changes: 7 additions & 0 deletions x/oracle/spec/01_concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!--
order: 1
-->

# Concepts

The `oracle` module in the Elys Network provides decentralized price feeds and asset information. It facilitates querying and setting asset prices from different sources such as Band and Elys, maintaining the integrity and availability of price data within the network. This module enhances the efficiency and reliability of price-related operations across the network.
68 changes: 68 additions & 0 deletions x/oracle/spec/02_usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!--
order: 2
-->

# Usage

## Commands

### Querying Parameters and Band Price Results

```bash
elysd query oracle params
elysd query oracle band-price-result [request_id]
elysd query oracle last-band-request-id
```

### Querying Asset Info

```bash
elysd query oracle list-asset-info
elysd query oracle show-asset-info [denom]
```

### Querying Prices

```bash
elysd query oracle list-price
elysd query oracle show-price [asset] --source="[source]" --timestamp=[timestamp]
elysd query oracle show-price [asset] --source="[source]"
elysd query oracle show-price [asset]
```

### Managing Price Feeders

```bash
elysd query oracle list-price-feeder
elysd query oracle show-price-feeder [feeder_address]

elysd tx oracle set-price-feeder [feeder_address] [is_active] --from=[key] --chain-id=[chain-id] --broadcast-mode=block --yes
elysd tx oracle delete-price-feeder [feeder_address] --from=[key] --chain-id=[chain-id] --broadcast-mode=block --yes
```

### Feeding Prices

```bash
elysd tx oracle feed-price [asset] [price] [source] --from=[provider] --chain-id=[chain-id] --broadcast-mode=block --yes
elysd tx oracle feed-multiple-prices [prices-json] --from=[creator] --chain-id=[chain-id] --broadcast-mode=block --yes
```

### Managing Asset Info

```bash
elysd tx oracle add-asset-info-proposal [denom] [display] [band_ticker] [elys_ticker] [decimal] --title="[title]" --description="[description]" --deposit="[deposit_amount]" --from=[authority] --chain-id=[chain-id] --broadcast-mode=block --yes
elysd tx oracle remove-asset-info-proposal [denom] --title="[title]" --description="[description]" --deposit="[deposit_amount]" --from=[authority] --chain-id=[chain-id] --broadcast-mode=block --yes
```

### Submitting Governance Proposals

```bash
elysd query gov proposals
elysd tx gov vote [proposal_id] yes --from=[voter] --chain-id=[chain-id] --broadcast-mode=block --yes
```

### Requesting Band Price

```bash
elysd tx oracle request-band-price --from=[key] --chain-id=[chain-id] --broadcast-mode=block --yes
```
203 changes: 203 additions & 0 deletions x/oracle/spec/03_keeper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
<!--
order: 3
-->

# Keeper

## Price Management

The `oracle` module's keeper handles the management and querying of asset prices and related information. It ensures the timely update and retrieval of price data and manages the lifecycle of price feeders.

### EndBlocker

The `EndBlocker` function is invoked at the end of each block. It is responsible for removing outdated prices based on the configured expiration parameters.

```go
func (k Keeper) EndBlock(ctx sdk.Context) {
params := k.GetParams(ctx)
for _, price := range k.GetAllPrice(ctx) {
if price.Timestamp + params.PriceExpiryTime < uint64(ctx.BlockTime().Unix()) {
k.RemovePrice(ctx, price.Asset, price.Source, price.Timestamp)
}
if price.BlockHeight + params.LifeTimeInBlocks < uint64(ctx.BlockHeight()) {
k.RemovePrice(ctx, price.Asset, price.Source, price.Timestamp)
}
}
}
```

### Managing Asset Info

The `SetAssetInfo`, `GetAssetInfo`, `RemoveAssetInfo`, and `GetAllAssetInfo` functions handle the creation, retrieval, deletion, and listing of asset information.

```go
func (k Keeper) SetAssetInfo(ctx sdk.Context, assetInfo types.AssetInfo) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.AssetInfoKeyPrefix))
bz := k.cdc.MustMarshal(&assetInfo)
store.Set(types.AssetInfoKey(assetInfo.Denom), bz)
}

func (k Keeper) GetAssetInfo(ctx sdk.Context, denom string) (val types.AssetInfo, found bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.AssetInfoKeyPrefix))
bz := store.Get(types.AssetInfoKey(denom))
if bz == nil {
return val, false
}
k.cdc.MustUnmarshal(bz, &val)
return val, true
}

func (k Keeper) RemoveAssetInfo(ctx sdk.Context, denom string) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.AssetInfoKeyPrefix))
store.Delete(types.AssetInfoKey(denom))
}

func (k Keeper) GetAllAssetInfo(ctx sdk.Context) (list []types.AssetInfo) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.AssetInfoKeyPrefix))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.AssetInfo
k.cdc.MustUnmarshal(iterator.Value(), &val)
list = append(list, val)
}
return
}
```

### Managing Band Price Results

The `SetBandPriceResult`, `GetBandPriceResult`, `GetLastBandRequestId`, and `SetLastBandRequestId` functions manage the storage and retrieval of price data from Band protocol.

```go
func (k Keeper) SetBandPriceResult(ctx sdk.Context, requestID types.OracleRequestID, result types.BandPriceResult) {
store := ctx.KVStore(k.storeKey)
store.Set(types.BandPriceResultStoreKey(requestID), k.cdc.MustMarshal(&result))
}

func (k Keeper) GetBandPriceResult(ctx sdk.Context, id types.OracleRequestID) (types.BandPriceResult, error) {
bz := ctx.KVStore(k.storeKey).Get(types.BandPriceResultStoreKey(id))
if bz == nil {
return types.BandPriceResult{}, errorsmod.Wrapf(types.ErrNotAvailable, "Result for request ID %d is not available.", id)
}
var result types.BandPriceResult
k.cdc.MustUnmarshal(bz, &result)
return result, nil
}

func (k Keeper) GetLastBandRequestId(ctx sdk.Context) int64 {
bz := ctx.KVStore(k.storeKey).Get(types.KeyPrefix(types.LastBandRequestIdKey))
intV := gogotypes.Int64Value{}
k.cdc.MustUnmarshalLengthPrefixed(bz, &intV)
return intV.GetValue()
}

func (k Keeper) SetLastBandRequestId(ctx sdk.Context, id types.OracleRequestID) {
store := ctx.KVStore(k.storeKey)
store.Set(types.KeyPrefix(types.LastBandRequestIdKey), k.cdc.MustMarshalLengthPrefixed(&gogotypes.Int64Value{Value: int64(id)}))
}
```

### Managing Prices

The `SetPrice`, `GetPrice`, `GetLatestPriceFromAssetAndSource`, `GetLatestPriceFromAnySource`, `RemovePrice`, and `GetAllPrice` functions manage the lifecycle and retrieval of price data.

```go
func (k Keeper) SetPrice(ctx sdk.Context, price types.Price) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshal(&price)
store.Set(types.PriceKey(price.Asset, price.Source, price.Timestamp), b)
}

func (k Keeper) GetPrice(ctx sdk.Context, asset, source string, timestamp uint64) (val types.Price, found bool) {
store := ctx.KVStore(k.storeKey)
b := store.Get(types.PriceKey(asset, source, timestamp))
if b == nil {
return val, false
}
k.cdc.MustUnmarshal(b, &val)
return val, true
}

func (k Keeper) GetLatestPriceFromAssetAndSource(ctx sdk.Context, asset, source string) (val types.Price, found bool) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStoreReversePrefixIterator(store, types.PriceKeyPrefixAssetAndSource(asset, source))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.Price
k.cdc.MustUnmarshal(iterator.Value(), &val)
return val, true
}
return val, false
}

func (k Keeper) GetLatestPriceFromAnySource(ctx sdk.Context, asset string) (val types.Price, found bool) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStoreReversePrefixIterator(store, types.PriceKeyPrefixAsset(asset))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.Price
k.cdc.MustUnmarshal(iterator.Value(), &val)
return val, true
}
return val, false
}

func (k Keeper) RemovePrice(ctx sdk.Context, asset, source string, timestamp uint64) {
store := ctx.KVStore(k.storeKey)
store.Delete(types.PriceKey(asset, source, timestamp))
}

func (k Keeper) GetAllPrice(ctx sdk.Context) (list []types.Price) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PriceKeyPrefix))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.Price
k.cdc.MustUnmarshal(iterator.Value(), &val)
list = append(list, val)
}
return
}
```

### Managing Price Feeders

The `SetPriceFeeder`, `GetPriceFeeder`, `RemovePriceFeeder`, and `GetAllPriceFeeder` functions manage the lifecycle and retrieval of price feeder data.

```go
func (k Keeper) SetPriceFeeder(ctx sdk.Context, priceFeeder types.PriceFeeder) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PriceFeederKeyPrefix))
b := k.cdc.MustMarshal(&priceFeeder)
store.Set(types.PriceFeederKey(priceFeeder.Feeder), b)
}

func (

k Keeper) GetPriceFeeder(ctx sdk.Context, feeder string) (val types.PriceFeeder, found bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PriceFeederKeyPrefix))
b := store.Get(types.PriceFeederKey(feeder))
if b == nil {
return val, false
}
k.cdc.MustUnmarshal(b, &val)
return val, true
}

func (k Keeper) RemovePriceFeeder(ctx sdk.Context, feeder string) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PriceFeederKeyPrefix))
store.Delete(types.PriceFeederKey(feeder))
}

func (k Keeper) GetAllPriceFeeder(ctx sdk.Context) (list []types.PriceFeeder) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PriceFeederKeyPrefix))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.PriceFeeder
k.cdc.MustUnmarshal(iterator.Value(), &val)
list = append(list, val)
}
return
}
```
Loading

0 comments on commit fc0ee22

Please sign in to comment.