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

feat: include flag versioned in query markets to allow to query disabled markets #1585

Merged
merged 24 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b6460b7
make market inmutable and include market version
jgimeno Aug 25, 2023
0bdef35
temp commit after adding market version
jgimeno Aug 28, 2023
18bd1ec
Merge branch 'master' into feature/market-version
jgimeno Aug 28, 2023
ccf45db
make test pass
jgimeno Aug 30, 2023
14051bf
add genesis part
jgimeno Aug 30, 2023
a789617
Merge remote-tracking branch 'origin/master' into feature/market-version
jgimeno Sep 7, 2023
93f9c18
create changelog
jgimeno Sep 7, 2023
d2e631e
add option for market creation when another one is closed
jgimeno Sep 7, 2023
52f61d3
make tests pass
jgimeno Sep 8, 2023
e47c89b
make linter
jgimeno Sep 8, 2023
4a8252a
Merge branch 'master' into feature/market-version
jgimeno Sep 11, 2023
e5e5d20
fix bug
jgimeno Sep 13, 2023
03524f2
Merge branch 'feature/market-version' of github.com:NibiruChain/nibir…
jgimeno Sep 13, 2023
824b4f5
Merge branch 'master' into feature/market-version
jgimeno Sep 13, 2023
5f5fdb3
add convenience method for saving market
jgimeno Sep 13, 2023
6894f76
Merge branch 'feature/market-version' of github.com:NibiruChain/nibir…
jgimeno Sep 13, 2023
c08dd53
add new methods
jgimeno Sep 13, 2023
83f6f97
remove comments
jgimeno Sep 13, 2023
1e65fc0
add query versioned markets
jgimeno Sep 15, 2023
bee3026
update query markets
jgimeno Sep 15, 2023
5f54d0b
update changelog
jgimeno Sep 15, 2023
004b616
Merge branch 'master' into feature/market-version-query
jgimeno Sep 15, 2023
c7e3d5e
Merge branch 'master' into feature/market-version-query
Unique-Divine Sep 19, 2023
d405bf9
docs(perp): small docs improvements for CLI and proto comment
Unique-Divine Sep 19, 2023
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* [#1503](https://github.com/NibiruChain/nibiru/pull/1503) - feat(wasm): add Oracle Exchange Rate query for wasm
* [#1543](https://github.com/NibiruChain/nibiru/pull/1543) - epic(devgas): devgas module for incentivizing smart contract
* [#1559](https://github.com/NibiruChain/nibiru/pull/1559) - feat: add versions to markets to allow to disable them
* [#1585](https://github.com/NibiruChain/nibiru/pull/1585) - feat: include flag versioned in query markets to allow to query disabled markets

### Bug Fixes

Expand Down Expand Up @@ -649,4 +650,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Testing

* [#695](https://github.com/NibiruChain/nibiru/pull/695) Add `OpenPosition` integration tests.
* [#692](https://github.com/NibiruChain/nibiru/pull/692) Add test coverage for Perp MsgServer methods.
* [#692](https://github.com/NibiruChain/nibiru/pull/692) Add test coverage for Perp MsgServer methods.
12 changes: 8 additions & 4 deletions proto/nibiru/perp/v2/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import "nibiru/perp/v2/state.proto";
option go_package = "github.com/NibiruChain/nibiru/x/perp/v2/types";

// GenesisState defines the perp module's genesis state.
// Thge genesis state is used not only to start the network but also useful for
// exporting and importing state during network upgrades.
message GenesisState {
repeated Market markets = 2 [ (gogoproto.nullable) = false ];

repeated GenesisMarketLastVersion market_last_versions = 8 [ (gogoproto.nullable) = false ];

repeated AMM amms = 3 [ (gogoproto.nullable) = false ];

repeated Position positions = 4 [ (gogoproto.nullable) = false ];
Expand All @@ -34,9 +34,13 @@ message GenesisState {
(gogoproto.nullable) = false
];
}

repeated GenesisMarketLastVersion market_last_versions = 8
[ (gogoproto.nullable) = false ];
}

// GenesisMarketLastVersion is the last version including pair only used for genesis
// GenesisMarketLastVersion is the last version including pair only used for
// genesis
message GenesisMarketLastVersion {
string pair = 1 [
(gogoproto.customtype) =
Expand All @@ -45,4 +49,4 @@ message GenesisMarketLastVersion {
];

uint64 version = 2;
}
}
4 changes: 3 additions & 1 deletion proto/nibiru/perp/v2/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,9 @@ message AmmMarket {
AMM amm = 2 [ (gogoproto.nullable) = false ];
}

message QueryMarketsRequest {}
message QueryMarketsRequest {
bool versioned = 1;
}

message QueryMarketsResponse {
repeated AmmMarket amm_markets = 1 [ (gogoproto.nullable) = false ];
Expand Down
91 changes: 91 additions & 0 deletions proto/nibiru/tokenfactory/v1/state.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
syntax = "proto3";

package nibiru.tokenfactory.v1;

import "gogoproto/gogo.proto";
import "cosmos_proto/cosmos.proto";
import "cosmos/base/v1beta1/coin.proto";

option go_package = "github.com/NibiruChain/nibiru/x/tokenfactory/types";

// DenomAuthorityMetadata specifies metadata foraddresses that have specific
// capabilities over a token factory denom. Right now there is only one Admin
// permission, but is planned to be extended to the future.
message DenomAuthorityMetadata {
option (gogoproto.equal) = true;

// Admin: Bech32 address of the admin for the tokefactory denom. Can be empty
// for no admin.
string admin = 1 [ (gogoproto.moretags) = "yaml:\"admin\"" ];
}

// ModuleParams defines the parameters for the tokenfactory module.
//
// ### On Denom Creation Costs
//
// We'd like for fees to be paid by the user/signer of a ransaction, but in many
// casess, token creation is abstracted away behind a smart contract. Setting a
// nonzero `denom_creation_fee` would force each contract to handle collecting
// and paying a fees for denom (factory/{contract-addr}/{subdenom}) creation on
// behalf of the end user.
//
// For IBC token transfers, it's unclear who should pay the fee—the contract,
// the relayer, or the original sender?
// > "Charging fees will mess up composability, the same way Terra transfer tax
// caused all kinds of headaches for contract devs." - @ethanfrey
//
// ### Recommended Solution
//
// Have the end user (signer) pay fees directly in the form of higher gas costs.
// This way, contracts won't need to handle collecting or paying fees. And for
// IBC, the gas costs are already paid by the original sender and can be
// estimated by the relayer. It's easier to tune gas costs to make spam
// prohibitively expensive since there are per-transaction and per-block gas
// limits.
//
// See https://github.com/CosmWasm/token-factory/issues/11 for the initial
// discussion of the issue with @ethanfrey and @valardragon.
message ModuleParams {
// Adds gas consumption to the execution of `MsgCreateDenom` as a method of
// spam prevention. Defaults to 10 NIBI.
uint64 denom_creation_gas_consume = 1
[ (gogoproto.moretags) = "yaml:\"denom_creation_gas_consume\"" ];
}

// TFDenom is a token factory (TF) denom. The canonical representation is
// "tf/{creator}/{subdenom}", its unique denomination in the x/bank module.
message TFDenom {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.stringer) = false;

// Creator: Bech32 address of the creator of the denom.
string creator = 1;
// Subdenom: Unique suffix of a token factory denom. A subdenom is specific
// to a given creator. It is the name given during a token factory "Mint".
string subdenom = 2;
}

// ----------------------------------------------
// Genesis
// ----------------------------------------------

// GenesisState for the Token Factory module.
message GenesisState {
ModuleParams params = 1 [ (gogoproto.nullable) = false ];

repeated GenesisDenom factory_denoms = 2 [
(gogoproto.moretags) = "yaml:\"factory_denoms\"",
(gogoproto.nullable) = false
];
}

// GenesisDenom defines a tokenfactory denoms in the genesis state.
message GenesisDenom {
option (gogoproto.equal) = true;

string denom = 1 [ (gogoproto.moretags) = "yaml:\"denom\"" ];
DenomAuthorityMetadata authority_metadata = 2 [
(gogoproto.moretags) = "yaml:\"authority_metadata\"",
(gogoproto.nullable) = false
];
}
21 changes: 18 additions & 3 deletions x/perp/v2/client/cli/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import (
types "github.com/NibiruChain/nibiru/x/perp/v2/types"
)

const FlagVersioned = "versioned"

// GetQueryCmd returns the cli query commands for this module
func GetQueryCmd() *cobra.Command {
// Group stablecoin queries under a subcommand
Expand Down Expand Up @@ -146,8 +148,12 @@ func CmdQueryModuleAccounts() *cobra.Command {
func CmdQueryMarkets() *cobra.Command {
cmd := &cobra.Command{
Use: "markets",
Short: "query all market info",
Args: cobra.NoArgs,
Short: "Query all market info",
Long: `
Query all market info. By default, only active tradable markets are shown.
If --versioned is to to true, the query will return all markets including the
inactive ones.`,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
Expand All @@ -156,7 +162,14 @@ func CmdQueryMarkets() *cobra.Command {

queryClient := types.NewQueryClient(clientCtx)

res, err := queryClient.QueryMarkets(cmd.Context(), &types.QueryMarketsRequest{})
versioned, err := cmd.Flags().GetBool(FlagVersioned)
if err != nil {
return err
}

res, err := queryClient.QueryMarkets(cmd.Context(), &types.QueryMarketsRequest{
Versioned: versioned,
})
if err != nil {
return err
}
Expand All @@ -165,6 +178,8 @@ func CmdQueryMarkets() *cobra.Command {
},
}

cmd.Flags().Bool(FlagVersioned, false, "toggles whether to include inactive markets")

flags.AddQueryFlagsToCmd(cmd)

return cmd
Expand Down
31 changes: 22 additions & 9 deletions x/perp/v2/integration/action/market.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (c createMarketAction) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context
}

// CreateCustomMarket creates a market with custom parameters
func CreateCustomMarket(pair asset.Pair, marketModifiers ...marketModifier) action.Action {
func CreateCustomMarket(pair asset.Pair, marketModifiers ...MarketModifier) action.Action {
market := types.DefaultMarket(pair)
amm := types.AMM{
Pair: pair,
Expand All @@ -75,52 +75,65 @@ func CreateCustomMarket(pair asset.Pair, marketModifiers ...marketModifier) acti
}
}

type marketModifier func(market *types.Market, amm *types.AMM)
type MarketModifier func(market *types.Market, amm *types.AMM)

func WithPrepaidBadDebt(amount sdkmath.Int) marketModifier {
func WithPrepaidBadDebt(amount sdkmath.Int) MarketModifier {
return func(market *types.Market, amm *types.AMM) {
market.PrepaidBadDebt = sdk.NewCoin(market.Pair.QuoteDenom(), amount)
}
}

func WithPricePeg(newValue sdk.Dec) marketModifier {
func WithPricePeg(newValue sdk.Dec) MarketModifier {
return func(market *types.Market, amm *types.AMM) {
amm.PriceMultiplier = newValue
}
}

func WithTotalLong(amount sdk.Dec) marketModifier {
func WithTotalLong(amount sdk.Dec) MarketModifier {
return func(market *types.Market, amm *types.AMM) {
amm.TotalLong = amount
}
}

func WithTotalShort(amount sdk.Dec) marketModifier {
func WithTotalShort(amount sdk.Dec) MarketModifier {
return func(market *types.Market, amm *types.AMM) {
amm.TotalShort = amount
}
}

func WithSqrtDepth(amount sdk.Dec) marketModifier {
func WithSqrtDepth(amount sdk.Dec) MarketModifier {
return func(market *types.Market, amm *types.AMM) {
amm.SqrtDepth = amount
amm.BaseReserve = amount
amm.QuoteReserve = amount
}
}

func WithLatestMarketCPF(amount sdk.Dec) marketModifier {
func WithLatestMarketCPF(amount sdk.Dec) MarketModifier {
return func(market *types.Market, amm *types.AMM) {
market.LatestCumulativePremiumFraction = amount
}
}

func WithMaxFundingRate(amount sdk.Dec) marketModifier {
func WithMaxFundingRate(amount sdk.Dec) MarketModifier {
return func(market *types.Market, amm *types.AMM) {
market.MaxFundingRate = amount
}
}

func WithVersion(version uint64) MarketModifier {
return func(market *types.Market, amm *types.AMM) {
market.Version = version
amm.Version = version
}
}

func WithEnabled(enabled bool) MarketModifier {
return func(market *types.Market, amm *types.AMM) {
market.Enabled = enabled
}
}

type editPriceMultiplier struct {
pair asset.Pair
newValue sdk.Dec
Expand Down
25 changes: 22 additions & 3 deletions x/perp/v2/integration/action/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@ func (q queryPositionNotFound) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Cont
Trader: q.traderAddress.String(),
})
if !errors.Is(err, collections.ErrNotFound) {
return ctx, fmt.Errorf("expected position not found, but found a position for pair %s, trader %s", q.pair, q.traderAddress), false
return ctx, fmt.Errorf(
"expected position not found, but found a position for pair %s, trader %s",
q.pair,
q.traderAddress,
), false
}

return ctx, nil, false
Expand All @@ -145,13 +149,16 @@ func QueryPositionNotFound(pair asset.Pair, traderAddress sdk.AccAddress) action
}

type queryMarkets struct {
versioned bool
allResponseCheckers []QueryMarketsChecker
}

func (q queryMarkets) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, error, bool) {
queryServer := keeper.NewQuerier(app.PerpKeeperV2)

resp, err := queryServer.QueryMarkets(sdk.WrapSDKContext(ctx), &types.QueryMarketsRequest{})
resp, err := queryServer.QueryMarkets(sdk.WrapSDKContext(ctx), &types.QueryMarketsRequest{
Versioned: q.versioned,
})
if err != nil {
return ctx, err, false
}
Expand All @@ -165,8 +172,10 @@ func (q queryMarkets) Do(app *app.NibiruApp, ctx sdk.Context) (sdk.Context, erro
return ctx, nil, false
}

func QueryMarkets(responseCheckers ...QueryMarketsChecker) action.Action {
// QueryMarkets queries all markets, versioned contains active and inactive markets
func QueryMarkets(versioned bool, responseCheckers ...QueryMarketsChecker) action.Action {
return queryMarkets{
versioned: versioned,
allResponseCheckers: responseCheckers,
}
}
Expand All @@ -188,6 +197,16 @@ func QueryMarkets_MarketsShouldContain(expectedMarket types.Market) QueryMarkets
}
}

func QueryMarkets_ShouldLength(length int) QueryMarketsChecker {
return func(resp []types.AmmMarket) error {
if len(resp) != length {
return fmt.Errorf("expected markets to have length %d, got %d", length, len(resp))
}

return nil
}
}

type queryModuleAccounts struct {
allResponseCheckers []QueryModuleAccountsChecker
}
Expand Down
4 changes: 2 additions & 2 deletions x/perp/v2/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,15 +164,15 @@ func (q queryServer) ModuleAccounts(
}

func (q queryServer) QueryMarkets(
goCtx context.Context, _ *types.QueryMarketsRequest,
goCtx context.Context, req *types.QueryMarketsRequest,
) (*types.QueryMarketsResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

var ammMarkets []types.AmmMarket
markets := q.k.Markets.Iterate(ctx, collections.Range[collections.Pair[asset.Pair, uint64]]{}).Values()
for _, market := range markets {
// disabled markets are not returned
if !market.Enabled {
if !req.Versioned && !market.Enabled {
continue
}

Expand Down
16 changes: 15 additions & 1 deletion x/perp/v2/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ func TestQueryMarkets(t *testing.T) {
),
).
Then(
QueryMarkets(QueryMarkets_MarketsShouldContain(types.DefaultMarket(pair))),
QueryMarkets(false, QueryMarkets_MarketsShouldContain(types.DefaultMarket(pair))),
QueryModuleAccounts(QueryModuleAccounts_ModulesBalanceShouldBe(
map[string]sdk.Coins{
"perp_ef": sdk.NewCoins(
Expand All @@ -358,6 +358,20 @@ func TestQueryMarkets(t *testing.T) {
},
)),
),
TC("versioned, all markets (active and inactive)").Given(
CreateCustomMarket("BTC:USD", WithVersion(1), WithEnabled(true)),
CreateCustomMarket("ETC:USD", WithVersion(1), WithEnabled(false)),
CreateCustomMarket("ETC:USD", WithVersion(2), WithEnabled(true)),
).Then(
QueryMarkets(true, QueryMarkets_ShouldLength(3)),
),
TC("not versioned, only active markets").Given(
CreateCustomMarket("BTC:USD", WithVersion(1), WithEnabled(true)),
CreateCustomMarket("ETC:USD", WithVersion(1), WithEnabled(false)),
CreateCustomMarket("ETC:USD", WithVersion(2), WithEnabled(true)),
).Then(
QueryMarkets(true, QueryMarkets_ShouldLength(3)),
),
}

NewTestSuite(t).WithTestCases(tc...).Run()
Expand Down
Loading
Loading