Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] WASM oracle querier #405

Merged
merged 1 commit into from
Sep 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import (

bankwasm "github.com/terra-project/core/x/bank/wasm"
marketwasm "github.com/terra-project/core/x/market/wasm"
oraclewasm "github.com/terra-project/core/x/oracle/wasm"
stakingwasm "github.com/terra-project/core/x/staking/wasm"
treasurywasm "github.com/terra-project/core/x/treasury/wasm"
)
Expand Down Expand Up @@ -253,6 +254,7 @@ func NewTerraApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest
wasm.WasmQueryRouteBank: bankwasm.NewWasmQuerier(app.bankKeeper),
wasm.WasmQueryRouteStaking: stakingwasm.NewWasmQuerier(app.stakingKeeper),
wasm.WasmQueryRouteMarket: marketwasm.NewWasmQuerier(app.marketKeeper),
wasm.WasmQueryRouteOracle: oraclewasm.NewWasmQuerier(app.oracleKeeper),
wasm.WasmQueryRouteTreasury: treasurywasm.NewWasmQuerier(app.treasuryKeeper),
wasm.WasmQueryRouteWasm: wasm.NewWasmQuerier(app.wasmKeeper),
})
Expand Down
92 changes: 92 additions & 0 deletions x/oracle/wasm/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package wasm

import (
"encoding/json"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

wasmTypes "github.com/CosmWasm/go-cosmwasm/types"

"github.com/terra-project/core/x/oracle/internal/keeper"
wasm "github.com/terra-project/core/x/wasm/exported"
)

var _ wasm.WasmQuerierInterface = WasmQuerier{}

// WasmQuerier - staking query interface for wasm contract
type WasmQuerier struct {
keeper keeper.Keeper
}

// NewWasmQuerier return bank wasm query interface
func NewWasmQuerier(keeper keeper.Keeper) WasmQuerier {
return WasmQuerier{keeper}
}

// Query - implement query function
func (WasmQuerier) Query(_ sdk.Context, _ wasmTypes.QueryRequest) ([]byte, error) { return nil, nil }

// ExchangeRateQueryParams query request params for exchange rates
type ExchangeRateQueryParams struct {
BaseDenom string `json:"base_denom"`
QuoteDenoms []string `json:"quote_denoms"`
}

// CosmosQuery custom query interface for oracle querier
type CosmosQuery struct {
ExchangeRates ExchangeRateQueryParams `json:"exchange_rates"`
}

// ExchangeRatesQueryResponseItem - exchange rates query response item
type exchangeRateItem struct {
ExchangeRate string `json:"exchange_rate"`
QuoteDenom string `json:"quote_denom"`
}

// ExchangeRatesQueryResponse - exchange rates query response for wasm module
type ExchangeRatesQueryResponse struct {
ExchangeRates []exchangeRateItem `json:"exchange_rates"`
BaseDenom string `json:"base_denom"`
}

// QueryCustom implements custom query interface
func (querier WasmQuerier) QueryCustom(ctx sdk.Context, data json.RawMessage) ([]byte, error) {
var params CosmosQuery
err := json.Unmarshal(data, &params)

if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
}

// LUNA / BASE_DENOM
baseDenomExchangeRate, err := querier.keeper.GetLunaExchangeRate(ctx, params.ExchangeRates.BaseDenom)
if err != nil {
return nil, err
}

var items []exchangeRateItem
for _, quoteDenom := range params.ExchangeRates.QuoteDenoms {
quoteDenomExchangeRate, err := querier.keeper.GetLunaExchangeRate(ctx, quoteDenom)
if err != nil {
return nil, err
}

// (BASE_DENOM / LUNA) / (DENOM / LUNA) = BASE_DENOM / QUOTE_DENOM
items = append(items, exchangeRateItem{
ExchangeRate: baseDenomExchangeRate.Quo(quoteDenomExchangeRate).String(),
QuoteDenom: quoteDenom,
})
}

bz, err := json.Marshal(ExchangeRatesQueryResponse{
BaseDenom: params.ExchangeRates.BaseDenom,
ExchangeRates: items,
})

if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
}

return bz, nil
}
90 changes: 90 additions & 0 deletions x/oracle/wasm/interface_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package wasm

import (
"encoding/json"
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"

core "github.com/terra-project/core/types"
"github.com/terra-project/core/x/oracle/internal/keeper"
)

func TestQueryExchangeRates(t *testing.T) {
input := keeper.CreateTestInput(t)

KRWExchangeRate := sdk.NewDec(1700)
USDExchangeRate := sdk.NewDecWithPrec(17, 1)
SDRExchangeRate := sdk.NewDecWithPrec(19, 1)
input.OracleKeeper.SetLunaExchangeRate(input.Ctx, core.MicroKRWDenom, KRWExchangeRate)
input.OracleKeeper.SetLunaExchangeRate(input.Ctx, core.MicroUSDDenom, USDExchangeRate)
input.OracleKeeper.SetLunaExchangeRate(input.Ctx, core.MicroSDRDenom, SDRExchangeRate)

querier := NewWasmQuerier(input.OracleKeeper)
var err error

// empty data will occur error
_, err = querier.QueryCustom(input.Ctx, []byte{})
require.Error(t, err)

// not existing quote denom query
queryParams := ExchangeRateQueryParams{
BaseDenom: core.MicroLunaDenom,
QuoteDenoms: []string{core.MicroMNTDenom},
}
bz, err := json.Marshal(CosmosQuery{
ExchangeRates: queryParams,
})
require.NoError(t, err)

res, err := querier.QueryCustom(input.Ctx, bz)
require.Error(t, err)

// not existing base denom query
queryParams = ExchangeRateQueryParams{
BaseDenom: core.MicroCNYDenom,
QuoteDenoms: []string{core.MicroKRWDenom, core.MicroUSDDenom, core.MicroSDRDenom},
}
bz, err = json.Marshal(CosmosQuery{
ExchangeRates: queryParams,
})
require.NoError(t, err)

res, err = querier.QueryCustom(input.Ctx, bz)
require.Error(t, err)

// valid query luna exchange rates
queryParams = ExchangeRateQueryParams{
BaseDenom: core.MicroKRWDenom,
QuoteDenoms: []string{core.MicroLunaDenom, core.MicroUSDDenom, core.MicroSDRDenom},
}
bz, err = json.Marshal(CosmosQuery{
ExchangeRates: queryParams,
})
require.NoError(t, err)

res, err = querier.QueryCustom(input.Ctx, bz)
require.NoError(t, err)

var exchangeRatesResponse ExchangeRatesQueryResponse
err = json.Unmarshal(res, &exchangeRatesResponse)
require.NoError(t, err)
require.Equal(t, exchangeRatesResponse, ExchangeRatesQueryResponse{
BaseDenom: core.MicroKRWDenom,
ExchangeRates: []exchangeRateItem{
{
ExchangeRate: KRWExchangeRate.String(),
QuoteDenom: core.MicroLunaDenom,
},
{
ExchangeRate: KRWExchangeRate.Quo(USDExchangeRate).String(),
QuoteDenom: core.MicroUSDDenom,
},
{
ExchangeRate: KRWExchangeRate.Quo(SDRExchangeRate).String(),
QuoteDenom: core.MicroSDRDenom,
},
},
})
}
10 changes: 2 additions & 8 deletions x/treasury/wasm/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ func TestQueryTaxRate(t *testing.T) {

var taxRateResponse TaxRateQueryResponse
require.NoError(t, json.Unmarshal(res, &taxRateResponse))

taxRateRes, err := sdk.NewDecFromStr(taxRateResponse.Rate)
require.NoError(t, err)
require.Equal(t, rate, taxRateRes)
require.Equal(t, rate.String(), taxRateResponse.Rate)
}

func TestQueryTaxCap(t *testing.T) {
Expand Down Expand Up @@ -71,8 +68,5 @@ func TestQueryTaxCap(t *testing.T) {

var taxCapResponse TaxCapQueryResponse
require.NoError(t, json.Unmarshal(res, &taxCapResponse))

taxCapRes, ok := sdk.NewIntFromString(taxCapResponse.Cap)
require.True(t, ok)
require.Equal(t, cap, taxCapRes)
require.Equal(t, cap.String(), taxCapResponse.Cap)
}
1 change: 1 addition & 0 deletions x/wasm/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const (
WasmQueryRouteBank = types.WasmQueryRouteBank
WasmQueryRouteStaking = types.WasmQueryRouteStaking
WasmQueryRouteMarket = types.WasmQueryRouteMarket
WasmQueryRouteOracle = types.WasmQueryRouteOracle
WasmQueryRouteTreasury = types.WasmQueryRouteTreasury
WasmQueryRouteWasm = types.WasmQueryRouteWasm
)
Expand Down
Loading