mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-25 15:55:18 +00:00
kava-3 to kava-4 pricefeed migration (#664)
This commit is contained in:
parent
6e923d70a4
commit
d577711056
@ -7,6 +7,8 @@ import (
|
||||
|
||||
v0_11bep3 "github.com/kava-labs/kava/x/bep3/legacy/v0_11"
|
||||
v0_9bep3 "github.com/kava-labs/kava/x/bep3/legacy/v0_9"
|
||||
v0_11pricefeed "github.com/kava-labs/kava/x/pricefeed"
|
||||
v0_9pricefeed "github.com/kava-labs/kava/x/pricefeed/legacy/v0_9"
|
||||
)
|
||||
|
||||
// MigrateBep3 migrates from a v0.9 (or v0.10) bep3 genesis state to a v0.11 bep3 genesis state
|
||||
@ -65,3 +67,32 @@ func MigrateBep3(oldGenState v0_9bep3.GenesisState) v0_11bep3.GenesisState {
|
||||
PreviousBlockTime: v0_11bep3.DefaultPreviousBlockTime,
|
||||
}
|
||||
}
|
||||
|
||||
// MigratePricefeed migrates from a v0.9 (or v0.10) pricefeed genesis state to a v0.11 pricefeed genesis state
|
||||
func MigratePricefeed(oldGenState v0_9pricefeed.GenesisState) v0_11pricefeed.GenesisState {
|
||||
var newMarkets v0_11pricefeed.Markets
|
||||
var newPostedPrices v0_11pricefeed.PostedPrices
|
||||
var oracles []sdk.AccAddress
|
||||
|
||||
for _, market := range oldGenState.Params.Markets {
|
||||
newMarket := v0_11pricefeed.NewMarket(market.MarketID, market.BaseAsset, market.QuoteAsset, market.Oracles, market.Active)
|
||||
newMarkets = append(newMarkets, newMarket)
|
||||
oracles = market.Oracles
|
||||
}
|
||||
// ------- add btc, xrp, busd markets --------
|
||||
btcSpotMarket := v0_11pricefeed.NewMarket("btc:usd", "btc", "usd", oracles, true)
|
||||
btcLiquidationMarket := v0_11pricefeed.NewMarket("btc:usd:30", "btc", "usd", oracles, true)
|
||||
xrpSpotMarket := v0_11pricefeed.NewMarket("xrp:usd", "xrp", "usd", oracles, true)
|
||||
xrpLiquidationMarket := v0_11pricefeed.NewMarket("xrp:usd:30", "xrp", "usd", oracles, true)
|
||||
busdSpotMarket := v0_11pricefeed.NewMarket("busd:usd", "busd", "usd", oracles, true)
|
||||
busdLiquidationMarket := v0_11pricefeed.NewMarket("busd:usd:30", "busd", "usd", oracles, true)
|
||||
newMarkets = append(newMarkets, btcSpotMarket, btcLiquidationMarket, xrpSpotMarket, xrpLiquidationMarket, busdSpotMarket, busdLiquidationMarket)
|
||||
|
||||
for _, price := range oldGenState.PostedPrices {
|
||||
newPrice := v0_11pricefeed.NewPostedPrice(price.MarketID, price.OracleAddress, price.Price, price.Expiry)
|
||||
newPostedPrices = append(newPostedPrices, newPrice)
|
||||
}
|
||||
newParams := v0_11pricefeed.NewParams(newMarkets)
|
||||
|
||||
return v0_11pricefeed.NewGenesisState(newParams, newPostedPrices)
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
|
||||
"github.com/kava-labs/kava/app"
|
||||
v0_9bep3 "github.com/kava-labs/kava/x/bep3/legacy/v0_9"
|
||||
v0_9pricefeed "github.com/kava-labs/kava/x/pricefeed/legacy/v0_9"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
@ -35,3 +36,16 @@ func TestMigrateBep3(t *testing.T) {
|
||||
err = newGenState.Validate()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestMigratePricefeed(t *testing.T) {
|
||||
bz, err := ioutil.ReadFile(filepath.Join("testdata", "pricefeed-v09.json"))
|
||||
require.NoError(t, err)
|
||||
var oldGenState v0_9pricefeed.GenesisState
|
||||
cdc := app.MakeCodec()
|
||||
require.NotPanics(t, func() {
|
||||
cdc.MustUnmarshalJSON(bz, &oldGenState)
|
||||
})
|
||||
newGenState := MigratePricefeed(oldGenState)
|
||||
err = newGenState.Validate()
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
152
migrate/v0_11/testdata/pricefeed-v09.json
vendored
Normal file
152
migrate/v0_11/testdata/pricefeed-v09.json
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
{
|
||||
"params": {
|
||||
"markets": [
|
||||
{
|
||||
"active": true,
|
||||
"base_asset": "bnb",
|
||||
"market_id": "bnb:usd",
|
||||
"oracles": [
|
||||
"kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl",
|
||||
"kava1tuxyepdrkwraa22k99w04c0wa64tgh70mv87fs",
|
||||
"kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg",
|
||||
"kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl",
|
||||
"kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp",
|
||||
"kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj",
|
||||
"kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
|
||||
"kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn",
|
||||
"kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy",
|
||||
"kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh"
|
||||
],
|
||||
"quote_asset": "usd"
|
||||
},
|
||||
{
|
||||
"active": true,
|
||||
"base_asset": "bnb",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracles": [
|
||||
"kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl",
|
||||
"kava1tuxyepdrkwraa22k99w04c0wa64tgh70mv87fs",
|
||||
"kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg",
|
||||
"kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl",
|
||||
"kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp",
|
||||
"kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj",
|
||||
"kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
|
||||
"kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn",
|
||||
"kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy",
|
||||
"kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh"
|
||||
],
|
||||
"quote_asset": "usd"
|
||||
}
|
||||
]
|
||||
},
|
||||
"posted_prices": [
|
||||
{
|
||||
"expiry": "2020-08-19T06:14:00Z",
|
||||
"market_id": "bnb:usd",
|
||||
"oracle_address": "kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
|
||||
"price": "22.925799999999998846"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:14:00Z",
|
||||
"market_id": "bnb:usd",
|
||||
"oracle_address": "kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy",
|
||||
"price": "22.932800000000000296"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-07-28T07:30:00Z",
|
||||
"market_id": "bnb:usd",
|
||||
"oracle_address": "kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp",
|
||||
"price": "20.084499999999998465"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:14:00Z",
|
||||
"market_id": "bnb:usd",
|
||||
"oracle_address": "kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg",
|
||||
"price": "22.932800000000000296"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:22:00Z",
|
||||
"market_id": "bnb:usd",
|
||||
"oracle_address": "kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj",
|
||||
"price": "22.866299999999998960"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:14:01Z",
|
||||
"market_id": "bnb:usd",
|
||||
"oracle_address": "kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl",
|
||||
"price": "22.932800000000000296"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:14:00Z",
|
||||
"market_id": "bnb:usd",
|
||||
"oracle_address": "kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn",
|
||||
"price": "22.932800000000000296"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:28:00Z",
|
||||
"market_id": "bnb:usd",
|
||||
"oracle_address": "kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh",
|
||||
"price": "22.836200000000001609"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:29:31Z",
|
||||
"market_id": "bnb:usd",
|
||||
"oracle_address": "kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl",
|
||||
"price": "22.834499999999998465"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:25:00Z",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracle_address": "kava19rjk5qmmwywnzfccwzyn02jywgpwjqf60afj92",
|
||||
"price": "22.967586666666665707"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:24:00Z",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracle_address": "kava1pt6q4kdmwawr3thm9cd82pq7hml8u84rd0f3jy",
|
||||
"price": "22.972826666666666284"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:22:30Z",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracle_address": "kava1ueak7nzesm3pnev6lngp6lgk0ry02djz8pjpcg",
|
||||
"price": "22.980756666666668053"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-07-28T08:30:00Z",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracle_address": "kava1ujfrlcd0ted58mzplnyxzklsw0sqevlgxndanp",
|
||||
"price": "20.056519999999995463"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:25:00Z",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracle_address": "kava17fatl3wzxvk4rwfu3tqsctdp5x9vute67j9ufj",
|
||||
"price": "22.967586666666665707"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:25:00Z",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracle_address": "kava12dyshua9nkvx9w8ywp72wdnzrc4t4mnnycz0dl",
|
||||
"price": "22.967586666666665707"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:25:00Z",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracle_address": "kava1xd39avn2f008jmvua0eupg39zsp2xn3wf802vn",
|
||||
"price": "22.967586666666665707"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:22:00Z",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracle_address": "kava13tpwqygswyzupqfggfgh9dmtgthgucn5wpfksh",
|
||||
"price": "22.972629999999998773"
|
||||
},
|
||||
{
|
||||
"expiry": "2020-08-19T06:24:31Z",
|
||||
"market_id": "bnb:usd:30",
|
||||
"oracle_address": "kava1sl62nqm89c780yxm3m9lp3tacmpnfljq6tytvl",
|
||||
"price": "22.967533333333335577"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,81 +1,78 @@
|
||||
package pricefeed
|
||||
|
||||
// DO NOT EDIT - generated by aliasgen tool (github.com/rhuairahrighairidh/aliasgen)
|
||||
|
||||
import (
|
||||
"github.com/kava-labs/kava/x/pricefeed/keeper"
|
||||
"github.com/kava-labs/kava/x/pricefeed/types"
|
||||
)
|
||||
|
||||
// autogenerated code using github.com/rigelrozanski/multitool
|
||||
// aliases generated for the following subdirectories:
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/pricefeed/types/
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/pricefeed/keeper/
|
||||
|
||||
// nolint
|
||||
const (
|
||||
EventTypeMarketPriceUpdated = types.EventTypeMarketPriceUpdated
|
||||
EventTypeOracleUpdatedPrice = types.EventTypeOracleUpdatedPrice
|
||||
EventTypeNoValidPrices = types.EventTypeNoValidPrices
|
||||
AttributeValueCategory = types.AttributeValueCategory
|
||||
AttributeExpiry = types.AttributeExpiry
|
||||
AttributeMarketID = types.AttributeMarketID
|
||||
AttributeMarketPrice = types.AttributeMarketPrice
|
||||
AttributeOracle = types.AttributeOracle
|
||||
AttributeExpiry = types.AttributeExpiry
|
||||
ModuleName = types.ModuleName
|
||||
StoreKey = types.StoreKey
|
||||
RouterKey = types.RouterKey
|
||||
QuerierRoute = types.QuerierRoute
|
||||
AttributeValueCategory = types.AttributeValueCategory
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
TypeMsgPostPrice = types.TypeMsgPostPrice
|
||||
EventTypeMarketPriceUpdated = types.EventTypeMarketPriceUpdated
|
||||
EventTypeNoValidPrices = types.EventTypeNoValidPrices
|
||||
EventTypeOracleUpdatedPrice = types.EventTypeOracleUpdatedPrice
|
||||
MaxExpiry = types.MaxExpiry
|
||||
ModuleName = types.ModuleName
|
||||
QuerierRoute = types.QuerierRoute
|
||||
QueryGetParams = types.QueryGetParams
|
||||
QueryMarkets = types.QueryMarkets
|
||||
QueryOracles = types.QueryOracles
|
||||
QueryRawPrices = types.QueryRawPrices
|
||||
QueryPrice = types.QueryPrice
|
||||
MaxExpiry = types.MaxExpiry
|
||||
QueryRawPrices = types.QueryRawPrices
|
||||
RouterKey = types.RouterKey
|
||||
StoreKey = types.StoreKey
|
||||
TypeMsgPostPrice = types.TypeMsgPostPrice
|
||||
)
|
||||
|
||||
// nolint
|
||||
var (
|
||||
// functions aliases
|
||||
// function aliases
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
RegisterCodec = types.RegisterCodec
|
||||
ErrEmptyInput = types.ErrEmptyInput
|
||||
ErrExpired = types.ErrExpired
|
||||
ErrNoValidPrice = types.ErrNoValidPrice
|
||||
ErrInvalidMarket = types.ErrInvalidMarket
|
||||
ErrInvalidOracle = types.ErrInvalidOracle
|
||||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
CurrentPriceKey = types.CurrentPriceKey
|
||||
RawPriceKey = types.RawPriceKey
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
DefaultParams = types.DefaultParams
|
||||
NewCurrentPrice = types.NewCurrentPrice
|
||||
NewPostedPrice = types.NewPostedPrice
|
||||
NewGenesisState = types.NewGenesisState
|
||||
NewMarket = types.NewMarket
|
||||
NewMsgPostPrice = types.NewMsgPostPrice
|
||||
NewParams = types.NewParams
|
||||
DefaultParams = types.DefaultParams
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
NewPostedPrice = types.NewPostedPrice
|
||||
NewQueryWithMarketIDParams = types.NewQueryWithMarketIDParams
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
RawPriceKey = types.RawPriceKey
|
||||
RegisterCodec = types.RegisterCodec
|
||||
|
||||
// variable aliases
|
||||
ModuleCdc = types.ModuleCdc
|
||||
CurrentPricePrefix = types.CurrentPricePrefix
|
||||
RawPriceFeedPrefix = types.RawPriceFeedPrefix
|
||||
KeyMarkets = types.KeyMarkets
|
||||
DefaultMarkets = types.DefaultMarkets
|
||||
ErrAssetNotFound = types.ErrAssetNotFound
|
||||
ErrEmptyInput = types.ErrEmptyInput
|
||||
ErrExpired = types.ErrExpired
|
||||
ErrInvalidMarket = types.ErrInvalidMarket
|
||||
ErrInvalidOracle = types.ErrInvalidOracle
|
||||
ErrNoValidPrice = types.ErrNoValidPrice
|
||||
KeyMarkets = types.KeyMarkets
|
||||
ModuleCdc = types.ModuleCdc
|
||||
RawPriceFeedPrefix = types.RawPriceFeedPrefix
|
||||
)
|
||||
|
||||
// nolint
|
||||
type (
|
||||
Keeper = keeper.Keeper
|
||||
CurrentPrice = types.CurrentPrice
|
||||
CurrentPrices = types.CurrentPrices
|
||||
GenesisState = types.GenesisState
|
||||
Market = types.Market
|
||||
Markets = types.Markets
|
||||
CurrentPrice = types.CurrentPrice
|
||||
PostedPrice = types.PostedPrice
|
||||
PostedPrices = types.PostedPrices
|
||||
SortDecs = types.SortDecs
|
||||
MsgPostPrice = types.MsgPostPrice
|
||||
Params = types.Params
|
||||
PostedPrice = types.PostedPrice
|
||||
PostedPrices = types.PostedPrices
|
||||
QueryWithMarketIDParams = types.QueryWithMarketIDParams
|
||||
SortDecs = types.SortDecs
|
||||
)
|
||||
|
@ -9,11 +9,13 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, gs GenesisState) {
|
||||
// Set the markets and oracles from params
|
||||
keeper.SetParams(ctx, gs.Params)
|
||||
|
||||
// Iterate through the posted prices and set them in the store
|
||||
// Iterate through the posted prices and set them in the store if they are not expired
|
||||
for _, pp := range gs.PostedPrices {
|
||||
_, err := keeper.SetPrice(ctx, pp.OracleAddress, pp.MarketID, pp.Price, pp.Expiry)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
if pp.Expiry.After(ctx.BlockTime()) {
|
||||
_, err := keeper.SetPrice(ctx, pp.OracleAddress, pp.MarketID, pp.Price, pp.Expiry)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
params := keeper.GetParams(ctx)
|
||||
|
193
x/pricefeed/legacy/v0_9/types.go
Normal file
193
x/pricefeed/legacy/v0_9/types.go
Normal file
@ -0,0 +1,193 @@
|
||||
package v0_9
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
// GenesisState - pricefeed state that must be provided at genesis
|
||||
type GenesisState struct {
|
||||
Params Params `json:"params" yaml:"params"`
|
||||
PostedPrices PostedPrices `json:"posted_prices" yaml:"posted_prices"`
|
||||
}
|
||||
|
||||
// NewGenesisState creates a new genesis state for the pricefeed module
|
||||
func NewGenesisState(p Params, pp []PostedPrice) GenesisState {
|
||||
return GenesisState{
|
||||
Params: p,
|
||||
PostedPrices: pp,
|
||||
}
|
||||
}
|
||||
|
||||
type Params struct {
|
||||
Markets Markets `json:"markets" yaml:"markets"` // Array containing the markets supported by the pricefeed
|
||||
}
|
||||
|
||||
type Market struct {
|
||||
// TODO: rename to ID
|
||||
MarketID string `json:"market_id" yaml:"market_id"`
|
||||
BaseAsset string `json:"base_asset" yaml:"base_asset"`
|
||||
QuoteAsset string `json:"quote_asset" yaml:"quote_asset"`
|
||||
Oracles []sdk.AccAddress `json:"oracles" yaml:"oracles"`
|
||||
Active bool `json:"active" yaml:"active"`
|
||||
}
|
||||
|
||||
// String implement fmt.Stringer
|
||||
func (m Market) String() string {
|
||||
return fmt.Sprintf(`Asset:
|
||||
Market ID: %s
|
||||
Base Asset: %s
|
||||
Quote Asset: %s
|
||||
Oracles: %s
|
||||
Active: %t`,
|
||||
m.MarketID, m.BaseAsset, m.QuoteAsset, m.Oracles, m.Active)
|
||||
}
|
||||
|
||||
// Validate performs a basic validation of the market params
|
||||
func (m Market) Validate() error {
|
||||
if strings.TrimSpace(m.MarketID) == "" {
|
||||
return errors.New("market id cannot be blank")
|
||||
}
|
||||
if err := sdk.ValidateDenom(m.BaseAsset); err != nil {
|
||||
return fmt.Errorf("invalid base asset: %w", err)
|
||||
}
|
||||
if err := sdk.ValidateDenom(m.QuoteAsset); err != nil {
|
||||
return fmt.Errorf("invalid quote asset: %w", err)
|
||||
}
|
||||
seenOracles := make(map[string]bool)
|
||||
for i, oracle := range m.Oracles {
|
||||
if oracle.Empty() {
|
||||
return fmt.Errorf("oracle %d is empty", i)
|
||||
}
|
||||
if seenOracles[oracle.String()] {
|
||||
return fmt.Errorf("duplicated oracle %s", oracle)
|
||||
}
|
||||
seenOracles[oracle.String()] = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Markets array type for oracle
|
||||
type Markets []Market
|
||||
|
||||
// Validate checks if all the markets are valid and there are no duplicated
|
||||
// entries.
|
||||
func (ms Markets) Validate() error {
|
||||
seenMarkets := make(map[string]bool)
|
||||
for _, m := range ms {
|
||||
if seenMarkets[m.MarketID] {
|
||||
return fmt.Errorf("duplicated market %s", m.MarketID)
|
||||
}
|
||||
if err := m.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
seenMarkets[m.MarketID] = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer
|
||||
func (ms Markets) String() string {
|
||||
out := "Markets:\n"
|
||||
for _, m := range ms {
|
||||
out += fmt.Sprintf("%s\n", m.String())
|
||||
}
|
||||
return strings.TrimSpace(out)
|
||||
}
|
||||
|
||||
// CurrentPrice struct that contains the metadata of a current price for a particular market in the pricefeed module.
|
||||
type CurrentPrice struct {
|
||||
MarketID string `json:"market_id" yaml:"market_id"`
|
||||
Price sdk.Dec `json:"price" yaml:"price"`
|
||||
}
|
||||
|
||||
// NewCurrentPrice returns an instance of CurrentPrice
|
||||
func NewCurrentPrice(marketID string, price sdk.Dec) CurrentPrice {
|
||||
return CurrentPrice{MarketID: marketID, Price: price}
|
||||
}
|
||||
|
||||
// CurrentPrices type for an array of CurrentPrice
|
||||
type CurrentPrices []CurrentPrice
|
||||
|
||||
// PostedPrice price for market posted by a specific oracle
|
||||
type PostedPrice struct {
|
||||
MarketID string `json:"market_id" yaml:"market_id"`
|
||||
OracleAddress sdk.AccAddress `json:"oracle_address" yaml:"oracle_address"`
|
||||
Price sdk.Dec `json:"price" yaml:"price"`
|
||||
Expiry time.Time `json:"expiry" yaml:"expiry"`
|
||||
}
|
||||
|
||||
// NewPostedPrice returns a new PostedPrice
|
||||
func NewPostedPrice(marketID string, oracle sdk.AccAddress, price sdk.Dec, expiry time.Time) PostedPrice {
|
||||
return PostedPrice{
|
||||
MarketID: marketID,
|
||||
OracleAddress: oracle,
|
||||
Price: price,
|
||||
Expiry: expiry,
|
||||
}
|
||||
}
|
||||
|
||||
// Validate performs a basic check of a PostedPrice params.
|
||||
func (pp PostedPrice) Validate() error {
|
||||
if strings.TrimSpace(pp.MarketID) == "" {
|
||||
return errors.New("market id cannot be blank")
|
||||
}
|
||||
if pp.OracleAddress.Empty() {
|
||||
return errors.New("oracle address cannot be empty")
|
||||
}
|
||||
if pp.Price.IsNegative() {
|
||||
return fmt.Errorf("posted price cannot be negative %s", pp.Price)
|
||||
}
|
||||
if pp.Expiry.IsZero() {
|
||||
return errors.New("expiry time cannot be zero")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PostedPrices type for an array of PostedPrice
|
||||
type PostedPrices []PostedPrice
|
||||
|
||||
// Validate checks if all the posted prices are valid and there are no duplicated
|
||||
// entries.
|
||||
func (pps PostedPrices) Validate() error {
|
||||
seenPrices := make(map[string]bool)
|
||||
for _, pp := range pps {
|
||||
if pp.OracleAddress != nil && seenPrices[pp.MarketID+pp.OracleAddress.String()] {
|
||||
return fmt.Errorf("duplicated posted price for marked id %s and oracle address %s", pp.MarketID, pp.OracleAddress)
|
||||
}
|
||||
|
||||
if err := pp.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
seenPrices[pp.MarketID+pp.OracleAddress.String()] = true
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// implement fmt.Stringer
|
||||
func (cp CurrentPrice) String() string {
|
||||
return strings.TrimSpace(fmt.Sprintf(`Market ID: %s
|
||||
Price: %s`, cp.MarketID, cp.Price))
|
||||
}
|
||||
|
||||
// implement fmt.Stringer
|
||||
func (pp PostedPrice) String() string {
|
||||
return strings.TrimSpace(fmt.Sprintf(`Market ID: %s
|
||||
Oracle Address: %s
|
||||
Price: %s
|
||||
Expiry: %s`, pp.MarketID, pp.OracleAddress, pp.Price, pp.Expiry))
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer
|
||||
func (ps PostedPrices) String() string {
|
||||
out := "Posted Prices:\n"
|
||||
for _, p := range ps {
|
||||
out += fmt.Sprintf("%s\n", p.String())
|
||||
}
|
||||
return strings.TrimSpace(out)
|
||||
}
|
@ -19,6 +19,17 @@ type Market struct {
|
||||
Active bool `json:"active" yaml:"active"`
|
||||
}
|
||||
|
||||
// NewMarket returns a new Market
|
||||
func NewMarket(id, base, quote string, oracles []sdk.AccAddress, active bool) Market {
|
||||
return Market{
|
||||
MarketID: id,
|
||||
BaseAsset: base,
|
||||
QuoteAsset: quote,
|
||||
Oracles: oracles,
|
||||
Active: active,
|
||||
}
|
||||
}
|
||||
|
||||
// String implement fmt.Stringer
|
||||
func (m Market) String() string {
|
||||
return fmt.Sprintf(`Asset:
|
||||
|
Loading…
Reference in New Issue
Block a user