From 5a43bd6a8ae04ac56610e9ee759a7ffa13712388 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 11 Oct 2022 16:42:17 -0400 Subject: [PATCH 01/12] add stop loss and stop limit orders --- proto/dex/enums.proto | 2 + proto/dex/genesis.proto | 2 + proto/dex/order.proto | 9 + proto/dex/trigger_book.proto | 18 + wasmbinding/test/encoder_test.go | 2 + x/dex/cache/order.go | 16 + x/dex/client/cli/tx/tx_place_orders.go | 13 + x/dex/contract/execution.go | 59 +++ x/dex/exchange/helpers.go | 4 + x/dex/exchange/limit_order.go | 8 + x/dex/exchange/market_order.go | 23 +- x/dex/genesis.go | 4 + .../msgserver/msg_server_place_orders.go | 4 + .../msgserver/msg_server_place_orders_test.go | 14 +- x/dex/keeper/trigger_book.go | 62 +++ x/dex/types/enums.pb.go | 59 +-- x/dex/types/genesis.pb.go | 122 +++-- x/dex/types/keys.go | 11 + x/dex/types/order.pb.go | 180 ++++++-- x/dex/types/trigger_book.pb.go | 434 ++++++++++++++++++ x/dex/types/utils/alias.go | 6 + 21 files changed, 949 insertions(+), 103 deletions(-) create mode 100644 proto/dex/trigger_book.proto create mode 100644 x/dex/keeper/trigger_book.go create mode 100644 x/dex/types/trigger_book.pb.go diff --git a/proto/dex/enums.proto b/proto/dex/enums.proto index 76a88dd05b..49588e2dcf 100644 --- a/proto/dex/enums.proto +++ b/proto/dex/enums.proto @@ -19,6 +19,8 @@ enum OrderType { LIQUIDATION = 2; FOKMARKET = 3; // fill-or-kill market order FOKMARKETBYVALUE = 4; // fill-or-kill market by value order + STOPLOSS = 5; + STOPLIMIT = 6; } enum Unit { diff --git a/proto/dex/genesis.proto b/proto/dex/genesis.proto index d3cf6c842e..505e515177 100644 --- a/proto/dex/genesis.proto +++ b/proto/dex/genesis.proto @@ -7,6 +7,7 @@ import "dex/long_book.proto"; import "dex/short_book.proto"; import "dex/twap.proto"; import "dex/tick_size.proto"; +import "dex/trigger_book.proto"; // this line is used by starport scaffolding # genesis/proto/import option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; @@ -19,5 +20,6 @@ message GenesisState { repeated Twap twapList = 4; repeated TickSize tickSizeList = 5; // if null, then no restriction, todo(zw) should set it to not nullable? uint64 lastEpoch = 6; + repeated TriggerBook triggerBookList = 7 [(gogoproto.nullable) = false]; // this line is used by starport scaffolding # genesis/proto/state } diff --git a/proto/dex/order.proto b/proto/dex/order.proto index fed167a84f..8b366eb6e6 100644 --- a/proto/dex/order.proto +++ b/proto/dex/order.proto @@ -59,6 +59,15 @@ message Order { (gogoproto.nullable) = false, (gogoproto.jsontag) = "nominal" ]; + string triggerPrice = 14 [ + (gogoproto.moretags) = "yaml:\"trigger_price\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "trigger_price" + ]; + bool triggerStatus = 15 [ + (gogoproto.jsontag) = "trigger_status" + ]; } message Cancellation { diff --git a/proto/dex/trigger_book.proto b/proto/dex/trigger_book.proto new file mode 100644 index 0000000000..0076d749c8 --- /dev/null +++ b/proto/dex/trigger_book.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; +import "dex/order.proto"; +import "gogoproto/gogo.proto"; + +message TriggerBook { + repeated Order order = 1 [ + (gogoproto.jsontag) = "order" + ]; + string priceDenom = 2 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 3 [ + (gogoproto.jsontag) = "asset_denom" + ]; +} \ No newline at end of file diff --git a/wasmbinding/test/encoder_test.go b/wasmbinding/test/encoder_test.go index 836dd266d5..439c3a707b 100644 --- a/wasmbinding/test/encoder_test.go +++ b/wasmbinding/test/encoder_test.go @@ -31,6 +31,8 @@ func TestEncodePlaceOrder(t *testing.T) { Quantity: sdk.OneDec(), Data: "{\"position_effect\":\"OPEN\", \"leverage\":\"1\"}", Nominal: sdk.ZeroDec(), + TriggerPrice: sdk.ZeroDec(), + TriggerStatus: false, } fund := sdk.NewCoin("usei", sdk.NewInt(1000000000)) msg := bindings.PlaceOrders{ diff --git a/x/dex/cache/order.go b/x/dex/cache/order.go index 87b87f06a2..42cb9bc02a 100644 --- a/x/dex/cache/order.go +++ b/x/dex/cache/order.go @@ -78,6 +78,22 @@ func (o *BlockOrders) GetLimitOrders(direction types.PositionDirection) []*types return o.getOrdersByCriteria(types.OrderType_LIMIT, direction) } +func (o *BlockOrders) GetTriggeredOrders() []*types.Order { + o.mu.Lock() + defer o.mu.Unlock() + // TODO: abstract the getOrdersByCriteria + // might be worth to get all directions too + return o.getOrdersByCriteriaMap( + map[types.OrderType]bool{ + types.OrderType_STOPLOSS: true, + types.OrderType_STOPLIMIT: true, + }, + map[types.PositionDirection]bool{ + types.PositionDirection_LONG: true, + types.PositionDirection_SHORT: true, + }) +} + func (o *BlockOrders) getOrdersByCriteria(orderType types.OrderType, direction types.PositionDirection) []*types.Order { res := []*types.Order{} for _, order := range o.internal { diff --git a/x/dex/client/cli/tx/tx_place_orders.go b/x/dex/client/cli/tx/tx_place_orders.go index 63da4cd675..d147ece99a 100644 --- a/x/dex/client/cli/tx/tx_place_orders.go +++ b/x/dex/client/cli/tx/tx_place_orders.go @@ -60,6 +60,19 @@ func CmdPlaceOrders() *cobra.Command { } newOrder.Nominal = argNominal } + if newOrder.OrderType == types.OrderType_STOPLOSS || newOrder.OrderType == types.OrderType_STOPLIMIT { + triggerPrice, err := sdk.NewDecFromStr(orderDetails[7]) + if err != nil { + return err + } + triggerStatus, err := strconv.ParseBool(orderDetails[8]) + if err != nil { + return err + } + + newOrder.TriggerPrice = triggerPrice + newOrder.TriggerStatus = triggerStatus + } orders = append(orders, &newOrder) } diff --git a/x/dex/contract/execution.go b/x/dex/contract/execution.go index b78956ead2..7ccddd7d10 100644 --- a/x/dex/contract/execution.go +++ b/x/dex/contract/execution.go @@ -68,6 +68,7 @@ func ExecutePair( // Fill limit orders limitOrderOutcome := exchange.MatchLimitOrders(ctx, orderbook) totalOutcome := marketOrderOutcome.Merge(&limitOrderOutcome) + updateTriggeredOrderForPair(ctx, typedContractAddr, typedPairStr, dexkeeper, totalOutcome) dexkeeperutils.SetPriceStateFromExecutionOutcome(ctx, dexkeeper, typedContractAddr, pair, totalOutcome) dexkeeperutils.FlushOrderbook(ctx, dexkeeper, typedContractAddr, orderbook) @@ -111,6 +112,63 @@ func matchMarketOrderForPair( return marketBuyOutcome.Merge(&marketSellOutcome) } + +func moveTriggeredOrderForPair( + ctx sdk.Context, + typedContractAddr dextypesutils.ContractAddress, + typedPairStr dextypesutils.PairString, + dexkeeper *keeper.Keeper, +) { + priceDenom, assetDenom := dextypesutils.GetPriceAssetString(typedPairStr) + for _, order := range dexkeeper.GetAllTriggerBookOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) { + if order.TriggerStatus { + if order.OrderType == types.OrderType_STOPLOSS { + order.OrderType = types.OrderType_MARKET + } else if order.OrderType == types.OrderType_STOPLIMIT { + order.OrderType = types.OrderType_LIMIT + } + dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr).Add(&order) + dexkeeper.RemoveTriggerBookOrder(ctx, string(typedContractAddr), order.Id, priceDenom, assetDenom) + } + } +} + +func updateTriggeredOrderForPair( + ctx sdk.Context, + typedContractAddr dextypesutils.ContractAddress, + typedPairStr dextypesutils.PairString, + dexkeeper *keeper.Keeper, + totalOutcome exchange.ExecutionOutcome, +) { + + orders := dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr) + triggeredOrders := orders.GetTriggeredOrders() + + // update existing trigger orders + priceDenom, assetDenom := dextypesutils.GetPriceAssetString(typedPairStr) + for _, order := range dexkeeper.GetAllTriggerBookOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) { + if (order.PositionDirection == types.PositionDirection_LONG && order.TriggerPrice.LTE(totalOutcome.MaxPrice)) || + order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { + order.TriggerStatus = true + dexkeeper.SetTriggerBookOrder(ctx, order.ContractAddr, order, order.PriceDenom, order.AssetDenom) + } + } + + for _, order := range triggeredOrders { + if order.PositionDirection == types.PositionDirection_LONG && order.TriggerPrice.LTE(totalOutcome.MaxPrice) { + // trigger order to close short position - buy back + order.TriggerStatus = true + } else if order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { + // trigger order to close long position - sell back + order.TriggerStatus = true + } + } + + for _, order := range triggeredOrders { + dexkeeper.SetTriggerBookOrder(ctx, order.ContractAddr, *order, order.PriceDenom, order.AssetDenom) + } +} + func GetMatchResults( ctx sdk.Context, typedContractAddr dextypesutils.ContractAddress, @@ -168,6 +226,7 @@ func ExecutePairsInParallel(ctx sdk.Context, contractAddr string, dexkeeper *kee pairCopy := pair pairStr := dextypesutils.GetPairString(&pairCopy) + moveTriggeredOrderForPair(ctx, typedContractAddr, pairStr, dexkeeper) orderbook, found := orderBooks.Load(pairStr) if !found { panic(fmt.Sprintf("Orderbook not found for %s", pairStr)) diff --git a/x/dex/exchange/helpers.go b/x/dex/exchange/helpers.go index 57bf15ebbc..026d3c14d5 100644 --- a/x/dex/exchange/helpers.go +++ b/x/dex/exchange/helpers.go @@ -9,6 +9,8 @@ type ExecutionOutcome struct { TotalNotional sdk.Dec TotalQuantity sdk.Dec Settlements []*types.SettlementEntry + MinPrice sdk.Dec + MaxPrice sdk.Dec } func (o *ExecutionOutcome) Merge(other *ExecutionOutcome) ExecutionOutcome { @@ -16,5 +18,7 @@ func (o *ExecutionOutcome) Merge(other *ExecutionOutcome) ExecutionOutcome { TotalNotional: o.TotalNotional.Add(other.TotalNotional), TotalQuantity: o.TotalQuantity.Add(other.TotalQuantity), Settlements: append(o.Settlements, other.Settlements...), + MinPrice: sdk.MinDec(o.MinPrice, other.MinPrice), + MaxPrice: sdk.MaxDec(o.MaxPrice, other.MaxPrice), } } diff --git a/x/dex/exchange/limit_order.go b/x/dex/exchange/limit_order.go index e531222cc6..5e0c63b46a 100644 --- a/x/dex/exchange/limit_order.go +++ b/x/dex/exchange/limit_order.go @@ -1,6 +1,8 @@ package exchange import ( + "math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sei-protocol/sei-chain/x/dex/types" ) @@ -11,6 +13,7 @@ func MatchLimitOrders( ) ExecutionOutcome { settlements := []*types.SettlementEntry{} totalExecuted, totalPrice := sdk.ZeroDec(), sdk.ZeroDec() + minPrice, maxPrice := sdk.NewDecFromInt(sdk.NewIntFromUint64(math.MaxInt64)), sdk.OneDec().Neg() longPtr, shortPtr := len(orderbook.Longs.Entries)-1, 0 for longPtr >= 0 && shortPtr < len(orderbook.Shorts.Entries) && orderbook.Longs.Entries[longPtr].GetPrice().GTE(orderbook.Shorts.Entries[shortPtr].GetPrice()) { @@ -21,11 +24,14 @@ func MatchLimitOrders( executed = orderbook.Shorts.Entries[shortPtr].GetEntry().Quantity } totalExecuted = totalExecuted.Add(executed).Add(executed) + // I think the line-below is off... but I'm not really sure I udnerstand the logic totalPrice = totalPrice.Add( executed.Mul( orderbook.Longs.Entries[longPtr].GetPrice().Add(orderbook.Shorts.Entries[shortPtr].GetPrice()), ), ) + minPrice = sdk.MinDec(minPrice, orderbook.Longs.Entries[longPtr].GetPrice()) + maxPrice = sdk.MaxDec(maxPrice, orderbook.Longs.Entries[longPtr].GetPrice()) orderbook.Longs.AddDirtyEntry(orderbook.Longs.Entries[longPtr]) orderbook.Shorts.AddDirtyEntry(orderbook.Shorts.Entries[shortPtr]) @@ -48,6 +54,8 @@ func MatchLimitOrders( TotalNotional: totalPrice, TotalQuantity: totalExecuted, Settlements: settlements, + MinPrice: minPrice, + MaxPrice: maxPrice, } } diff --git a/x/dex/exchange/market_order.go b/x/dex/exchange/market_order.go index 2c99880ba5..68595bd57c 100644 --- a/x/dex/exchange/market_order.go +++ b/x/dex/exchange/market_order.go @@ -1,6 +1,8 @@ package exchange import ( + "math" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sei-protocol/sei-chain/x/dex/types" ) @@ -12,19 +14,20 @@ func MatchMarketOrders( direction types.PositionDirection, ) ExecutionOutcome { totalExecuted, totalPrice := sdk.ZeroDec(), sdk.ZeroDec() + minPrice, maxPrice := sdk.NewDecFromInt(sdk.NewIntFromUint64(math.MaxInt64)), sdk.OneDec().Neg() settlements := []*types.SettlementEntry{} allTakerSettlements := []*types.SettlementEntry{} for _, marketOrder := range marketOrders { switch marketOrder.OrderType { case types.OrderType_FOKMARKETBYVALUE: settlements, allTakerSettlements = MatchByValueFOKMarketOrder( - ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, settlements, allTakerSettlements) + ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, &minPrice, &maxPrice, settlements, allTakerSettlements) case types.OrderType_FOKMARKET: settlements, allTakerSettlements = MatchFOKMarketOrder( - ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, settlements, allTakerSettlements) + ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, &minPrice, &maxPrice, settlements, allTakerSettlements) default: settlements, allTakerSettlements = MatchMarketOrder( - ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, settlements, allTakerSettlements) + ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, &minPrice, &maxPrice, settlements, allTakerSettlements) } } @@ -39,6 +42,8 @@ func MatchMarketOrders( TotalNotional: totalPrice, TotalQuantity: totalExecuted, Settlements: settlements, + MinPrice: minPrice, + MaxPrice: maxPrice, } } @@ -49,6 +54,8 @@ func MatchMarketOrder( direction types.PositionDirection, totalExecuted *sdk.Dec, totalPrice *sdk.Dec, + minPrice *sdk.Dec, + maxPrice *sdk.Dec, settlements []*types.SettlementEntry, allTakerSettlements []*types.SettlementEntry, ) ([]*types.SettlementEntry, []*types.SettlementEntry) { @@ -84,6 +91,8 @@ func MatchMarketOrder( *totalPrice = totalPrice.Add( executed.Mul(existingOrder.GetPrice()), ) + *minPrice = sdk.MinDec(*minPrice, existingOrder.GetPrice()) + *maxPrice = sdk.MaxDec(*maxPrice, existingOrder.GetPrice()) orderBookEntries.AddDirtyEntry(existingOrder) takerSettlements, makerSettlements := Settle( @@ -111,6 +120,8 @@ func MatchFOKMarketOrder( direction types.PositionDirection, totalExecuted *sdk.Dec, totalPrice *sdk.Dec, + minPrice *sdk.Dec, + maxPrice *sdk.Dec, settlements []*types.SettlementEntry, allTakerSettlements []*types.SettlementEntry, ) ([]*types.SettlementEntry, []*types.SettlementEntry) { @@ -159,6 +170,8 @@ func MatchFOKMarketOrder( *totalPrice = totalPrice.Add( executed.Mul(existingOrder.GetPrice()), ) + *minPrice = sdk.MinDec(*minPrice, existingOrder.GetPrice()) + *maxPrice = sdk.MaxDec(*maxPrice, existingOrder.GetPrice()) orderBookEntries.AddDirtyEntry(existingOrder) takerSettlements, makerSettlements := Settle( @@ -183,6 +196,8 @@ func MatchByValueFOKMarketOrder( direction types.PositionDirection, totalExecuted *sdk.Dec, totalPrice *sdk.Dec, + minPrice *sdk.Dec, + maxPrice *sdk.Dec, settlements []*types.SettlementEntry, allTakerSettlements []*types.SettlementEntry, ) ([]*types.SettlementEntry, []*types.SettlementEntry) { @@ -237,6 +252,8 @@ func MatchByValueFOKMarketOrder( *totalPrice = totalPrice.Add( executed.Mul(existingOrder.GetPrice()), ) + *minPrice = sdk.MinDec(*minPrice, existingOrder.GetPrice()) + *maxPrice = sdk.MaxDec(*maxPrice, existingOrder.GetPrice()) orderBookEntries.AddDirtyEntry(existingOrder) takerSettlements, makerSettlements := Settle( diff --git a/x/dex/genesis.go b/x/dex/genesis.go index bc8df3c225..8db9042c6a 100644 --- a/x/dex/genesis.go +++ b/x/dex/genesis.go @@ -19,6 +19,10 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) k.SetShortBook(ctx, "genesis", elem) } + for _, elem := range genState.TriggerBookList { + k.SetTriggerBook(ctx, "genesis", elem) + } + // Set initial tick size for each pair // tick size is the minimum unit that can be traded for certain pair for _, elem := range genState.TickSizeList { diff --git a/x/dex/keeper/msgserver/msg_server_place_orders.go b/x/dex/keeper/msgserver/msg_server_place_orders.go index e5aa326e47..eeb9567599 100644 --- a/x/dex/keeper/msgserver/msg_server_place_orders.go +++ b/x/dex/keeper/msgserver/msg_server_place_orders.go @@ -99,5 +99,9 @@ func (k msgServer) validateOrder(order *types.Order) error { if order.OrderType == types.OrderType_FOKMARKETBYVALUE && (order.Nominal.IsNil() || order.Nominal.IsNegative()) { return fmt.Errorf("invalid nominal value for market by value order: %s", order.Nominal) } + if (order.OrderType == types.OrderType_STOPLIMIT || order.OrderType == types.OrderType_STOPLOSS) && + (order.TriggerPrice.IsNil() || order.TriggerPrice.IsNegative()) { + return fmt.Errorf("invalid trigger price for stop loss/limit order: %s", order.TriggerPrice) + } return nil } diff --git a/x/dex/keeper/msgserver/msg_server_place_orders_test.go b/x/dex/keeper/msgserver/msg_server_place_orders_test.go index 03fc026f86..bc2bf6f069 100644 --- a/x/dex/keeper/msgserver/msg_server_place_orders_test.go +++ b/x/dex/keeper/msgserver/msg_server_place_orders_test.go @@ -38,6 +38,17 @@ func TestPlaceOrder(t *testing.T) { PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom, }, + { + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_STOPLOSS, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("10"), + TriggerStatus: false, + }, }, } keeper, ctx := keepertest.DexKeeper(t) @@ -47,9 +58,10 @@ func TestPlaceOrder(t *testing.T) { server := msgserver.NewMsgServerImpl(*keeper) res, err := server.PlaceOrders(wctx, msg) require.Nil(t, err) - require.Equal(t, 2, len(res.OrderIds)) + require.Equal(t, 3, len(res.OrderIds)) require.Equal(t, uint64(0), res.OrderIds[0]) require.Equal(t, uint64(1), res.OrderIds[1]) + require.Equal(t, uint64(2), res.OrderIds[2]) // Ensure that contract addr and account is set in the order require.Equal(t, msg.Orders[0].ContractAddr, TestContract) require.Equal(t, msg.Orders[0].Account, TestCreator) diff --git a/x/dex/keeper/trigger_book.go b/x/dex/keeper/trigger_book.go new file mode 100644 index 0000000000..75585b3315 --- /dev/null +++ b/x/dex/keeper/trigger_book.go @@ -0,0 +1,62 @@ +package keeper + +import ( + "encoding/binary" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// I don't think this is proper lmao +func (k Keeper) SetTriggerBook(ctx sdk.Context, contractAddr string, triggerBook types.TriggerBook) { + prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, triggerBook.PriceDenom, triggerBook.AssetDenom)) +} + +func (k Keeper) SetTriggerBookOrder(ctx sdk.Context, contractAddr string, order types.Order, priceDenom string, assetDenom string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) + + b := k.Cdc.MustMarshal(&order) + store.Set(GetKeyForOrderId(order.Id), b) +} + +func (k Keeper) RemoveTriggerBookOrder(ctx sdk.Context, contractAddr string, order_id uint64, priceDenom string, assetDenom string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) + store.Delete(GetKeyForOrderId(order_id)) +} + +func (k Keeper) GetTriggerBookByOrderId(ctx sdk.Context, contractAddr string, order_id uint64, priceDenom string, assetDenom string) (val types.Order, found bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) + b := store.Get(GetKeyForOrderId(order_id)) + if b == nil { + return val, false + } + k.Cdc.MustUnmarshal(b, &val) + return val, true +} + +func (k Keeper) GetAllTriggerBookOrdersForPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string) (list []types.Order) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Order + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return +} + +// func GetKeyForTriggerBook(triggerBook types.TriggerBook) []byte { +// return GetKeyForPrice(shortBook.Entry.Price) +// } + +func GetKeyForOrderId(order_id uint64) []byte { + key := make([]byte, 8) + binary.LittleEndian.PutUint64(key, order_id) + + return key +} diff --git a/x/dex/types/enums.pb.go b/x/dex/types/enums.pb.go index 0505e07a64..1690031dec 100644 --- a/x/dex/types/enums.pb.go +++ b/x/dex/types/enums.pb.go @@ -78,6 +78,8 @@ const ( OrderType_LIQUIDATION OrderType = 2 OrderType_FOKMARKET OrderType = 3 OrderType_FOKMARKETBYVALUE OrderType = 4 + OrderType_STOPLOSS OrderType = 5 + OrderType_STOPLIMIT OrderType = 6 ) var OrderType_name = map[int32]string{ @@ -86,6 +88,8 @@ var OrderType_name = map[int32]string{ 2: "LIQUIDATION", 3: "FOKMARKET", 4: "FOKMARKETBYVALUE", + 5: "STOPLOSS", + 6: "STOPLIMIT", } var OrderType_value = map[string]int32{ @@ -94,6 +98,8 @@ var OrderType_value = map[string]int32{ "LIQUIDATION": 2, "FOKMARKET": 3, "FOKMARKETBYVALUE": 4, + "STOPLOSS": 5, + "STOPLIMIT": 6, } func (x OrderType) String() string { @@ -203,30 +209,31 @@ func init() { func init() { proto.RegisterFile("dex/enums.proto", fileDescriptor_b8c5bb23c6eb0b88) } var fileDescriptor_b8c5bb23c6eb0b88 = []byte{ - // 391 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x3c, 0x91, 0xcd, 0x8e, 0xd3, 0x30, - 0x14, 0x85, 0xe3, 0x69, 0x19, 0x4d, 0xef, 0xc0, 0xd4, 0x18, 0x90, 0x58, 0x65, 0x87, 0x84, 0x22, - 0x4d, 0x22, 0x04, 0x2f, 0xe0, 0x49, 0xdc, 0xc1, 0x1a, 0x37, 0x2e, 0xf9, 0x41, 0xc0, 0x66, 0x94, - 0x49, 0x5d, 0x6a, 0xa9, 0x4d, 0xaa, 0xc4, 0x95, 0xda, 0xb7, 0xe0, 0xb1, 0x58, 0x76, 0xc9, 0x12, - 0xb5, 0x2f, 0x82, 0x9c, 0xb6, 0xec, 0xce, 0xb9, 0xf7, 0x44, 0xf7, 0x8b, 0x0f, 0x0c, 0xa7, 0x6a, - 0x13, 0xa8, 0x6a, 0xbd, 0x6c, 0xfd, 0x55, 0x53, 0x9b, 0x9a, 0xbc, 0x6d, 0x95, 0xee, 0x54, 0x59, - 0x2f, 0xfc, 0x56, 0xe9, 0x72, 0x5e, 0xe8, 0xca, 0x9f, 0xaa, 0x8d, 0xf7, 0x1e, 0x5e, 0x4e, 0xea, - 0x56, 0x1b, 0x5d, 0x57, 0x91, 0x6e, 0x54, 0x69, 0x05, 0xb9, 0x82, 0xbe, 0x90, 0xf1, 0x3d, 0x76, - 0xc8, 0x00, 0x9e, 0xa5, 0x9f, 0x65, 0x92, 0x61, 0xe4, 0xbd, 0x83, 0x9b, 0x73, 0x92, 0xcd, 0x66, - 0xaa, 0x34, 0x36, 0x26, 0x27, 0x2c, 0x3e, 0xc6, 0x42, 0x21, 0x53, 0x86, 0x91, 0xf7, 0x0d, 0x06, - 0xb2, 0x99, 0xaa, 0x26, 0xdb, 0xae, 0x94, 0x9d, 0x0b, 0x3e, 0xe6, 0x19, 0x76, 0x08, 0xc0, 0xe5, - 0x98, 0x26, 0x0f, 0x2c, 0xc3, 0x88, 0x0c, 0xe1, 0x5a, 0xf0, 0x2f, 0x39, 0x8f, 0x68, 0xc6, 0x65, - 0x8c, 0x2f, 0xc8, 0x0b, 0x18, 0x8c, 0xe4, 0xc3, 0x69, 0xdf, 0x23, 0xaf, 0x01, 0xff, 0xb7, 0x77, - 0xdf, 0xbf, 0x52, 0x91, 0x33, 0xdc, 0xf7, 0x3e, 0x41, 0x3f, 0xaf, 0xb4, 0x21, 0xcf, 0xe1, 0x2a, - 0xcd, 0x68, 0x1c, 0xd1, 0x24, 0x3a, 0x9e, 0x1e, 0x73, 0x21, 0x38, 0x46, 0x47, 0x19, 0x26, 0x12, - 0x5f, 0x58, 0xb4, 0x98, 0xc6, 0x12, 0xf7, 0x3c, 0x01, 0xd7, 0x1d, 0x4f, 0x6a, 0x0a, 0xb3, 0x6e, - 0x2d, 0xc6, 0x44, 0xd0, 0x90, 0xd9, 0x4f, 0x5f, 0xc1, 0x70, 0x44, 0xb9, 0x60, 0xd1, 0x63, 0x26, - 0x1f, 0xbb, 0x29, 0x46, 0x16, 0x25, 0xa4, 0x71, 0xc8, 0x84, 0x60, 0xd1, 0x89, 0x2c, 0x17, 0x23, - 0xde, 0xd9, 0x9e, 0xf7, 0x01, 0xde, 0x84, 0x45, 0x55, 0xaa, 0xc5, 0xa2, 0xb0, 0x0f, 0xc1, 0x2b, - 0x6d, 0x74, 0x61, 0xea, 0xc6, 0x1e, 0xcc, 0x53, 0x96, 0x60, 0x87, 0xdc, 0x00, 0x9c, 0x7f, 0x8e, - 0x45, 0x18, 0xdd, 0xdd, 0xff, 0xde, 0xbb, 0x68, 0xb7, 0x77, 0xd1, 0xdf, 0xbd, 0x8b, 0x7e, 0x1d, - 0x5c, 0x67, 0x77, 0x70, 0x9d, 0x3f, 0x07, 0xd7, 0xf9, 0x71, 0xfb, 0x53, 0x9b, 0xf9, 0xfa, 0xc9, - 0x2f, 0xeb, 0x65, 0xd0, 0x2a, 0x7d, 0x7b, 0x6e, 0xa8, 0x33, 0x5d, 0x45, 0xc1, 0x26, 0xb0, 0x55, - 0x9a, 0xed, 0x4a, 0xb5, 0x4f, 0x97, 0xdd, 0xfe, 0xe3, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, - 0x0a, 0x70, 0x34, 0xde, 0x01, 0x00, 0x00, + // 404 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x3c, 0x51, 0x5d, 0x6f, 0xd3, 0x30, + 0x14, 0x8d, 0xd7, 0xae, 0x5a, 0xef, 0x60, 0x35, 0x06, 0x24, 0x9e, 0xf2, 0x86, 0x84, 0x22, 0xad, + 0x15, 0x82, 0x3f, 0xe0, 0x25, 0xee, 0xb0, 0xe6, 0xc6, 0x25, 0x1f, 0x48, 0xf0, 0x32, 0x65, 0xa9, + 0xc7, 0x2c, 0x75, 0x49, 0x95, 0x38, 0x52, 0xf7, 0x2f, 0xf8, 0x59, 0x3c, 0xee, 0x91, 0x47, 0xd4, + 0xfe, 0x11, 0x64, 0xa7, 0xe5, 0xed, 0x9c, 0x7b, 0xcf, 0xf5, 0x3d, 0xbe, 0x07, 0x26, 0x2b, 0xb5, + 0x9d, 0xa9, 0xaa, 0x7b, 0x6c, 0xa7, 0x9b, 0xa6, 0x36, 0x35, 0x79, 0xd7, 0x2a, 0xed, 0x50, 0x59, + 0xaf, 0xa7, 0xad, 0xd2, 0xe5, 0x43, 0xa1, 0xab, 0xe9, 0x4a, 0x6d, 0x83, 0x0f, 0xf0, 0x6a, 0x59, + 0xb7, 0xda, 0xe8, 0xba, 0x8a, 0x74, 0xa3, 0x4a, 0x0b, 0xc8, 0x19, 0x0c, 0x85, 0x8c, 0xaf, 0xb1, + 0x47, 0xc6, 0x70, 0x9a, 0x7e, 0x91, 0x49, 0x86, 0x51, 0xf0, 0x1e, 0x2e, 0x8e, 0x4a, 0x76, 0x7f, + 0xaf, 0x4a, 0x63, 0x65, 0x72, 0xc9, 0xe2, 0x5e, 0x16, 0x0a, 0x99, 0x32, 0x8c, 0x82, 0x0e, 0xc6, + 0xb2, 0x59, 0xa9, 0x26, 0x7b, 0xda, 0x28, 0x5b, 0x17, 0x7c, 0xc1, 0x33, 0xec, 0x11, 0x80, 0xd1, + 0x82, 0x26, 0x37, 0x2c, 0xc3, 0x88, 0x4c, 0xe0, 0x5c, 0xf0, 0xaf, 0x39, 0x8f, 0x68, 0xc6, 0x65, + 0x8c, 0x4f, 0xc8, 0x4b, 0x18, 0xcf, 0xe5, 0xcd, 0xa1, 0x3f, 0x20, 0x6f, 0x00, 0xff, 0xa7, 0x57, + 0xdf, 0xbf, 0x51, 0x91, 0x33, 0x3c, 0x24, 0x2f, 0xe0, 0x2c, 0xcd, 0xe4, 0x52, 0xc8, 0x34, 0xc5, + 0xa7, 0x76, 0xc4, 0x31, 0xf7, 0xfc, 0x28, 0xf8, 0x0c, 0xc3, 0xbc, 0xd2, 0xa6, 0x17, 0xd1, 0x38, + 0xa2, 0x49, 0xd4, 0xfb, 0x5a, 0x70, 0x21, 0x38, 0x46, 0x3d, 0x0c, 0x13, 0x89, 0x4f, 0xac, 0xef, + 0x98, 0xc6, 0x12, 0x0f, 0x02, 0x01, 0xe7, 0xce, 0x6c, 0x6a, 0x0a, 0xd3, 0xb5, 0xd6, 0xe3, 0x52, + 0xd0, 0x90, 0xd9, 0xd1, 0xd7, 0x30, 0x99, 0x53, 0x2e, 0x58, 0x74, 0x9b, 0xc9, 0x5b, 0x57, 0xc5, + 0xc8, 0x2e, 0x0d, 0x69, 0x1c, 0x32, 0x21, 0x58, 0x74, 0xb0, 0x9d, 0x8b, 0x39, 0x77, 0x74, 0x10, + 0x7c, 0x84, 0xb7, 0x61, 0x51, 0x95, 0x6a, 0xbd, 0x2e, 0xec, 0x95, 0x78, 0xa5, 0x8d, 0x2e, 0x4c, + 0xdd, 0xd8, 0x85, 0x79, 0xca, 0x12, 0xec, 0x91, 0x0b, 0x80, 0xe3, 0xcf, 0x59, 0x84, 0xd1, 0xd5, + 0xf5, 0xef, 0x9d, 0x8f, 0x9e, 0x77, 0x3e, 0xfa, 0xbb, 0xf3, 0xd1, 0xaf, 0xbd, 0xef, 0x3d, 0xef, + 0x7d, 0xef, 0xcf, 0xde, 0xf7, 0x7e, 0x5c, 0xfe, 0xd4, 0xe6, 0xa1, 0xbb, 0x9b, 0x96, 0xf5, 0xe3, + 0xac, 0x55, 0xfa, 0xf2, 0x18, 0x9f, 0x23, 0x2e, 0xbf, 0xd9, 0x76, 0x66, 0x73, 0x36, 0x4f, 0x1b, + 0xd5, 0xde, 0x8d, 0x5c, 0xff, 0xd3, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0x64, 0xc8, 0xd2, 0x69, + 0xfb, 0x01, 0x00, 0x00, } diff --git a/x/dex/types/genesis.pb.go b/x/dex/types/genesis.pb.go index e192bb861e..f8c33901fc 100644 --- a/x/dex/types/genesis.pb.go +++ b/x/dex/types/genesis.pb.go @@ -25,12 +25,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the dex module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - LongBookList []LongBook `protobuf:"bytes,2,rep,name=longBookList,proto3" json:"longBookList"` - ShortBookList []ShortBook `protobuf:"bytes,3,rep,name=shortBookList,proto3" json:"shortBookList"` - TwapList []*Twap `protobuf:"bytes,4,rep,name=twapList,proto3" json:"twapList,omitempty"` - TickSizeList []*TickSize `protobuf:"bytes,5,rep,name=tickSizeList,proto3" json:"tickSizeList,omitempty"` - LastEpoch uint64 `protobuf:"varint,6,opt,name=lastEpoch,proto3" json:"lastEpoch,omitempty"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + LongBookList []LongBook `protobuf:"bytes,2,rep,name=longBookList,proto3" json:"longBookList"` + ShortBookList []ShortBook `protobuf:"bytes,3,rep,name=shortBookList,proto3" json:"shortBookList"` + TwapList []*Twap `protobuf:"bytes,4,rep,name=twapList,proto3" json:"twapList,omitempty"` + TickSizeList []*TickSize `protobuf:"bytes,5,rep,name=tickSizeList,proto3" json:"tickSizeList,omitempty"` + LastEpoch uint64 `protobuf:"varint,6,opt,name=lastEpoch,proto3" json:"lastEpoch,omitempty"` + TriggerBookList []TriggerBook `protobuf:"bytes,7,rep,name=triggerBookList,proto3" json:"triggerBookList"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -108,6 +109,13 @@ func (m *GenesisState) GetLastEpoch() uint64 { return 0 } +func (m *GenesisState) GetTriggerBookList() []TriggerBook { + if m != nil { + return m.TriggerBookList + } + return nil +} + func init() { proto.RegisterType((*GenesisState)(nil), "seiprotocol.seichain.dex.GenesisState") } @@ -115,29 +123,31 @@ func init() { func init() { proto.RegisterFile("dex/genesis.proto", fileDescriptor_a803aaabd08db59d) } var fileDescriptor_a803aaabd08db59d = []byte{ - // 354 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0x3f, 0x4f, 0xc2, 0x40, - 0x18, 0xc6, 0x5b, 0x41, 0xa2, 0x07, 0x1a, 0x3d, 0x19, 0x1a, 0x62, 0xce, 0x06, 0x17, 0x16, 0xda, - 0x04, 0x37, 0x07, 0x07, 0x12, 0x65, 0x21, 0xd1, 0x14, 0x26, 0x17, 0x72, 0x94, 0x4b, 0x7b, 0xe1, - 0xcf, 0xdb, 0x70, 0x67, 0x40, 0xbe, 0x84, 0x7e, 0x2c, 0x46, 0x46, 0x27, 0x63, 0xe0, 0x8b, 0x98, - 0xbb, 0x1e, 0x08, 0x43, 0xe3, 0x76, 0x7d, 0xde, 0xe7, 0xf9, 0xbd, 0x7f, 0x8a, 0x2e, 0x07, 0x6c, - 0xee, 0x47, 0x6c, 0xc2, 0x04, 0x17, 0x5e, 0x32, 0x05, 0x09, 0xd8, 0x11, 0x8c, 0xeb, 0x57, 0x08, - 0x23, 0x4f, 0x30, 0x1e, 0xc6, 0x94, 0x4f, 0xbc, 0x01, 0x9b, 0x57, 0xca, 0x11, 0x44, 0xa0, 0x4b, - 0xbe, 0x7a, 0xa5, 0xfe, 0xca, 0x85, 0x42, 0x24, 0x74, 0x4a, 0xc7, 0x86, 0x50, 0xb9, 0x52, 0xca, - 0x08, 0x26, 0x51, 0xaf, 0x0f, 0x30, 0x34, 0x62, 0x59, 0x89, 0x22, 0x86, 0xa9, 0xdc, 0x57, 0xcf, - 0x95, 0x2a, 0x67, 0x34, 0xd9, 0x8f, 0x4a, 0x1e, 0x0e, 0x7b, 0x82, 0x2f, 0x58, 0x2a, 0x56, 0x3f, - 0x72, 0xa8, 0xd4, 0x4a, 0x67, 0xec, 0x48, 0x2a, 0x19, 0x7e, 0x40, 0x85, 0xb4, 0xa1, 0x63, 0xbb, - 0x76, 0xad, 0xd8, 0x70, 0xbd, 0xac, 0x99, 0xbd, 0x17, 0xed, 0x6b, 0xe6, 0x97, 0xdf, 0x37, 0x56, - 0x60, 0x52, 0xb8, 0x8d, 0x4a, 0x6a, 0xbc, 0x26, 0xc0, 0xb0, 0xcd, 0x85, 0x74, 0x8e, 0xdc, 0x5c, - 0xad, 0xd8, 0xa8, 0x66, 0x53, 0xda, 0xc6, 0x6d, 0x38, 0x07, 0x69, 0xfc, 0x8c, 0xce, 0xf4, 0x5e, - 0x3b, 0x5c, 0x4e, 0xe3, 0x6e, 0xb3, 0x71, 0x9d, 0xad, 0xdd, 0xf0, 0x0e, 0xf3, 0xf8, 0x1e, 0x9d, - 0xa8, 0x93, 0x68, 0x56, 0x5e, 0xb3, 0x48, 0x36, 0xab, 0x3b, 0xa3, 0x49, 0xb0, 0xf3, 0xe3, 0x27, - 0x54, 0x52, 0xe7, 0xeb, 0xf0, 0x05, 0xd3, 0xf9, 0xe3, 0xff, 0x56, 0xeb, 0x1a, 0x77, 0x70, 0x90, - 0xc3, 0xd7, 0xe8, 0x74, 0x44, 0x85, 0x7c, 0x4c, 0x20, 0x8c, 0x9d, 0x82, 0x6b, 0xd7, 0xf2, 0xc1, - 0x9f, 0xd0, 0x6c, 0x2d, 0xd7, 0xc4, 0x5e, 0xad, 0x89, 0xfd, 0xb3, 0x26, 0xf6, 0xe7, 0x86, 0x58, - 0xab, 0x0d, 0xb1, 0xbe, 0x36, 0xc4, 0x7a, 0xad, 0x47, 0x5c, 0xc6, 0x6f, 0x7d, 0x2f, 0x84, 0xb1, - 0x2f, 0x18, 0xaf, 0x6f, 0x9b, 0xea, 0x0f, 0xdd, 0xd5, 0x9f, 0xfb, 0xfa, 0x27, 0xbf, 0x27, 0x4c, - 0xf4, 0x0b, 0xba, 0x7e, 0xf7, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x16, 0xb8, 0xbf, 0x49, 0x88, 0x02, + // 386 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xcb, 0x4e, 0xc2, 0x40, + 0x18, 0x85, 0x5b, 0x41, 0xd4, 0x01, 0x6f, 0x23, 0x31, 0x0d, 0x31, 0xb5, 0xc1, 0x98, 0xb0, 0xa1, + 0x4d, 0x70, 0xe7, 0xc2, 0x05, 0x89, 0xb2, 0x21, 0xd1, 0x14, 0xdc, 0xb8, 0x21, 0xa5, 0x4c, 0xda, + 0x09, 0x97, 0x69, 0x3a, 0x63, 0x40, 0x9e, 0xc2, 0xc7, 0x62, 0xc9, 0xd2, 0x95, 0x31, 0x90, 0xf8, + 0x1c, 0x66, 0x7e, 0x86, 0x9b, 0x49, 0x75, 0x37, 0x9c, 0x39, 0xe7, 0xfb, 0xff, 0x33, 0x14, 0x9d, + 0x76, 0xc8, 0xc8, 0x09, 0xc8, 0x80, 0x70, 0xca, 0xed, 0x28, 0x66, 0x82, 0x61, 0x83, 0x13, 0x0a, + 0x27, 0x9f, 0xf5, 0x6c, 0x4e, 0xa8, 0x1f, 0x7a, 0x74, 0x60, 0x77, 0xc8, 0xa8, 0x90, 0x0f, 0x58, + 0xc0, 0xe0, 0xca, 0x91, 0xa7, 0x85, 0xbf, 0x70, 0x22, 0x11, 0x91, 0x17, 0x7b, 0x7d, 0x45, 0x28, + 0x9c, 0x49, 0xa5, 0xc7, 0x06, 0x41, 0xab, 0xcd, 0x58, 0x57, 0x89, 0x79, 0x29, 0xf2, 0x90, 0xc5, + 0x62, 0x53, 0x3d, 0x92, 0xaa, 0x18, 0x7a, 0xd1, 0x66, 0x54, 0x50, 0xbf, 0xdb, 0xe2, 0x74, 0x4c, + 0x94, 0x78, 0x0e, 0x62, 0x4c, 0x83, 0x80, 0xc4, 0x1b, 0xe1, 0xe2, 0x77, 0x0a, 0xe5, 0x6a, 0x8b, + 0xdd, 0x1b, 0xc2, 0x13, 0x04, 0xdf, 0xa1, 0xcc, 0x62, 0x11, 0x43, 0xb7, 0xf4, 0x52, 0xb6, 0x62, + 0xd9, 0x49, 0x5d, 0xec, 0x27, 0xf0, 0x55, 0xd3, 0x93, 0xcf, 0x4b, 0xcd, 0x55, 0x29, 0x5c, 0x47, + 0x39, 0xb9, 0x76, 0x95, 0xb1, 0x6e, 0x9d, 0x72, 0x61, 0xec, 0x58, 0xa9, 0x52, 0xb6, 0x52, 0x4c, + 0xa6, 0xd4, 0x95, 0x5b, 0x71, 0xb6, 0xd2, 0xf8, 0x11, 0x1d, 0x42, 0xdf, 0x15, 0x2e, 0x05, 0xb8, + 0xab, 0x64, 0x5c, 0x63, 0x69, 0x57, 0xbc, 0xed, 0x3c, 0xbe, 0x45, 0xfb, 0xf2, 0xa9, 0x80, 0x95, + 0x06, 0x96, 0x99, 0xcc, 0x6a, 0x0e, 0xbd, 0xc8, 0x5d, 0xf9, 0xf1, 0x03, 0xca, 0xc9, 0x67, 0x6d, + 0xd0, 0x31, 0x81, 0xfc, 0xee, 0x7f, 0xd5, 0x9a, 0xca, 0xed, 0x6e, 0xe5, 0xf0, 0x05, 0x3a, 0xe8, + 0x79, 0x5c, 0xdc, 0x47, 0xcc, 0x0f, 0x8d, 0x8c, 0xa5, 0x97, 0xd2, 0xee, 0x5a, 0xc0, 0xcf, 0xe8, + 0x58, 0xfd, 0x4f, 0xab, 0xd2, 0x7b, 0x30, 0xe8, 0xfa, 0x8f, 0x41, 0xeb, 0x80, 0xaa, 0xfd, 0x9b, + 0x51, 0xad, 0x4d, 0x66, 0xa6, 0x3e, 0x9d, 0x99, 0xfa, 0xd7, 0xcc, 0xd4, 0xdf, 0xe7, 0xa6, 0x36, + 0x9d, 0x9b, 0xda, 0xc7, 0xdc, 0xd4, 0x5e, 0xca, 0x01, 0x15, 0xe1, 0x6b, 0xdb, 0xf6, 0x59, 0xdf, + 0xe1, 0x84, 0x96, 0x97, 0x23, 0xe0, 0x07, 0xcc, 0x70, 0x46, 0x0e, 0x7c, 0x3e, 0x6f, 0x11, 0xe1, + 0xed, 0x0c, 0xdc, 0xdf, 0xfc, 0x04, 0x00, 0x00, 0xff, 0xff, 0x60, 0xfa, 0x1f, 0x27, 0xf7, 0x02, 0x00, 0x00, } @@ -161,6 +171,20 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.TriggerBookList) > 0 { + for iNdEx := len(m.TriggerBookList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.TriggerBookList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } if m.LastEpoch != 0 { i = encodeVarintGenesis(dAtA, i, uint64(m.LastEpoch)) i-- @@ -281,6 +305,12 @@ func (m *GenesisState) Size() (n int) { if m.LastEpoch != 0 { n += 1 + sovGenesis(uint64(m.LastEpoch)) } + if len(m.TriggerBookList) > 0 { + for _, e := range m.TriggerBookList { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } return n } @@ -507,6 +537,40 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { break } } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TriggerBookList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenesis + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenesis + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TriggerBookList = append(m.TriggerBookList, TriggerBook{}) + if err := m.TriggerBookList[len(m.TriggerBookList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) diff --git a/x/dex/types/keys.go b/x/dex/types/keys.go index a8a283c19a..ed1c5b5c00 100644 --- a/x/dex/types/keys.go +++ b/x/dex/types/keys.go @@ -47,6 +47,15 @@ func OrderBookPrefix(long bool, contractAddr string, priceDenom string, assetDen ) } +func TriggerOrderBookPrefix(contractAddr string, priceDenom string, assetDenom string) []byte { + prefix := KeyPrefix(TriggerBookKey) + + return append( + append(prefix, KeyPrefix(contractAddr)...), + PairPrefix(priceDenom, assetDenom)..., + ) +} + func TwapPrefix(contractAddr string) []byte { return append(KeyPrefix(TwapKey), KeyPrefix(contractAddr)...) } @@ -138,6 +147,8 @@ const ( ShortBookKey = "ShortBook-value-" + TriggerBookKey = "TriggerBook-value-" + OrderKey = "order" AccountActiveOrdersKey = "account-active-orders" CancelKey = "cancel" diff --git a/x/dex/types/order.pb.go b/x/dex/types/order.pb.go index b02a9967fc..69c89707db 100644 --- a/x/dex/types/order.pb.go +++ b/x/dex/types/order.pb.go @@ -38,6 +38,8 @@ type Order struct { Data string `protobuf:"bytes,11,opt,name=data,proto3" json:"data"` StatusDescription string `protobuf:"bytes,12,opt,name=statusDescription,proto3" json:"status_description"` Nominal github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,13,opt,name=nominal,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"nominal" yaml:"nominal"` + TriggerPrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,14,opt,name=triggerPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"trigger_price" yaml:"trigger_price"` + TriggerStatus bool `protobuf:"varint,15,opt,name=triggerStatus,proto3" json:"trigger_status"` } func (m *Order) Reset() { *m = Order{} } @@ -143,6 +145,13 @@ func (m *Order) GetStatusDescription() string { return "" } +func (m *Order) GetTriggerStatus() bool { + if m != nil { + return m.TriggerStatus + } + return false +} + type Cancellation struct { Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id"` Initiator CancellationInitiator `protobuf:"varint,2,opt,name=initiator,proto3,enum=seiprotocol.seichain.dex.CancellationInitiator" json:"initiator"` @@ -289,50 +298,54 @@ func init() { func init() { proto.RegisterFile("dex/order.proto", fileDescriptor_c2d5fab85368797d) } var fileDescriptor_c2d5fab85368797d = []byte{ - // 681 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6e, 0x13, 0x3d, - 0x14, 0xcd, 0xa4, 0xf9, 0x75, 0xd3, 0xf4, 0xab, 0x55, 0x55, 0xf3, 0x55, 0x28, 0x13, 0x05, 0x81, - 0x52, 0xa1, 0x66, 0x24, 0xd8, 0x20, 0xc4, 0xa6, 0x43, 0xa4, 0x0a, 0xa1, 0x0a, 0x30, 0xac, 0x10, - 0x28, 0x72, 0x6d, 0xab, 0xb5, 0x48, 0xc6, 0xe9, 0xd8, 0x41, 0xcd, 0x5b, 0xb0, 0x64, 0xc3, 0xfb, - 0x74, 0xd9, 0x25, 0x62, 0x61, 0xa1, 0x76, 0x37, 0xcb, 0x3e, 0x01, 0x9a, 0x3b, 0x33, 0x4d, 0xfa, - 0xa7, 0xd2, 0x45, 0x37, 0x99, 0xeb, 0x73, 0xcf, 0x39, 0xd7, 0x63, 0xdf, 0x3b, 0x41, 0xcb, 0x5c, - 0x1c, 0xfa, 0x2a, 0xe2, 0x22, 0xea, 0x8d, 0x23, 0x65, 0x14, 0x76, 0xb5, 0x90, 0x10, 0x31, 0x35, - 0xec, 0x69, 0x21, 0xd9, 0x3e, 0x95, 0x61, 0x8f, 0x8b, 0xc3, 0xf5, 0xd5, 0x3d, 0xb5, 0xa7, 0x20, - 0xe5, 0x27, 0x51, 0xca, 0x5f, 0x07, 0x03, 0x11, 0x4e, 0x46, 0x3a, 0x05, 0x3a, 0x3f, 0xaa, 0xa8, - 0xfc, 0x36, 0x31, 0xc4, 0xeb, 0xa8, 0x28, 0xb9, 0xeb, 0xb4, 0x9d, 0x6e, 0x29, 0x40, 0x47, 0xd6, - 0x73, 0x62, 0xeb, 0x15, 0x25, 0x27, 0x45, 0xc9, 0xf1, 0x0e, 0xaa, 0x68, 0x43, 0xcd, 0x44, 0xbb, - 0xc5, 0xb6, 0xd3, 0x6d, 0x3e, 0x7d, 0xd4, 0xbb, 0xa9, 0x6e, 0x0f, 0xcc, 0x3e, 0x00, 0x39, 0x68, - 0x66, 0x36, 0x99, 0x98, 0x64, 0x4f, 0xbc, 0x81, 0xaa, 0x94, 0x31, 0x35, 0x09, 0x8d, 0xbb, 0xd0, - 0x76, 0xba, 0xf5, 0x60, 0x39, 0x23, 0xe6, 0x30, 0xc9, 0x03, 0xfc, 0x12, 0x35, 0x98, 0x0a, 0x4d, - 0x44, 0x99, 0xd9, 0xe2, 0x3c, 0x72, 0x4b, 0xc0, 0x77, 0x33, 0xfe, 0x7f, 0x79, 0x6e, 0x40, 0x39, - 0x8f, 0x84, 0xd6, 0xe4, 0x02, 0x1b, 0x7f, 0x41, 0xe5, 0x71, 0x24, 0x99, 0x70, 0xcb, 0x20, 0xdb, - 0x3e, 0xb2, 0x5e, 0xe1, 0xb7, 0xf5, 0x1e, 0xef, 0x49, 0xb3, 0x3f, 0xd9, 0xed, 0x31, 0x35, 0xf2, - 0x99, 0xd2, 0x23, 0xa5, 0xb3, 0xc7, 0xa6, 0xe6, 0x5f, 0x7d, 0x33, 0x1d, 0x0b, 0xdd, 0xeb, 0x0b, - 0x16, 0x5b, 0x2f, 0x95, 0x9f, 0x59, 0xaf, 0x31, 0xa5, 0xa3, 0xe1, 0x8b, 0x0e, 0x2c, 0x3b, 0x24, - 0x85, 0xb1, 0x44, 0xb5, 0x83, 0x09, 0x0d, 0x8d, 0x34, 0x53, 0xb7, 0x02, 0x15, 0x76, 0xee, 0x5c, - 0xe1, 0xdc, 0xe1, 0xcc, 0x7a, 0xcb, 0x69, 0x91, 0x1c, 0xe9, 0x90, 0xf3, 0x24, 0xf6, 0x11, 0x82, - 0x9a, 0x7d, 0x11, 0xaa, 0x91, 0x5b, 0x4d, 0x4f, 0x2d, 0xb6, 0xde, 0x22, 0xa0, 0x03, 0x9e, 0xc0, - 0x64, 0x8e, 0x92, 0x08, 0xa8, 0xd6, 0xc2, 0xa4, 0x82, 0xda, 0x4c, 0x00, 0x68, 0x2e, 0x98, 0x51, - 0xf0, 0x7b, 0x54, 0x87, 0xce, 0xfa, 0x38, 0x1d, 0x0b, 0xb7, 0x0e, 0xd7, 0xfc, 0xf0, 0x96, 0x6b, - 0x4e, 0xa8, 0x41, 0x33, 0xb6, 0x1e, 0x02, 0xe5, 0x20, 0x79, 0x2f, 0x32, 0x73, 0xc1, 0x07, 0x68, - 0x65, 0xac, 0xb4, 0x34, 0x52, 0x85, 0x7d, 0x19, 0x09, 0x96, 0x04, 0x2e, 0x02, 0xeb, 0x27, 0x37, - 0x5b, 0xbf, 0xbb, 0x2c, 0x09, 0xd6, 0x62, 0xeb, 0xe1, 0xdc, 0x69, 0xc0, 0x73, 0x9c, 0x5c, 0x75, - 0xc7, 0x0f, 0x50, 0x89, 0x53, 0x43, 0xdd, 0x45, 0x78, 0xe1, 0x5a, 0x6c, 0x3d, 0x58, 0x13, 0xf8, - 0xc5, 0x7d, 0xb4, 0x92, 0xb6, 0x60, 0x5f, 0x68, 0x16, 0xc9, 0x31, 0x6c, 0xa8, 0x01, 0x54, 0xa8, - 0x91, 0x26, 0x07, 0x7c, 0x96, 0x25, 0x57, 0x05, 0x58, 0xa0, 0x6a, 0xa8, 0x46, 0x32, 0xa4, 0x43, - 0x77, 0x09, 0xb4, 0x6f, 0xee, 0x7c, 0xeb, 0xb9, 0xc1, 0x99, 0xf5, 0x9a, 0xe9, 0xa5, 0x67, 0x40, - 0x87, 0xe4, 0xa9, 0xce, 0xcf, 0x12, 0x6a, 0xbc, 0xa2, 0x21, 0x13, 0xc3, 0x21, 0x85, 0xba, 0x6b, - 0x73, 0x13, 0x5a, 0x99, 0x9b, 0xce, 0xcf, 0xa8, 0x2e, 0x43, 0x69, 0x24, 0x35, 0x2a, 0xca, 0x06, - 0xd4, 0xbf, 0xf9, 0x78, 0xe7, 0x2d, 0x5f, 0xe7, 0xb2, 0x60, 0x29, 0xb6, 0xde, 0xcc, 0x85, 0xcc, - 0xc2, 0x64, 0x58, 0x59, 0x24, 0xc0, 0xfb, 0xd2, 0xb0, 0x66, 0x30, 0xc9, 0x03, 0xfc, 0xfc, 0xda, - 0x61, 0x5d, 0xfd, 0x87, 0x41, 0xbd, 0xd8, 0xde, 0xe5, 0xbb, 0xb6, 0x77, 0xe5, 0xf6, 0xf6, 0xbe, - 0xb6, 0x17, 0xab, 0xf7, 0xda, 0x8b, 0xe7, 0x5f, 0x9f, 0xda, 0x7d, 0x7c, 0x7d, 0x3a, 0x1b, 0xa8, - 0xb1, 0xc5, 0x8c, 0xfc, 0x26, 0x60, 0x16, 0x35, 0xfe, 0x1f, 0x2d, 0x48, 0xae, 0x5d, 0xa7, 0xbd, - 0xd0, 0x2d, 0x05, 0xd5, 0xd8, 0x7a, 0xc9, 0x92, 0x24, 0x3f, 0xc1, 0xf6, 0xd1, 0x49, 0xcb, 0x39, - 0x3e, 0x69, 0x39, 0x7f, 0x4e, 0x5a, 0xce, 0xf7, 0xd3, 0x56, 0xe1, 0xf8, 0xb4, 0x55, 0xf8, 0x75, - 0xda, 0x2a, 0x7c, 0xda, 0x9c, 0xdb, 0x8c, 0x16, 0x72, 0x33, 0x3f, 0x06, 0x58, 0xc0, 0x39, 0xf8, - 0x87, 0x7e, 0xf2, 0xa7, 0x01, 0xfb, 0xda, 0xad, 0x40, 0xfe, 0xd9, 0xdf, 0x00, 0x00, 0x00, 0xff, - 0xff, 0x16, 0x0c, 0xff, 0x27, 0x89, 0x06, 0x00, 0x00, + // 737 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6a, 0xdb, 0x4c, + 0x14, 0xb5, 0x1c, 0xff, 0x4e, 0x1c, 0xfb, 0xcb, 0x10, 0x82, 0xbe, 0x50, 0x2c, 0xa3, 0xd2, 0xe2, + 0x50, 0x62, 0x41, 0xbb, 0x09, 0xa5, 0x9b, 0xa8, 0x86, 0x50, 0x4a, 0x68, 0x3a, 0x2d, 0x14, 0x4a, + 0x8b, 0x51, 0x34, 0x83, 0x33, 0xd4, 0xd6, 0x38, 0x9a, 0x71, 0x89, 0xe9, 0x4b, 0xf4, 0x05, 0xfa, + 0x3e, 0xd9, 0x35, 0xcb, 0xd2, 0x85, 0x28, 0xc9, 0x4e, 0xcb, 0x3c, 0x41, 0xd1, 0x95, 0x26, 0xb6, + 0xf3, 0x43, 0xea, 0x45, 0x36, 0xd6, 0x9d, 0x73, 0xcf, 0x39, 0x57, 0x9a, 0x99, 0x7b, 0x8d, 0x1a, + 0x94, 0x1d, 0x3b, 0x22, 0xa4, 0x2c, 0xec, 0x8c, 0x42, 0xa1, 0x04, 0x36, 0x25, 0xe3, 0x10, 0xf9, + 0x62, 0xd0, 0x91, 0x8c, 0xfb, 0x87, 0x1e, 0x0f, 0x3a, 0x94, 0x1d, 0x6f, 0xac, 0xf5, 0x45, 0x5f, + 0x40, 0xca, 0x49, 0xa2, 0x94, 0xbf, 0x01, 0x06, 0x2c, 0x18, 0x0f, 0x65, 0x0a, 0xd8, 0x3f, 0x2b, + 0xa8, 0xf8, 0x26, 0x31, 0xc4, 0x1b, 0x28, 0xcf, 0xa9, 0x69, 0xb4, 0x8c, 0x76, 0xc1, 0x45, 0x27, + 0x91, 0x65, 0xc4, 0x91, 0x95, 0xe7, 0x94, 0xe4, 0x39, 0xc5, 0x7b, 0xa8, 0x24, 0x95, 0xa7, 0xc6, + 0xd2, 0xcc, 0xb7, 0x8c, 0x76, 0xfd, 0xe9, 0xa3, 0xce, 0x6d, 0x75, 0x3b, 0x60, 0xf6, 0x0e, 0xc8, + 0x6e, 0x3d, 0xb3, 0xc9, 0xc4, 0x24, 0x7b, 0xe2, 0x4d, 0x54, 0xf6, 0x7c, 0x5f, 0x8c, 0x03, 0x65, + 0x2e, 0xb5, 0x8c, 0x76, 0xd5, 0x6d, 0x64, 0x44, 0x0d, 0x13, 0x1d, 0xe0, 0x17, 0xa8, 0xe6, 0x8b, + 0x40, 0x85, 0x9e, 0xaf, 0x76, 0x28, 0x0d, 0xcd, 0x02, 0xf0, 0xcd, 0x8c, 0xff, 0x9f, 0xce, 0xf5, + 0x3c, 0x4a, 0x43, 0x26, 0x25, 0x99, 0x63, 0xe3, 0xcf, 0xa8, 0x38, 0x0a, 0xb9, 0xcf, 0xcc, 0x22, + 0xc8, 0x76, 0x4f, 0x22, 0x2b, 0xf7, 0x3b, 0xb2, 0x1e, 0xf7, 0xb9, 0x3a, 0x1c, 0x1f, 0x74, 0x7c, + 0x31, 0x74, 0x7c, 0x21, 0x87, 0x42, 0x66, 0x8f, 0x2d, 0x49, 0xbf, 0x38, 0x6a, 0x32, 0x62, 0xb2, + 0xd3, 0x65, 0x7e, 0x1c, 0x59, 0xa9, 0xfc, 0x22, 0xb2, 0x6a, 0x13, 0x6f, 0x38, 0x78, 0x6e, 0xc3, + 0xd2, 0x26, 0x29, 0x8c, 0x39, 0xaa, 0x1c, 0x8d, 0xbd, 0x40, 0x71, 0x35, 0x31, 0x4b, 0x50, 0x61, + 0x6f, 0xe1, 0x0a, 0x97, 0x0e, 0x17, 0x91, 0xd5, 0x48, 0x8b, 0x68, 0xc4, 0x26, 0x97, 0x49, 0xec, + 0x20, 0x04, 0x35, 0xbb, 0x2c, 0x10, 0x43, 0xb3, 0x9c, 0xee, 0x5a, 0x1c, 0x59, 0xcb, 0x80, 0xf6, + 0x68, 0x02, 0x93, 0x19, 0x4a, 0x22, 0xf0, 0xa4, 0x64, 0x2a, 0x15, 0x54, 0xa6, 0x02, 0x40, 0xb5, + 0x60, 0x4a, 0xc1, 0x6f, 0x51, 0x15, 0x6e, 0xd6, 0xfb, 0xc9, 0x88, 0x99, 0x55, 0x38, 0xe6, 0x87, + 0x77, 0x1c, 0x73, 0x42, 0x75, 0xeb, 0x71, 0x64, 0x21, 0x50, 0xf6, 0x92, 0xef, 0x22, 0x53, 0x17, + 0x7c, 0x84, 0x56, 0x47, 0x42, 0x72, 0xc5, 0x45, 0xd0, 0xe5, 0x21, 0xf3, 0x93, 0xc0, 0x44, 0x60, + 0xfd, 0xe4, 0x76, 0xeb, 0xfd, 0xab, 0x12, 0x77, 0x3d, 0x8e, 0x2c, 0xac, 0x9d, 0x7a, 0x54, 0xe3, + 0xe4, 0xba, 0x3b, 0x7e, 0x80, 0x0a, 0xd4, 0x53, 0x9e, 0xb9, 0x0c, 0x1f, 0x5c, 0x89, 0x23, 0x0b, + 0xd6, 0x04, 0x7e, 0x71, 0x17, 0xad, 0xa6, 0x57, 0xb0, 0xcb, 0xa4, 0x1f, 0xf2, 0x11, 0xbc, 0x50, + 0x0d, 0xa8, 0x50, 0x23, 0x4d, 0xf6, 0xe8, 0x34, 0x4b, 0xae, 0x0b, 0x30, 0x43, 0xe5, 0x40, 0x0c, + 0x79, 0xe0, 0x0d, 0xcc, 0x15, 0xd0, 0xbe, 0x5e, 0xf8, 0xd4, 0xb5, 0xc1, 0x45, 0x64, 0xd5, 0xd3, + 0x43, 0xcf, 0x00, 0x9b, 0xe8, 0x14, 0xfe, 0x86, 0x6a, 0x2a, 0xe4, 0xfd, 0x3e, 0x0b, 0xf7, 0xe1, + 0x0e, 0xd7, 0xa1, 0xd6, 0x87, 0x85, 0x6b, 0xad, 0x64, 0x2e, 0x3d, 0x7d, 0x97, 0xd7, 0xd2, 0x8a, + 0x73, 0xb0, 0x4d, 0xe6, 0x8a, 0xe1, 0x6d, 0xa4, 0x65, 0x69, 0x2f, 0x9b, 0x8d, 0x96, 0xd1, 0xae, + 0xb8, 0x38, 0x8e, 0xac, 0xba, 0x16, 0x66, 0x5d, 0x3d, 0x4f, 0xb4, 0x7f, 0x14, 0x50, 0xed, 0xa5, + 0x17, 0xf8, 0x6c, 0x30, 0xf0, 0x60, 0xbb, 0xd6, 0x67, 0x06, 0x4b, 0x69, 0x66, 0xa8, 0x7c, 0x42, + 0x55, 0x1e, 0x70, 0xc5, 0x3d, 0x25, 0xc2, 0x6c, 0xae, 0x38, 0xb7, 0xdf, 0x8a, 0x59, 0xcb, 0x57, + 0x5a, 0xe6, 0xae, 0xc4, 0x91, 0x35, 0x75, 0x21, 0xd3, 0x30, 0x99, 0x31, 0x7e, 0xc8, 0xc0, 0xfb, + 0xca, 0x8c, 0xc9, 0x60, 0xa2, 0x03, 0xbc, 0x7d, 0xe3, 0x8c, 0x59, 0xfb, 0x87, 0xf9, 0x32, 0xdf, + 0x95, 0xc5, 0x45, 0xbb, 0xb2, 0x74, 0x77, 0x57, 0xde, 0xd8, 0x42, 0xe5, 0x7b, 0x6d, 0xa1, 0xcb, + 0xa1, 0x59, 0xb9, 0x8f, 0xa1, 0x69, 0x6f, 0xa2, 0xda, 0x8e, 0xaf, 0xf8, 0x57, 0x06, 0x23, 0x44, + 0xe2, 0xff, 0xd1, 0x12, 0xa7, 0xd2, 0x34, 0x5a, 0x4b, 0xed, 0x82, 0x5b, 0x8e, 0x23, 0x2b, 0x59, + 0x92, 0xe4, 0xc7, 0xdd, 0x3d, 0x39, 0x6b, 0x1a, 0xa7, 0x67, 0x4d, 0xe3, 0xcf, 0x59, 0xd3, 0xf8, + 0x7e, 0xde, 0xcc, 0x9d, 0x9e, 0x37, 0x73, 0xbf, 0xce, 0x9b, 0xb9, 0x8f, 0x5b, 0x33, 0x2f, 0x23, + 0x19, 0xdf, 0xd2, 0xdb, 0x00, 0x0b, 0xd8, 0x07, 0xe7, 0xd8, 0x49, 0xfe, 0xeb, 0xe0, 0xbd, 0x0e, + 0x4a, 0x90, 0x7f, 0xf6, 0x37, 0x00, 0x00, 0xff, 0xff, 0xa3, 0x4e, 0x8b, 0xbe, 0x40, 0x07, 0x00, + 0x00, } func (m *Order) Marshal() (dAtA []byte, err error) { @@ -355,6 +368,26 @@ func (m *Order) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TriggerStatus { + i-- + if m.TriggerStatus { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x78 + } + { + size := m.TriggerPrice.Size() + i -= size + if _, err := m.TriggerPrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOrder(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x72 { size := m.Nominal.Size() i -= size @@ -626,6 +659,11 @@ func (m *Order) Size() (n int) { } l = m.Nominal.Size() n += 1 + l + sovOrder(uint64(l)) + l = m.TriggerPrice.Size() + n += 1 + l + sovOrder(uint64(l)) + if m.TriggerStatus { + n += 2 + } return n } @@ -1086,6 +1124,60 @@ func (m *Order) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TriggerPrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthOrder + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOrder + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.TriggerPrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TriggerStatus", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.TriggerStatus = bool(v != 0) default: iNdEx = preIndex skippy, err := skipOrder(dAtA[iNdEx:]) diff --git a/x/dex/types/trigger_book.pb.go b/x/dex/types/trigger_book.pb.go new file mode 100644 index 0000000000..cc5504d90f --- /dev/null +++ b/x/dex/types/trigger_book.pb.go @@ -0,0 +1,434 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/trigger_book.proto + +package types + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type TriggerBook struct { + Order []*Order `protobuf:"bytes,1,rep,name=order,proto3" json:"order"` + PriceDenom string `protobuf:"bytes,2,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,3,opt,name=assetDenom,proto3" json:"asset_denom"` +} + +func (m *TriggerBook) Reset() { *m = TriggerBook{} } +func (m *TriggerBook) String() string { return proto.CompactTextString(m) } +func (*TriggerBook) ProtoMessage() {} +func (*TriggerBook) Descriptor() ([]byte, []int) { + return fileDescriptor_c1b5381dd75ec750, []int{0} +} +func (m *TriggerBook) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TriggerBook) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TriggerBook.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *TriggerBook) XXX_Merge(src proto.Message) { + xxx_messageInfo_TriggerBook.Merge(m, src) +} +func (m *TriggerBook) XXX_Size() int { + return m.Size() +} +func (m *TriggerBook) XXX_DiscardUnknown() { + xxx_messageInfo_TriggerBook.DiscardUnknown(m) +} + +var xxx_messageInfo_TriggerBook proto.InternalMessageInfo + +func (m *TriggerBook) GetOrder() []*Order { + if m != nil { + return m.Order + } + return nil +} + +func (m *TriggerBook) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *TriggerBook) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func init() { + proto.RegisterType((*TriggerBook)(nil), "seiprotocol.seichain.dex.TriggerBook") +} + +func init() { proto.RegisterFile("dex/trigger_book.proto", fileDescriptor_c1b5381dd75ec750) } + +var fileDescriptor_c1b5381dd75ec750 = []byte{ + // 256 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4b, 0x49, 0xad, 0xd0, + 0x2f, 0x29, 0xca, 0x4c, 0x4f, 0x4f, 0x2d, 0x8a, 0x4f, 0xca, 0xcf, 0xcf, 0xd6, 0x2b, 0x28, 0xca, + 0x2f, 0xc9, 0x17, 0x92, 0x28, 0x4e, 0xcd, 0x04, 0xb3, 0x92, 0xf3, 0x73, 0xf4, 0x8a, 0x53, 0x33, + 0x93, 0x33, 0x12, 0x33, 0xf3, 0xf4, 0x52, 0x52, 0x2b, 0xa4, 0xf8, 0x41, 0x3a, 0xf2, 0x8b, 0x52, + 0x52, 0x8b, 0x20, 0x4a, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x4c, 0x7d, 0x10, 0x0b, 0x22, + 0xaa, 0xb4, 0x91, 0x91, 0x8b, 0x3b, 0x04, 0x62, 0xae, 0x53, 0x7e, 0x7e, 0xb6, 0x90, 0x03, 0x17, + 0x2b, 0x58, 0x93, 0x04, 0xa3, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0xbc, 0x1e, 0x2e, 0x0b, 0xf4, 0xfc, + 0x41, 0xca, 0x9c, 0x38, 0x5f, 0xdd, 0x93, 0x87, 0xe8, 0x08, 0x82, 0x50, 0x42, 0xfa, 0x5c, 0x5c, + 0x05, 0x45, 0x99, 0xc9, 0xa9, 0x2e, 0xa9, 0x79, 0xf9, 0xb9, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x9c, + 0x4e, 0xfc, 0xaf, 0xee, 0xc9, 0x73, 0x83, 0x45, 0xe3, 0x53, 0x40, 0xc2, 0x41, 0x48, 0x4a, 0x40, + 0x1a, 0x12, 0x8b, 0x8b, 0x53, 0x4b, 0x20, 0x1a, 0x98, 0x11, 0x1a, 0xc0, 0xa2, 0x30, 0x0d, 0x08, + 0x25, 0x4e, 0xee, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, + 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x9b, 0x9e, + 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x5f, 0x9c, 0x9a, 0xa9, 0x0b, 0x73, 0x39, + 0x98, 0x03, 0x76, 0xba, 0x7e, 0x85, 0x3e, 0x38, 0x28, 0x2b, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, + 0xf2, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xce, 0xaf, 0x93, 0xf4, 0x5e, 0x01, 0x00, 0x00, +} + +func (m *TriggerBook) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *TriggerBook) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TriggerBook) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintTriggerBook(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x1a + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintTriggerBook(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.Order) > 0 { + for iNdEx := len(m.Order) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Order[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTriggerBook(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintTriggerBook(dAtA []byte, offset int, v uint64) int { + offset -= sovTriggerBook(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *TriggerBook) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Order) > 0 { + for _, e := range m.Order { + l = e.Size() + n += 1 + l + sovTriggerBook(uint64(l)) + } + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovTriggerBook(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovTriggerBook(uint64(l)) + } + return n +} + +func sovTriggerBook(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTriggerBook(x uint64) (n int) { + return sovTriggerBook(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *TriggerBook) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTriggerBook + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: TriggerBook: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TriggerBook: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Order", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTriggerBook + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTriggerBook + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTriggerBook + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Order = append(m.Order, &Order{}) + if err := m.Order[len(m.Order)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PriceDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTriggerBook + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTriggerBook + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTriggerBook + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssetDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTriggerBook + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthTriggerBook + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTriggerBook + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTriggerBook(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTriggerBook + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTriggerBook(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTriggerBook + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTriggerBook + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowTriggerBook + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthTriggerBook + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTriggerBook + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTriggerBook + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTriggerBook = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTriggerBook = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTriggerBook = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/utils/alias.go b/x/dex/types/utils/alias.go index 41d2b32360..f99773c504 100644 --- a/x/dex/types/utils/alias.go +++ b/x/dex/types/utils/alias.go @@ -2,6 +2,7 @@ package utils import ( "fmt" + "strings" "github.com/sei-protocol/sei-chain/x/dex/types" ) @@ -16,3 +17,8 @@ func GetPairString(pair *types.Pair) PairString { fmt.Sprintf("%s|%s", pair.PriceDenom, pair.AssetDenom), ) } + +func GetPriceAssetString(pairString PairString) (string, string) { + output := strings.Split(string(pairString), "|") + return output[0], output[1] +} From 8c58c176c79f84b293db7d34ecc30c6940e276d8 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 11 Oct 2022 17:02:47 -0400 Subject: [PATCH 02/12] fix linting errors --- proto/dex/trigger_book.proto | 2 +- x/dex/contract/execution.go | 8 ++++---- x/dex/exchange/limit_order.go | 1 - x/dex/keeper/trigger_book.go | 14 +++++++------- x/oracle/simulation/operations.go | 4 ++-- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/proto/dex/trigger_book.proto b/proto/dex/trigger_book.proto index 0076d749c8..48df56b1a1 100644 --- a/proto/dex/trigger_book.proto +++ b/proto/dex/trigger_book.proto @@ -15,4 +15,4 @@ message TriggerBook { string assetDenom = 3 [ (gogoproto.jsontag) = "asset_denom" ]; -} \ No newline at end of file +} diff --git a/x/dex/contract/execution.go b/x/dex/contract/execution.go index 7ccddd7d10..a397ae4658 100644 --- a/x/dex/contract/execution.go +++ b/x/dex/contract/execution.go @@ -120,14 +120,15 @@ func moveTriggeredOrderForPair( dexkeeper *keeper.Keeper, ) { priceDenom, assetDenom := dextypesutils.GetPriceAssetString(typedPairStr) - for _, order := range dexkeeper.GetAllTriggerBookOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) { + triggeredOrders := dexkeeper.GetAllTriggerBookOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) + for i, order := range triggeredOrders { if order.TriggerStatus { if order.OrderType == types.OrderType_STOPLOSS { order.OrderType = types.OrderType_MARKET } else if order.OrderType == types.OrderType_STOPLIMIT { order.OrderType = types.OrderType_LIMIT } - dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr).Add(&order) + dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr).Add(&triggeredOrders[i]) dexkeeper.RemoveTriggerBookOrder(ctx, string(typedContractAddr), order.Id, priceDenom, assetDenom) } } @@ -140,7 +141,6 @@ func updateTriggeredOrderForPair( dexkeeper *keeper.Keeper, totalOutcome exchange.ExecutionOutcome, ) { - orders := dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr) triggeredOrders := orders.GetTriggeredOrders() @@ -148,7 +148,7 @@ func updateTriggeredOrderForPair( priceDenom, assetDenom := dextypesutils.GetPriceAssetString(typedPairStr) for _, order := range dexkeeper.GetAllTriggerBookOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) { if (order.PositionDirection == types.PositionDirection_LONG && order.TriggerPrice.LTE(totalOutcome.MaxPrice)) || - order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { + order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { order.TriggerStatus = true dexkeeper.SetTriggerBookOrder(ctx, order.ContractAddr, order, order.PriceDenom, order.AssetDenom) } diff --git a/x/dex/exchange/limit_order.go b/x/dex/exchange/limit_order.go index 5e0c63b46a..48e3b4d7b3 100644 --- a/x/dex/exchange/limit_order.go +++ b/x/dex/exchange/limit_order.go @@ -24,7 +24,6 @@ func MatchLimitOrders( executed = orderbook.Shorts.Entries[shortPtr].GetEntry().Quantity } totalExecuted = totalExecuted.Add(executed).Add(executed) - // I think the line-below is off... but I'm not really sure I udnerstand the logic totalPrice = totalPrice.Add( executed.Mul( orderbook.Longs.Entries[longPtr].GetPrice().Add(orderbook.Shorts.Entries[shortPtr].GetPrice()), diff --git a/x/dex/keeper/trigger_book.go b/x/dex/keeper/trigger_book.go index 75585b3315..f0784f230b 100644 --- a/x/dex/keeper/trigger_book.go +++ b/x/dex/keeper/trigger_book.go @@ -17,17 +17,17 @@ func (k Keeper) SetTriggerBookOrder(ctx sdk.Context, contractAddr string, order store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) b := k.Cdc.MustMarshal(&order) - store.Set(GetKeyForOrderId(order.Id), b) + store.Set(GetKeyForOrderID(order.Id), b) } -func (k Keeper) RemoveTriggerBookOrder(ctx sdk.Context, contractAddr string, order_id uint64, priceDenom string, assetDenom string) { +func (k Keeper) RemoveTriggerBookOrder(ctx sdk.Context, contractAddr string, orderID uint64, priceDenom string, assetDenom string) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) - store.Delete(GetKeyForOrderId(order_id)) + store.Delete(GetKeyForOrderID(orderID)) } -func (k Keeper) GetTriggerBookByOrderId(ctx sdk.Context, contractAddr string, order_id uint64, priceDenom string, assetDenom string) (val types.Order, found bool) { +func (k Keeper) GetTriggerBookByOrderID(ctx sdk.Context, contractAddr string, orderID uint64, priceDenom string, assetDenom string) (val types.Order, found bool) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) - b := store.Get(GetKeyForOrderId(order_id)) + b := store.Get(GetKeyForOrderID(orderID)) if b == nil { return val, false } @@ -54,9 +54,9 @@ func (k Keeper) GetAllTriggerBookOrdersForPair(ctx sdk.Context, contractAddr str // return GetKeyForPrice(shortBook.Entry.Price) // } -func GetKeyForOrderId(order_id uint64) []byte { +func GetKeyForOrderID(orderID uint64) []byte { key := make([]byte, 8) - binary.LittleEndian.PutUint64(key, order_id) + binary.LittleEndian.PutUint64(key, orderID) return key } diff --git a/x/oracle/simulation/operations.go b/x/oracle/simulation/operations.go index 3988c4b164..2028e73625 100644 --- a/x/oracle/simulation/operations.go +++ b/x/oracle/simulation/operations.go @@ -65,7 +65,7 @@ func WeightedOperations( } // SimulateMsgAggregateExchangeRateVote generates a MsgAggregateExchangeRateVote with random values. -//nolint: funlen +// nolint: funlen func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -122,7 +122,7 @@ func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankK } // SimulateMsgDelegateFeedConsent generates a MsgDelegateFeedConsent with random values. -//nolint: funlen +// nolint: funlen func SimulateMsgDelegateFeedConsent(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, From f0d933e77dd709acb019121eb2d644c7213aa102 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Tue, 11 Oct 2022 17:31:09 -0400 Subject: [PATCH 03/12] add cache test --- x/dex/cache/order_test.go | 42 +++++++++++++++++++++++++++++++ x/oracle/simulation/operations.go | 2 -- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/x/dex/cache/order_test.go b/x/dex/cache/order_test.go index 56afb231b3..2fbea4d714 100644 --- a/x/dex/cache/order_test.go +++ b/x/dex/cache/order_test.go @@ -139,3 +139,45 @@ func TestGetSortedMarketOrders(t *testing.T) { require.Equal(t, uint64(6), marketSellsWithoutLiquidation[0].Id) require.Equal(t, uint64(5), marketSellsWithoutLiquidation[1].Id) } + +func TestGetTriggeredOrders(t *testing.T) { + ctx := sdk.Context{} + stateOne := dex.NewMemState() + stateOne.GetBlockOrders(ctx, utils.ContractAddress(TEST_CONTRACT), utils.PairString(TEST_PAIR)).Add(&types.Order{ + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_STOPLOSS, + Price: sdk.MustNewDecFromStr("150"), + TriggerPrice: sdk.MustNewDecFromStr("100"), + TriggerStatus: false, + }) + stateOne.GetBlockOrders(ctx, utils.ContractAddress(TEST_CONTRACT), utils.PairString(TEST_PAIR)).Add(&types.Order{ + Id: 2, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_STOPLIMIT, + Price: sdk.MustNewDecFromStr("150"), + TriggerPrice: sdk.MustNewDecFromStr("200"), + TriggerStatus: false, + }) + stateOne.GetBlockOrders(ctx, utils.ContractAddress(TEST_CONTRACT), utils.PairString(TEST_PAIR)).Add(&types.Order{ + Id: 3, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_LIMIT, + Price: sdk.MustNewDecFromStr("100"), + }) + + triggeredOrders := stateOne.GetBlockOrders(ctx, utils.ContractAddress(TEST_CONTRACT), utils.PairString(TEST_PAIR)).GetTriggeredOrders() + var orderIds []uint64 + for _, order := range triggeredOrders { + orderIds = append(orderIds, order.Id) + } + + require.Equal(t, len(triggeredOrders), 2) + require.ElementsMatch(t, orderIds, []uint64{1, 2}) +} diff --git a/x/oracle/simulation/operations.go b/x/oracle/simulation/operations.go index 2028e73625..a64072548d 100644 --- a/x/oracle/simulation/operations.go +++ b/x/oracle/simulation/operations.go @@ -65,7 +65,6 @@ func WeightedOperations( } // SimulateMsgAggregateExchangeRateVote generates a MsgAggregateExchangeRateVote with random values. -// nolint: funlen func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -122,7 +121,6 @@ func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankK } // SimulateMsgDelegateFeedConsent generates a MsgDelegateFeedConsent with random values. -// nolint: funlen func SimulateMsgDelegateFeedConsent(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, From 4651cb7e06d40fc990c56e7722e650232418eaa6 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Wed, 12 Oct 2022 03:13:22 -0400 Subject: [PATCH 04/12] add more tests --- x/dex/cache/order.go | 2 - x/dex/contract/execution.go | 44 ++++----- x/dex/contract/execution_test.go | 159 ++++++++++++++++++++++++++++++ x/dex/exchange/helpers_test.go | 64 ++++++++++++ x/dex/exchange/market_order.go | 1 + x/dex/keeper/trigger_book_test.go | 1 + x/dex/types/keys_test.go | 12 +++ x/dex/types/utils/alias_test.go | 6 ++ 8 files changed, 264 insertions(+), 25 deletions(-) create mode 100644 x/dex/contract/execution_test.go create mode 100644 x/dex/exchange/helpers_test.go create mode 100644 x/dex/keeper/trigger_book_test.go diff --git a/x/dex/cache/order.go b/x/dex/cache/order.go index 42cb9bc02a..967da54f2d 100644 --- a/x/dex/cache/order.go +++ b/x/dex/cache/order.go @@ -81,8 +81,6 @@ func (o *BlockOrders) GetLimitOrders(direction types.PositionDirection) []*types func (o *BlockOrders) GetTriggeredOrders() []*types.Order { o.mu.Lock() defer o.mu.Unlock() - // TODO: abstract the getOrdersByCriteria - // might be worth to get all directions too return o.getOrdersByCriteriaMap( map[types.OrderType]bool{ types.OrderType_STOPLOSS: true, diff --git a/x/dex/contract/execution.go b/x/dex/contract/execution.go index a397ae4658..0d78b06ffe 100644 --- a/x/dex/contract/execution.go +++ b/x/dex/contract/execution.go @@ -68,7 +68,7 @@ func ExecutePair( // Fill limit orders limitOrderOutcome := exchange.MatchLimitOrders(ctx, orderbook) totalOutcome := marketOrderOutcome.Merge(&limitOrderOutcome) - updateTriggeredOrderForPair(ctx, typedContractAddr, typedPairStr, dexkeeper, totalOutcome) + UpdateTriggeredOrderForPair(ctx, typedContractAddr, typedPairStr, dexkeeper, totalOutcome) dexkeeperutils.SetPriceStateFromExecutionOutcome(ctx, dexkeeper, typedContractAddr, pair, totalOutcome) dexkeeperutils.FlushOrderbook(ctx, dexkeeper, typedContractAddr, orderbook) @@ -113,7 +113,7 @@ func matchMarketOrderForPair( } -func moveTriggeredOrderForPair( +func MoveTriggeredOrderForPair( ctx sdk.Context, typedContractAddr dextypesutils.ContractAddress, typedPairStr dextypesutils.PairString, @@ -124,9 +124,9 @@ func moveTriggeredOrderForPair( for i, order := range triggeredOrders { if order.TriggerStatus { if order.OrderType == types.OrderType_STOPLOSS { - order.OrderType = types.OrderType_MARKET + triggeredOrders[i].OrderType = types.OrderType_MARKET } else if order.OrderType == types.OrderType_STOPLIMIT { - order.OrderType = types.OrderType_LIMIT + triggeredOrders[i].OrderType = types.OrderType_LIMIT } dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr).Add(&triggeredOrders[i]) dexkeeper.RemoveTriggerBookOrder(ctx, string(typedContractAddr), order.Id, priceDenom, assetDenom) @@ -134,38 +134,36 @@ func moveTriggeredOrderForPair( } } -func updateTriggeredOrderForPair( +func UpdateTriggeredOrderForPair( ctx sdk.Context, typedContractAddr dextypesutils.ContractAddress, typedPairStr dextypesutils.PairString, dexkeeper *keeper.Keeper, totalOutcome exchange.ExecutionOutcome, ) { - orders := dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr) - triggeredOrders := orders.GetTriggeredOrders() - // update existing trigger orders priceDenom, assetDenom := dextypesutils.GetPriceAssetString(typedPairStr) - for _, order := range dexkeeper.GetAllTriggerBookOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) { - if (order.PositionDirection == types.PositionDirection_LONG && order.TriggerPrice.LTE(totalOutcome.MaxPrice)) || - order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { - order.TriggerStatus = true - dexkeeper.SetTriggerBookOrder(ctx, order.ContractAddr, order, order.PriceDenom, order.AssetDenom) + triggeredOrders := dexkeeper.GetAllTriggerBookOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) + for i, order := range triggeredOrders { + if order.PositionDirection == types.PositionDirection_LONG && order.TriggerPrice.LTE(totalOutcome.MaxPrice) { + triggeredOrders[i].TriggerStatus = true + dexkeeper.SetTriggerBookOrder(ctx, string(typedContractAddr), triggeredOrders[i], priceDenom, assetDenom) + } else if order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { + triggeredOrders[i].TriggerStatus = true + dexkeeper.SetTriggerBookOrder(ctx, string(typedContractAddr), triggeredOrders[i], priceDenom, assetDenom) } } - for _, order := range triggeredOrders { + // update triggered orders in cache + orders := dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr) + cacheTriggeredOrders := orders.GetTriggeredOrders() + for i, order := range cacheTriggeredOrders { if order.PositionDirection == types.PositionDirection_LONG && order.TriggerPrice.LTE(totalOutcome.MaxPrice) { - // trigger order to close short position - buy back - order.TriggerStatus = true + cacheTriggeredOrders[i].TriggerStatus = true } else if order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { - // trigger order to close long position - sell back - order.TriggerStatus = true + cacheTriggeredOrders[i].TriggerStatus = true } - } - - for _, order := range triggeredOrders { - dexkeeper.SetTriggerBookOrder(ctx, order.ContractAddr, *order, order.PriceDenom, order.AssetDenom) + dexkeeper.SetTriggerBookOrder(ctx, string(typedContractAddr), *cacheTriggeredOrders[i], priceDenom, assetDenom) } } @@ -226,7 +224,7 @@ func ExecutePairsInParallel(ctx sdk.Context, contractAddr string, dexkeeper *kee pairCopy := pair pairStr := dextypesutils.GetPairString(&pairCopy) - moveTriggeredOrderForPair(ctx, typedContractAddr, pairStr, dexkeeper) + MoveTriggeredOrderForPair(ctx, typedContractAddr, pairStr, dexkeeper) orderbook, found := orderBooks.Load(pairStr) if !found { panic(fmt.Sprintf("Orderbook not found for %s", pairStr)) diff --git a/x/dex/contract/execution_test.go b/x/dex/contract/execution_test.go new file mode 100644 index 0000000000..ca1d0acac7 --- /dev/null +++ b/x/dex/contract/execution_test.go @@ -0,0 +1,159 @@ +package contract_test + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/contract" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/sei-protocol/sei-chain/x/dex/types/utils" + "github.com/stretchr/testify/require" +) + +func TEST_PAIR() types.Pair { + return types.Pair{ + PriceDenom: "usdc", + AssetDenom: "atom", + } +} + +const ( + TEST_CONTRACT = "test" + TestTimestamp uint64 = 10000 + TestHeight uint64 = 1 +) + +func TestMoveTriggeredOrderIntoMemState(t *testing.T) { + pair := TEST_PAIR() + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + triggeredOrder := types.Order{ + Id: 8, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_STOPLOSS, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("10"), + TriggerStatus: true, + } + + dexkeeper.SetTriggerBookOrder(ctx, TEST_CONTRACT, triggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + contract.MoveTriggeredOrderForPair( + ctx, + utils.ContractAddress(TEST_CONTRACT), + utils.GetPairString(&pair), + dexkeeper, + ) + orders := dexkeeper.MemState.GetBlockOrders(ctx, TEST_CONTRACT, utils.GetPairString(&pair)) + cacheMarketOrders := orders.GetSortedMarketOrders(types.PositionDirection_LONG, false) + cacheTriggeredOrders := orders.GetTriggeredOrders() + + triggeredBookOrders := dexkeeper.GetAllTriggerBookOrdersForPair(ctx, TEST_CONTRACT, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + + require.Equal(t, len(triggeredBookOrders), 0) + require.Equal(t, len(cacheTriggeredOrders), 0) + require.Equal(t, len(cacheMarketOrders), 1) + require.Equal(t, cacheMarketOrders[0].Id, uint64(8)) + require.Equal(t, cacheMarketOrders[0].OrderType, types.OrderType_MARKET) + require.Equal(t, cacheMarketOrders[0].PositionDirection, types.PositionDirection_LONG) +} + +func TestUpdateTriggeredOrders(t *testing.T) { + pair := TEST_PAIR() + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + shortTriggeredOrder := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_STOPLIMIT, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("6"), + TriggerStatus: false, + } + longTriggeredOrder := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_STOPLOSS, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("19"), + TriggerStatus: false, + } + shortNotTriggeredOrder := types.Order{ + Id: 3, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_STOPLOSS, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + longNotTriggeredOrder := types.Order{ + Id: 4, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_STOPLIMIT, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + TriggerPrice: sdk.MustNewDecFromStr("21"), + TriggerStatus: false, + } + + totalOutcome := exchange.ExecutionOutcome{ + TotalNotional: sdk.MustNewDecFromStr("10"), + TotalQuantity: sdk.MustNewDecFromStr("10"), + Settlements: []*types.SettlementEntry{}, + MinPrice: sdk.MustNewDecFromStr("5"), + MaxPrice: sdk.MustNewDecFromStr("20"), + } + + dexkeeper.SetTriggerBookOrder(ctx, TEST_CONTRACT, shortTriggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + dexkeeper.SetTriggerBookOrder(ctx, TEST_CONTRACT, longNotTriggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + orders := dexkeeper.MemState.GetBlockOrders(ctx, TEST_CONTRACT, utils.GetPairString(&pair)) + orders.Add(&shortNotTriggeredOrder) + orders.Add(&longTriggeredOrder) + + contract.UpdateTriggeredOrderForPair( + ctx, + utils.ContractAddress(TEST_CONTRACT), + utils.GetPairString(&pair), + dexkeeper, + totalOutcome, + ) + + triggeredBookOrders := dexkeeper.GetAllTriggerBookOrdersForPair(ctx, TEST_CONTRACT, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + + require.Equal(t, len(triggeredBookOrders), 4) + triggerStatusMap := map[uint64]bool{} + + for _, order := range triggeredBookOrders { + triggerStatusMap[order.Id] = order.TriggerStatus + } + require.Contains(t, triggerStatusMap, uint64(1)) + require.Contains(t, triggerStatusMap, uint64(2)) + require.Contains(t, triggerStatusMap, uint64(3)) + require.Contains(t, triggerStatusMap, uint64(4)) + + require.Equal(t, triggerStatusMap[uint64(1)], true) + require.Equal(t, triggerStatusMap[uint64(2)], true) + require.Equal(t, triggerStatusMap[uint64(3)], false) + require.Equal(t, triggerStatusMap[uint64(4)], false) +} diff --git a/x/dex/exchange/helpers_test.go b/x/dex/exchange/helpers_test.go new file mode 100644 index 0000000000..3b271c3896 --- /dev/null +++ b/x/dex/exchange/helpers_test.go @@ -0,0 +1,64 @@ +package exchange_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMergeExecutionOutcomes(t *testing.T) { + s1 := types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(5), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + } + + s2 := types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(5), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + } + + e1 := exchange.ExecutionOutcome{ + TotalNotional: sdk.MustNewDecFromStr("1"), + TotalQuantity: sdk.MustNewDecFromStr("2"), + Settlements: []*types.SettlementEntry{&s1, &s2, &s1}, + MinPrice: sdk.MustNewDecFromStr("1"), + MaxPrice: sdk.MustNewDecFromStr("4"), + } + + e2 := exchange.ExecutionOutcome{ + TotalNotional: sdk.MustNewDecFromStr("4"), + TotalQuantity: sdk.MustNewDecFromStr("4"), + Settlements: []*types.SettlementEntry{&s1, &s2}, + MinPrice: sdk.MustNewDecFromStr("0.5"), + MaxPrice: sdk.MustNewDecFromStr("3"), + } + + outcome := e1.Merge(&e2) + + require.Equal(t, outcome.TotalNotional, sdk.MustNewDecFromStr("5")) + require.Equal(t, outcome.TotalQuantity, sdk.MustNewDecFromStr("6")) + require.Equal(t, len(outcome.Settlements), 5) + require.Equal(t, outcome.MinPrice, sdk.MustNewDecFromStr("0.5")) + require.Equal(t, outcome.MaxPrice, sdk.MustNewDecFromStr("4")) +} diff --git a/x/dex/exchange/market_order.go b/x/dex/exchange/market_order.go index 68595bd57c..019d9317dd 100644 --- a/x/dex/exchange/market_order.go +++ b/x/dex/exchange/market_order.go @@ -36,6 +36,7 @@ func MatchMarketOrders( for _, settlement := range allTakerSettlements { settlement.ExecutionCostOrProceed = clearingPrice } + minPrice, maxPrice = clearingPrice, clearingPrice settlements = append(settlements, allTakerSettlements...) } return ExecutionOutcome{ diff --git a/x/dex/keeper/trigger_book_test.go b/x/dex/keeper/trigger_book_test.go new file mode 100644 index 0000000000..9429264902 --- /dev/null +++ b/x/dex/keeper/trigger_book_test.go @@ -0,0 +1 @@ +package keeper_test diff --git a/x/dex/types/keys_test.go b/x/dex/types/keys_test.go index a091dade92..94f303ec66 100644 --- a/x/dex/types/keys_test.go +++ b/x/dex/types/keys_test.go @@ -22,3 +22,15 @@ func TestPricePrefix(t *testing.T) { expectedKey := append(priceContractBytes, pairBytes...) require.Equal(t, expectedKey, types.PricePrefix(testContract, testPriceDenom, testAssetDenom)) } + +func TestTriggerOrderBookPrefix(t *testing.T) { + testContract := "test" + testPriceDenom := "SEI" + testAssetDenom := "ATOM" + + triggerBookContractBytes := append([]byte(types.TriggerBookKey), []byte(testContract)...) + pairBytes := types.PairPrefix(testPriceDenom, testAssetDenom) + expectedKey := append(triggerBookContractBytes, pairBytes...) + + require.Equal(t, expectedKey, types.TriggerOrderBookPrefix(testContract, testPriceDenom, testAssetDenom)) +} diff --git a/x/dex/types/utils/alias_test.go b/x/dex/types/utils/alias_test.go index f3077f1121..893b571eb9 100644 --- a/x/dex/types/utils/alias_test.go +++ b/x/dex/types/utils/alias_test.go @@ -13,3 +13,9 @@ func TestGetPairString(t *testing.T) { expected := utils.PairString("USDC|ATOM") require.Equal(t, expected, utils.GetPairString(&pair)) } + +func TestGetPriceAssetString(t *testing.T) { + priceDenom, assetDenom := utils.GetPriceAssetString(utils.PairString("USDC|ATOM")) + require.Equal(t, "USDC", priceDenom) + require.Equal(t, "ATOM", assetDenom) +} From 98a6bb6b747988737c2c7805b08ea23bc1b3d089 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Wed, 12 Oct 2022 11:41:19 -0400 Subject: [PATCH 05/12] restructure genesis message to be a list of orders --- proto/dex/genesis.proto | 4 +- proto/dex/trigger_book.proto | 18 -- x/dex/contract/execution.go | 12 +- x/dex/contract/execution_test.go | 10 +- x/dex/genesis.go | 5 +- x/dex/keeper/trigger_book.go | 14 +- x/dex/types/genesis.pb.go | 86 +++--- x/dex/types/trigger_book.pb.go | 434 ------------------------------- 8 files changed, 66 insertions(+), 517 deletions(-) delete mode 100644 proto/dex/trigger_book.proto delete mode 100644 x/dex/types/trigger_book.pb.go diff --git a/proto/dex/genesis.proto b/proto/dex/genesis.proto index 505e515177..9a1320da39 100644 --- a/proto/dex/genesis.proto +++ b/proto/dex/genesis.proto @@ -7,7 +7,7 @@ import "dex/long_book.proto"; import "dex/short_book.proto"; import "dex/twap.proto"; import "dex/tick_size.proto"; -import "dex/trigger_book.proto"; +import "dex/order.proto"; // this line is used by starport scaffolding # genesis/proto/import option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; @@ -20,6 +20,6 @@ message GenesisState { repeated Twap twapList = 4; repeated TickSize tickSizeList = 5; // if null, then no restriction, todo(zw) should set it to not nullable? uint64 lastEpoch = 6; - repeated TriggerBook triggerBookList = 7 [(gogoproto.nullable) = false]; + repeated Order triggeredOrdersList = 7 [(gogoproto.nullable) = false]; // this line is used by starport scaffolding # genesis/proto/state } diff --git a/proto/dex/trigger_book.proto b/proto/dex/trigger_book.proto deleted file mode 100644 index 48df56b1a1..0000000000 --- a/proto/dex/trigger_book.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; -package seiprotocol.seichain.dex; - -option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; -import "dex/order.proto"; -import "gogoproto/gogo.proto"; - -message TriggerBook { - repeated Order order = 1 [ - (gogoproto.jsontag) = "order" - ]; - string priceDenom = 2 [ - (gogoproto.jsontag) = "price_denom" - ]; - string assetDenom = 3 [ - (gogoproto.jsontag) = "asset_denom" - ]; -} diff --git a/x/dex/contract/execution.go b/x/dex/contract/execution.go index 0d78b06ffe..ad1825d716 100644 --- a/x/dex/contract/execution.go +++ b/x/dex/contract/execution.go @@ -120,7 +120,7 @@ func MoveTriggeredOrderForPair( dexkeeper *keeper.Keeper, ) { priceDenom, assetDenom := dextypesutils.GetPriceAssetString(typedPairStr) - triggeredOrders := dexkeeper.GetAllTriggerBookOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) + triggeredOrders := dexkeeper.GetAllTriggeredOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) for i, order := range triggeredOrders { if order.TriggerStatus { if order.OrderType == types.OrderType_STOPLOSS { @@ -129,7 +129,7 @@ func MoveTriggeredOrderForPair( triggeredOrders[i].OrderType = types.OrderType_LIMIT } dexkeeper.MemState.GetBlockOrders(ctx, typedContractAddr, typedPairStr).Add(&triggeredOrders[i]) - dexkeeper.RemoveTriggerBookOrder(ctx, string(typedContractAddr), order.Id, priceDenom, assetDenom) + dexkeeper.RemoveTriggeredOrder(ctx, string(typedContractAddr), order.Id, priceDenom, assetDenom) } } } @@ -143,14 +143,14 @@ func UpdateTriggeredOrderForPair( ) { // update existing trigger orders priceDenom, assetDenom := dextypesutils.GetPriceAssetString(typedPairStr) - triggeredOrders := dexkeeper.GetAllTriggerBookOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) + triggeredOrders := dexkeeper.GetAllTriggeredOrdersForPair(ctx, string(typedContractAddr), priceDenom, assetDenom) for i, order := range triggeredOrders { if order.PositionDirection == types.PositionDirection_LONG && order.TriggerPrice.LTE(totalOutcome.MaxPrice) { triggeredOrders[i].TriggerStatus = true - dexkeeper.SetTriggerBookOrder(ctx, string(typedContractAddr), triggeredOrders[i], priceDenom, assetDenom) + dexkeeper.SetTriggeredOrder(ctx, string(typedContractAddr), triggeredOrders[i], priceDenom, assetDenom) } else if order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { triggeredOrders[i].TriggerStatus = true - dexkeeper.SetTriggerBookOrder(ctx, string(typedContractAddr), triggeredOrders[i], priceDenom, assetDenom) + dexkeeper.SetTriggeredOrder(ctx, string(typedContractAddr), triggeredOrders[i], priceDenom, assetDenom) } } @@ -163,7 +163,7 @@ func UpdateTriggeredOrderForPair( } else if order.PositionDirection == types.PositionDirection_SHORT && order.TriggerPrice.GTE(totalOutcome.MinPrice) { cacheTriggeredOrders[i].TriggerStatus = true } - dexkeeper.SetTriggerBookOrder(ctx, string(typedContractAddr), *cacheTriggeredOrders[i], priceDenom, assetDenom) + dexkeeper.SetTriggeredOrder(ctx, string(typedContractAddr), *cacheTriggeredOrders[i], priceDenom, assetDenom) } } diff --git a/x/dex/contract/execution_test.go b/x/dex/contract/execution_test.go index ca1d0acac7..2e5d93c4d9 100644 --- a/x/dex/contract/execution_test.go +++ b/x/dex/contract/execution_test.go @@ -43,7 +43,7 @@ func TestMoveTriggeredOrderIntoMemState(t *testing.T) { TriggerStatus: true, } - dexkeeper.SetTriggerBookOrder(ctx, TEST_CONTRACT, triggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + dexkeeper.SetTriggeredOrder(ctx, TEST_CONTRACT, triggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) contract.MoveTriggeredOrderForPair( ctx, utils.ContractAddress(TEST_CONTRACT), @@ -54,7 +54,7 @@ func TestMoveTriggeredOrderIntoMemState(t *testing.T) { cacheMarketOrders := orders.GetSortedMarketOrders(types.PositionDirection_LONG, false) cacheTriggeredOrders := orders.GetTriggeredOrders() - triggeredBookOrders := dexkeeper.GetAllTriggerBookOrdersForPair(ctx, TEST_CONTRACT, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + triggeredBookOrders := dexkeeper.GetAllTriggeredOrdersForPair(ctx, TEST_CONTRACT, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) require.Equal(t, len(triggeredBookOrders), 0) require.Equal(t, len(cacheTriggeredOrders), 0) @@ -125,8 +125,8 @@ func TestUpdateTriggeredOrders(t *testing.T) { MaxPrice: sdk.MustNewDecFromStr("20"), } - dexkeeper.SetTriggerBookOrder(ctx, TEST_CONTRACT, shortTriggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) - dexkeeper.SetTriggerBookOrder(ctx, TEST_CONTRACT, longNotTriggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + dexkeeper.SetTriggeredOrder(ctx, TEST_CONTRACT, shortTriggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + dexkeeper.SetTriggeredOrder(ctx, TEST_CONTRACT, longNotTriggeredOrder, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) orders := dexkeeper.MemState.GetBlockOrders(ctx, TEST_CONTRACT, utils.GetPairString(&pair)) orders.Add(&shortNotTriggeredOrder) orders.Add(&longTriggeredOrder) @@ -139,7 +139,7 @@ func TestUpdateTriggeredOrders(t *testing.T) { totalOutcome, ) - triggeredBookOrders := dexkeeper.GetAllTriggerBookOrdersForPair(ctx, TEST_CONTRACT, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) + triggeredBookOrders := dexkeeper.GetAllTriggeredOrdersForPair(ctx, TEST_CONTRACT, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom) require.Equal(t, len(triggeredBookOrders), 4) triggerStatusMap := map[uint64]bool{} diff --git a/x/dex/genesis.go b/x/dex/genesis.go index 8db9042c6a..f993907d17 100644 --- a/x/dex/genesis.go +++ b/x/dex/genesis.go @@ -19,8 +19,9 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) k.SetShortBook(ctx, "genesis", elem) } - for _, elem := range genState.TriggerBookList { - k.SetTriggerBook(ctx, "genesis", elem) + for _, elem := range genState.TriggeredOrdersList { + // not sure if it's guaranteed that the Order has the correct Price/Asset/Contract details... + k.SetTriggeredOrder(ctx, "genesis", elem, elem.PriceDenom, elem.AssetDenom) } // Set initial tick size for each pair diff --git a/x/dex/keeper/trigger_book.go b/x/dex/keeper/trigger_book.go index f0784f230b..a840bc849a 100644 --- a/x/dex/keeper/trigger_book.go +++ b/x/dex/keeper/trigger_book.go @@ -9,23 +9,23 @@ import ( ) // I don't think this is proper lmao -func (k Keeper) SetTriggerBook(ctx sdk.Context, contractAddr string, triggerBook types.TriggerBook) { - prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, triggerBook.PriceDenom, triggerBook.AssetDenom)) -} +// func (k Keeper) SetTriggerBook(ctx sdk.Context, contractAddr string, triggerBook types.TriggerBook) { +// prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, triggerBook.PriceDenom, triggerBook.AssetDenom)) +// } -func (k Keeper) SetTriggerBookOrder(ctx sdk.Context, contractAddr string, order types.Order, priceDenom string, assetDenom string) { +func (k Keeper) SetTriggeredOrder(ctx sdk.Context, contractAddr string, order types.Order, priceDenom string, assetDenom string) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) b := k.Cdc.MustMarshal(&order) store.Set(GetKeyForOrderID(order.Id), b) } -func (k Keeper) RemoveTriggerBookOrder(ctx sdk.Context, contractAddr string, orderID uint64, priceDenom string, assetDenom string) { +func (k Keeper) RemoveTriggeredOrder(ctx sdk.Context, contractAddr string, orderID uint64, priceDenom string, assetDenom string) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) store.Delete(GetKeyForOrderID(orderID)) } -func (k Keeper) GetTriggerBookByOrderID(ctx sdk.Context, contractAddr string, orderID uint64, priceDenom string, assetDenom string) (val types.Order, found bool) { +func (k Keeper) GetTriggeredOrderByID(ctx sdk.Context, contractAddr string, orderID uint64, priceDenom string, assetDenom string) (val types.Order, found bool) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) b := store.Get(GetKeyForOrderID(orderID)) if b == nil { @@ -35,7 +35,7 @@ func (k Keeper) GetTriggerBookByOrderID(ctx sdk.Context, contractAddr string, or return val, true } -func (k Keeper) GetAllTriggerBookOrdersForPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string) (list []types.Order) { +func (k Keeper) GetAllTriggeredOrdersForPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string) (list []types.Order) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) iterator := sdk.KVStorePrefixIterator(store, []byte{}) diff --git a/x/dex/types/genesis.pb.go b/x/dex/types/genesis.pb.go index f8c33901fc..140f71f87e 100644 --- a/x/dex/types/genesis.pb.go +++ b/x/dex/types/genesis.pb.go @@ -25,13 +25,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the dex module's genesis state. type GenesisState struct { - Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` - LongBookList []LongBook `protobuf:"bytes,2,rep,name=longBookList,proto3" json:"longBookList"` - ShortBookList []ShortBook `protobuf:"bytes,3,rep,name=shortBookList,proto3" json:"shortBookList"` - TwapList []*Twap `protobuf:"bytes,4,rep,name=twapList,proto3" json:"twapList,omitempty"` - TickSizeList []*TickSize `protobuf:"bytes,5,rep,name=tickSizeList,proto3" json:"tickSizeList,omitempty"` - LastEpoch uint64 `protobuf:"varint,6,opt,name=lastEpoch,proto3" json:"lastEpoch,omitempty"` - TriggerBookList []TriggerBook `protobuf:"bytes,7,rep,name=triggerBookList,proto3" json:"triggerBookList"` + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + LongBookList []LongBook `protobuf:"bytes,2,rep,name=longBookList,proto3" json:"longBookList"` + ShortBookList []ShortBook `protobuf:"bytes,3,rep,name=shortBookList,proto3" json:"shortBookList"` + TwapList []*Twap `protobuf:"bytes,4,rep,name=twapList,proto3" json:"twapList,omitempty"` + TickSizeList []*TickSize `protobuf:"bytes,5,rep,name=tickSizeList,proto3" json:"tickSizeList,omitempty"` + LastEpoch uint64 `protobuf:"varint,6,opt,name=lastEpoch,proto3" json:"lastEpoch,omitempty"` + TriggeredOrdersList []Order `protobuf:"bytes,7,rep,name=triggeredOrdersList,proto3" json:"triggeredOrdersList"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -109,9 +109,9 @@ func (m *GenesisState) GetLastEpoch() uint64 { return 0 } -func (m *GenesisState) GetTriggerBookList() []TriggerBook { +func (m *GenesisState) GetTriggeredOrdersList() []Order { if m != nil { - return m.TriggerBookList + return m.TriggeredOrdersList } return nil } @@ -123,32 +123,32 @@ func init() { func init() { proto.RegisterFile("dex/genesis.proto", fileDescriptor_a803aaabd08db59d) } var fileDescriptor_a803aaabd08db59d = []byte{ - // 386 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xcb, 0x4e, 0xc2, 0x40, - 0x18, 0x85, 0x5b, 0x41, 0xd4, 0x01, 0x6f, 0x23, 0x31, 0x0d, 0x31, 0xb5, 0xc1, 0x98, 0xb0, 0xa1, - 0x4d, 0x70, 0xe7, 0xc2, 0x05, 0x89, 0xb2, 0x21, 0xd1, 0x14, 0xdc, 0xb8, 0x21, 0xa5, 0x4c, 0xda, - 0x09, 0x97, 0x69, 0x3a, 0x63, 0x40, 0x9e, 0xc2, 0xc7, 0x62, 0xc9, 0xd2, 0x95, 0x31, 0x90, 0xf8, - 0x1c, 0x66, 0x7e, 0x86, 0x9b, 0x49, 0x75, 0x37, 0x9c, 0x39, 0xe7, 0xfb, 0xff, 0x33, 0x14, 0x9d, - 0x76, 0xc8, 0xc8, 0x09, 0xc8, 0x80, 0x70, 0xca, 0xed, 0x28, 0x66, 0x82, 0x61, 0x83, 0x13, 0x0a, - 0x27, 0x9f, 0xf5, 0x6c, 0x4e, 0xa8, 0x1f, 0x7a, 0x74, 0x60, 0x77, 0xc8, 0xa8, 0x90, 0x0f, 0x58, - 0xc0, 0xe0, 0xca, 0x91, 0xa7, 0x85, 0xbf, 0x70, 0x22, 0x11, 0x91, 0x17, 0x7b, 0x7d, 0x45, 0x28, - 0x9c, 0x49, 0xa5, 0xc7, 0x06, 0x41, 0xab, 0xcd, 0x58, 0x57, 0x89, 0x79, 0x29, 0xf2, 0x90, 0xc5, - 0x62, 0x53, 0x3d, 0x92, 0xaa, 0x18, 0x7a, 0xd1, 0x66, 0x54, 0x50, 0xbf, 0xdb, 0xe2, 0x74, 0x4c, - 0x94, 0x78, 0x0e, 0x62, 0x4c, 0x83, 0x80, 0xc4, 0x1b, 0xe1, 0xe2, 0x77, 0x0a, 0xe5, 0x6a, 0x8b, - 0xdd, 0x1b, 0xc2, 0x13, 0x04, 0xdf, 0xa1, 0xcc, 0x62, 0x11, 0x43, 0xb7, 0xf4, 0x52, 0xb6, 0x62, - 0xd9, 0x49, 0x5d, 0xec, 0x27, 0xf0, 0x55, 0xd3, 0x93, 0xcf, 0x4b, 0xcd, 0x55, 0x29, 0x5c, 0x47, - 0x39, 0xb9, 0x76, 0x95, 0xb1, 0x6e, 0x9d, 0x72, 0x61, 0xec, 0x58, 0xa9, 0x52, 0xb6, 0x52, 0x4c, - 0xa6, 0xd4, 0x95, 0x5b, 0x71, 0xb6, 0xd2, 0xf8, 0x11, 0x1d, 0x42, 0xdf, 0x15, 0x2e, 0x05, 0xb8, - 0xab, 0x64, 0x5c, 0x63, 0x69, 0x57, 0xbc, 0xed, 0x3c, 0xbe, 0x45, 0xfb, 0xf2, 0xa9, 0x80, 0x95, - 0x06, 0x96, 0x99, 0xcc, 0x6a, 0x0e, 0xbd, 0xc8, 0x5d, 0xf9, 0xf1, 0x03, 0xca, 0xc9, 0x67, 0x6d, - 0xd0, 0x31, 0x81, 0xfc, 0xee, 0x7f, 0xd5, 0x9a, 0xca, 0xed, 0x6e, 0xe5, 0xf0, 0x05, 0x3a, 0xe8, - 0x79, 0x5c, 0xdc, 0x47, 0xcc, 0x0f, 0x8d, 0x8c, 0xa5, 0x97, 0xd2, 0xee, 0x5a, 0xc0, 0xcf, 0xe8, - 0x58, 0xfd, 0x4f, 0xab, 0xd2, 0x7b, 0x30, 0xe8, 0xfa, 0x8f, 0x41, 0xeb, 0x80, 0xaa, 0xfd, 0x9b, - 0x51, 0xad, 0x4d, 0x66, 0xa6, 0x3e, 0x9d, 0x99, 0xfa, 0xd7, 0xcc, 0xd4, 0xdf, 0xe7, 0xa6, 0x36, - 0x9d, 0x9b, 0xda, 0xc7, 0xdc, 0xd4, 0x5e, 0xca, 0x01, 0x15, 0xe1, 0x6b, 0xdb, 0xf6, 0x59, 0xdf, - 0xe1, 0x84, 0x96, 0x97, 0x23, 0xe0, 0x07, 0xcc, 0x70, 0x46, 0x0e, 0x7c, 0x3e, 0x6f, 0x11, 0xe1, - 0xed, 0x0c, 0xdc, 0xdf, 0xfc, 0x04, 0x00, 0x00, 0xff, 0xff, 0x60, 0xfa, 0x1f, 0x27, 0xf7, 0x02, - 0x00, 0x00, + // 395 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0xcf, 0x6a, 0xea, 0x40, + 0x18, 0xc5, 0x93, 0xab, 0xd7, 0x7b, 0xef, 0xe8, 0xed, 0x9f, 0xd1, 0x45, 0x90, 0x12, 0x83, 0xdd, + 0xb8, 0x31, 0x01, 0xbb, 0xeb, 0xa2, 0x0b, 0xa1, 0x75, 0x23, 0x58, 0xa2, 0x50, 0xe8, 0x46, 0x62, + 0x32, 0x24, 0x83, 0x7f, 0x26, 0x64, 0xa6, 0x68, 0x7d, 0x8a, 0x3e, 0x96, 0x4b, 0x97, 0x5d, 0x95, + 0xa2, 0x9b, 0x3e, 0x46, 0x99, 0x2f, 0xa3, 0x55, 0x68, 0xe8, 0x6e, 0x3c, 0x73, 0xce, 0xef, 0x7c, + 0xdf, 0x18, 0x74, 0x1e, 0x90, 0x85, 0x13, 0x92, 0x19, 0xe1, 0x94, 0xdb, 0x71, 0xc2, 0x04, 0xc3, + 0x06, 0x27, 0x14, 0x4e, 0x3e, 0x9b, 0xd8, 0x9c, 0x50, 0x3f, 0xf2, 0xe8, 0xcc, 0x0e, 0xc8, 0xa2, + 0x5a, 0x09, 0x59, 0xc8, 0xe0, 0xca, 0x91, 0xa7, 0xd4, 0x5f, 0x3d, 0x93, 0x88, 0xd8, 0x4b, 0xbc, + 0xa9, 0x22, 0x54, 0xcb, 0x52, 0x99, 0xb0, 0x59, 0x38, 0x1c, 0x31, 0x36, 0x56, 0x62, 0x45, 0x8a, + 0x3c, 0x62, 0x89, 0x38, 0x54, 0x4f, 0xa4, 0x2a, 0xe6, 0x5e, 0x7c, 0x18, 0x15, 0xd4, 0x1f, 0x0f, + 0x39, 0x5d, 0x12, 0x25, 0x9e, 0x4a, 0x91, 0x25, 0x01, 0x49, 0x52, 0xa1, 0xfe, 0x91, 0x43, 0xa5, + 0x4e, 0x3a, 0x74, 0x5f, 0x78, 0x82, 0xe0, 0x1b, 0x54, 0x48, 0x27, 0x30, 0x74, 0x4b, 0x6f, 0x14, + 0x5b, 0x96, 0x9d, 0xb5, 0x84, 0x7d, 0x0f, 0xbe, 0x76, 0x7e, 0xf5, 0x56, 0xd3, 0x5c, 0x95, 0xc2, + 0x5d, 0x54, 0x92, 0xf3, 0xb6, 0x19, 0x1b, 0x77, 0x29, 0x17, 0xc6, 0x2f, 0x2b, 0xd7, 0x28, 0xb6, + 0xea, 0xd9, 0x94, 0xae, 0x72, 0x2b, 0xce, 0x51, 0x1a, 0xf7, 0xd0, 0x7f, 0x58, 0x74, 0x8f, 0xcb, + 0x01, 0xee, 0x32, 0x1b, 0xd7, 0xdf, 0xd9, 0x15, 0xef, 0x38, 0x8f, 0xaf, 0xd1, 0x5f, 0xf9, 0x46, + 0xc0, 0xca, 0x03, 0xcb, 0xcc, 0x66, 0x0d, 0xe6, 0x5e, 0xec, 0xee, 0xfd, 0xf8, 0x0e, 0x95, 0xe4, + 0x7b, 0xf6, 0xe9, 0x92, 0x40, 0xfe, 0xf7, 0x4f, 0xab, 0x0d, 0x94, 0xdb, 0x3d, 0xca, 0xe1, 0x0b, + 0xf4, 0x6f, 0xe2, 0x71, 0x71, 0x1b, 0x33, 0x3f, 0x32, 0x0a, 0x96, 0xde, 0xc8, 0xbb, 0x5f, 0x02, + 0x7e, 0x40, 0x65, 0x91, 0xd0, 0x30, 0x24, 0x09, 0x09, 0x7a, 0xf2, 0x9f, 0xe2, 0x50, 0xf6, 0x07, + 0xca, 0x6a, 0xd9, 0x65, 0xe0, 0x55, 0x4b, 0x7f, 0x47, 0x68, 0x77, 0x56, 0x1b, 0x53, 0x5f, 0x6f, + 0x4c, 0xfd, 0x7d, 0x63, 0xea, 0x2f, 0x5b, 0x53, 0x5b, 0x6f, 0x4d, 0xed, 0x75, 0x6b, 0x6a, 0x8f, + 0xcd, 0x90, 0x8a, 0xe8, 0x69, 0x64, 0xfb, 0x6c, 0xea, 0x70, 0x42, 0x9b, 0xbb, 0x02, 0xf8, 0x01, + 0x0d, 0xce, 0xc2, 0x81, 0xcf, 0xe9, 0x39, 0x26, 0x7c, 0x54, 0x80, 0xfb, 0xab, 0xcf, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x78, 0x93, 0xaa, 0xbc, 0xf2, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -171,10 +171,10 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l - if len(m.TriggerBookList) > 0 { - for iNdEx := len(m.TriggerBookList) - 1; iNdEx >= 0; iNdEx-- { + if len(m.TriggeredOrdersList) > 0 { + for iNdEx := len(m.TriggeredOrdersList) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.TriggerBookList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.TriggeredOrdersList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -305,8 +305,8 @@ func (m *GenesisState) Size() (n int) { if m.LastEpoch != 0 { n += 1 + sovGenesis(uint64(m.LastEpoch)) } - if len(m.TriggerBookList) > 0 { - for _, e := range m.TriggerBookList { + if len(m.TriggeredOrdersList) > 0 { + for _, e := range m.TriggeredOrdersList { l = e.Size() n += 1 + l + sovGenesis(uint64(l)) } @@ -539,7 +539,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { } case 7: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field TriggerBookList", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field TriggeredOrdersList", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -566,8 +566,8 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.TriggerBookList = append(m.TriggerBookList, TriggerBook{}) - if err := m.TriggerBookList[len(m.TriggerBookList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.TriggeredOrdersList = append(m.TriggeredOrdersList, Order{}) + if err := m.TriggeredOrdersList[len(m.TriggeredOrdersList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/x/dex/types/trigger_book.pb.go b/x/dex/types/trigger_book.pb.go deleted file mode 100644 index cc5504d90f..0000000000 --- a/x/dex/types/trigger_book.pb.go +++ /dev/null @@ -1,434 +0,0 @@ -// Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: dex/trigger_book.proto - -package types - -import ( - fmt "fmt" - _ "github.com/gogo/protobuf/gogoproto" - proto "github.com/gogo/protobuf/proto" - io "io" - math "math" - math_bits "math/bits" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package - -type TriggerBook struct { - Order []*Order `protobuf:"bytes,1,rep,name=order,proto3" json:"order"` - PriceDenom string `protobuf:"bytes,2,opt,name=priceDenom,proto3" json:"price_denom"` - AssetDenom string `protobuf:"bytes,3,opt,name=assetDenom,proto3" json:"asset_denom"` -} - -func (m *TriggerBook) Reset() { *m = TriggerBook{} } -func (m *TriggerBook) String() string { return proto.CompactTextString(m) } -func (*TriggerBook) ProtoMessage() {} -func (*TriggerBook) Descriptor() ([]byte, []int) { - return fileDescriptor_c1b5381dd75ec750, []int{0} -} -func (m *TriggerBook) XXX_Unmarshal(b []byte) error { - return m.Unmarshal(b) -} -func (m *TriggerBook) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - if deterministic { - return xxx_messageInfo_TriggerBook.Marshal(b, m, deterministic) - } else { - b = b[:cap(b)] - n, err := m.MarshalToSizedBuffer(b) - if err != nil { - return nil, err - } - return b[:n], nil - } -} -func (m *TriggerBook) XXX_Merge(src proto.Message) { - xxx_messageInfo_TriggerBook.Merge(m, src) -} -func (m *TriggerBook) XXX_Size() int { - return m.Size() -} -func (m *TriggerBook) XXX_DiscardUnknown() { - xxx_messageInfo_TriggerBook.DiscardUnknown(m) -} - -var xxx_messageInfo_TriggerBook proto.InternalMessageInfo - -func (m *TriggerBook) GetOrder() []*Order { - if m != nil { - return m.Order - } - return nil -} - -func (m *TriggerBook) GetPriceDenom() string { - if m != nil { - return m.PriceDenom - } - return "" -} - -func (m *TriggerBook) GetAssetDenom() string { - if m != nil { - return m.AssetDenom - } - return "" -} - -func init() { - proto.RegisterType((*TriggerBook)(nil), "seiprotocol.seichain.dex.TriggerBook") -} - -func init() { proto.RegisterFile("dex/trigger_book.proto", fileDescriptor_c1b5381dd75ec750) } - -var fileDescriptor_c1b5381dd75ec750 = []byte{ - // 256 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4b, 0x49, 0xad, 0xd0, - 0x2f, 0x29, 0xca, 0x4c, 0x4f, 0x4f, 0x2d, 0x8a, 0x4f, 0xca, 0xcf, 0xcf, 0xd6, 0x2b, 0x28, 0xca, - 0x2f, 0xc9, 0x17, 0x92, 0x28, 0x4e, 0xcd, 0x04, 0xb3, 0x92, 0xf3, 0x73, 0xf4, 0x8a, 0x53, 0x33, - 0x93, 0x33, 0x12, 0x33, 0xf3, 0xf4, 0x52, 0x52, 0x2b, 0xa4, 0xf8, 0x41, 0x3a, 0xf2, 0x8b, 0x52, - 0x52, 0x8b, 0x20, 0x4a, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x4c, 0x7d, 0x10, 0x0b, 0x22, - 0xaa, 0xb4, 0x91, 0x91, 0x8b, 0x3b, 0x04, 0x62, 0xae, 0x53, 0x7e, 0x7e, 0xb6, 0x90, 0x03, 0x17, - 0x2b, 0x58, 0x93, 0x04, 0xa3, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0xbc, 0x1e, 0x2e, 0x0b, 0xf4, 0xfc, - 0x41, 0xca, 0x9c, 0x38, 0x5f, 0xdd, 0x93, 0x87, 0xe8, 0x08, 0x82, 0x50, 0x42, 0xfa, 0x5c, 0x5c, - 0x05, 0x45, 0x99, 0xc9, 0xa9, 0x2e, 0xa9, 0x79, 0xf9, 0xb9, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x9c, - 0x4e, 0xfc, 0xaf, 0xee, 0xc9, 0x73, 0x83, 0x45, 0xe3, 0x53, 0x40, 0xc2, 0x41, 0x48, 0x4a, 0x40, - 0x1a, 0x12, 0x8b, 0x8b, 0x53, 0x4b, 0x20, 0x1a, 0x98, 0x11, 0x1a, 0xc0, 0xa2, 0x30, 0x0d, 0x08, - 0x25, 0x4e, 0xee, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, - 0x84, 0xc7, 0x72, 0x0c, 0x17, 0x1e, 0xcb, 0x31, 0xdc, 0x78, 0x2c, 0xc7, 0x10, 0xa5, 0x9b, 0x9e, - 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x5f, 0x9c, 0x9a, 0xa9, 0x0b, 0x73, 0x39, - 0x98, 0x03, 0x76, 0xba, 0x7e, 0x85, 0x3e, 0x38, 0x28, 0x2b, 0x0b, 0x52, 0x8b, 0x93, 0xd8, 0xc0, - 0xf2, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xce, 0xaf, 0x93, 0xf4, 0x5e, 0x01, 0x00, 0x00, -} - -func (m *TriggerBook) Marshal() (dAtA []byte, err error) { - size := m.Size() - dAtA = make([]byte, size) - n, err := m.MarshalToSizedBuffer(dAtA[:size]) - if err != nil { - return nil, err - } - return dAtA[:n], nil -} - -func (m *TriggerBook) MarshalTo(dAtA []byte) (int, error) { - size := m.Size() - return m.MarshalToSizedBuffer(dAtA[:size]) -} - -func (m *TriggerBook) MarshalToSizedBuffer(dAtA []byte) (int, error) { - i := len(dAtA) - _ = i - var l int - _ = l - if len(m.AssetDenom) > 0 { - i -= len(m.AssetDenom) - copy(dAtA[i:], m.AssetDenom) - i = encodeVarintTriggerBook(dAtA, i, uint64(len(m.AssetDenom))) - i-- - dAtA[i] = 0x1a - } - if len(m.PriceDenom) > 0 { - i -= len(m.PriceDenom) - copy(dAtA[i:], m.PriceDenom) - i = encodeVarintTriggerBook(dAtA, i, uint64(len(m.PriceDenom))) - i-- - dAtA[i] = 0x12 - } - if len(m.Order) > 0 { - for iNdEx := len(m.Order) - 1; iNdEx >= 0; iNdEx-- { - { - size, err := m.Order[iNdEx].MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintTriggerBook(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0xa - } - } - return len(dAtA) - i, nil -} - -func encodeVarintTriggerBook(dAtA []byte, offset int, v uint64) int { - offset -= sovTriggerBook(v) - base := offset - for v >= 1<<7 { - dAtA[offset] = uint8(v&0x7f | 0x80) - v >>= 7 - offset++ - } - dAtA[offset] = uint8(v) - return base -} -func (m *TriggerBook) Size() (n int) { - if m == nil { - return 0 - } - var l int - _ = l - if len(m.Order) > 0 { - for _, e := range m.Order { - l = e.Size() - n += 1 + l + sovTriggerBook(uint64(l)) - } - } - l = len(m.PriceDenom) - if l > 0 { - n += 1 + l + sovTriggerBook(uint64(l)) - } - l = len(m.AssetDenom) - if l > 0 { - n += 1 + l + sovTriggerBook(uint64(l)) - } - return n -} - -func sovTriggerBook(x uint64) (n int) { - return (math_bits.Len64(x|1) + 6) / 7 -} -func sozTriggerBook(x uint64) (n int) { - return sovTriggerBook(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} -func (m *TriggerBook) Unmarshal(dAtA []byte) error { - l := len(dAtA) - iNdEx := 0 - for iNdEx < l { - preIndex := iNdEx - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTriggerBook - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - fieldNum := int32(wire >> 3) - wireType := int(wire & 0x7) - if wireType == 4 { - return fmt.Errorf("proto: TriggerBook: wiretype end group for non-group") - } - if fieldNum <= 0 { - return fmt.Errorf("proto: TriggerBook: illegal tag %d (wire type %d)", fieldNum, wire) - } - switch fieldNum { - case 1: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Order", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTriggerBook - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return ErrInvalidLengthTriggerBook - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return ErrInvalidLengthTriggerBook - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.Order = append(m.Order, &Order{}) - if err := m.Order[len(m.Order)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } - iNdEx = postIndex - case 2: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field PriceDenom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTriggerBook - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTriggerBook - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTriggerBook - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.PriceDenom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - case 3: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AssetDenom", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return ErrIntOverflowTriggerBook - } - if iNdEx >= l { - return io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthTriggerBook - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthTriggerBook - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.AssetDenom = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipTriggerBook(dAtA[iNdEx:]) - if err != nil { - return err - } - if (skippy < 0) || (iNdEx+skippy) < 0 { - return ErrInvalidLengthTriggerBook - } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF - } - iNdEx += skippy - } - } - - if iNdEx > l { - return io.ErrUnexpectedEOF - } - return nil -} -func skipTriggerBook(dAtA []byte) (n int, err error) { - l := len(dAtA) - iNdEx := 0 - depth := 0 - for iNdEx < l { - var wire uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTriggerBook - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - wire |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - wireType := int(wire & 0x7) - switch wireType { - case 0: - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTriggerBook - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - iNdEx++ - if dAtA[iNdEx-1] < 0x80 { - break - } - } - case 1: - iNdEx += 8 - case 2: - var length int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return 0, ErrIntOverflowTriggerBook - } - if iNdEx >= l { - return 0, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - length |= (int(b) & 0x7F) << shift - if b < 0x80 { - break - } - } - if length < 0 { - return 0, ErrInvalidLengthTriggerBook - } - iNdEx += length - case 3: - depth++ - case 4: - if depth == 0 { - return 0, ErrUnexpectedEndOfGroupTriggerBook - } - depth-- - case 5: - iNdEx += 4 - default: - return 0, fmt.Errorf("proto: illegal wireType %d", wireType) - } - if iNdEx < 0 { - return 0, ErrInvalidLengthTriggerBook - } - if depth == 0 { - return iNdEx, nil - } - } - return 0, io.ErrUnexpectedEOF -} - -var ( - ErrInvalidLengthTriggerBook = fmt.Errorf("proto: negative length found during unmarshaling") - ErrIntOverflowTriggerBook = fmt.Errorf("proto: integer overflow") - ErrUnexpectedEndOfGroupTriggerBook = fmt.Errorf("proto: unexpected end of group") -) From 331e2abaa82082027e75ad7f76351265777647bd Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Wed, 12 Oct 2022 12:43:37 -0400 Subject: [PATCH 06/12] clean up triggerbook keeper module --- x/dex/keeper/trigger_book.go | 9 -- x/dex/keeper/trigger_book_test.go | 131 ++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 9 deletions(-) diff --git a/x/dex/keeper/trigger_book.go b/x/dex/keeper/trigger_book.go index a840bc849a..43f8d52104 100644 --- a/x/dex/keeper/trigger_book.go +++ b/x/dex/keeper/trigger_book.go @@ -8,11 +8,6 @@ import ( "github.com/sei-protocol/sei-chain/x/dex/types" ) -// I don't think this is proper lmao -// func (k Keeper) SetTriggerBook(ctx sdk.Context, contractAddr string, triggerBook types.TriggerBook) { -// prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, triggerBook.PriceDenom, triggerBook.AssetDenom)) -// } - func (k Keeper) SetTriggeredOrder(ctx sdk.Context, contractAddr string, order types.Order, priceDenom string, assetDenom string) { store := prefix.NewStore(ctx.KVStore(k.storeKey), types.TriggerOrderBookPrefix(contractAddr, priceDenom, assetDenom)) @@ -50,10 +45,6 @@ func (k Keeper) GetAllTriggeredOrdersForPair(ctx sdk.Context, contractAddr strin return } -// func GetKeyForTriggerBook(triggerBook types.TriggerBook) []byte { -// return GetKeyForPrice(shortBook.Entry.Price) -// } - func GetKeyForOrderID(orderID uint64) []byte { key := make([]byte, 8) binary.LittleEndian.PutUint64(key, orderID) diff --git a/x/dex/keeper/trigger_book_test.go b/x/dex/keeper/trigger_book_test.go index 9429264902..438c6eba02 100644 --- a/x/dex/keeper/trigger_book_test.go +++ b/x/dex/keeper/trigger_book_test.go @@ -1 +1,132 @@ package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/testutil/nullify" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestTriggeredOrderGetByID(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + order := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, order, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + + got, found := keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, nullify.Fill(&order), nullify.Fill(&got)) + + got, found = keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 2, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, !found) + require.Equal(t, types.Order{}, got) +} + +func TestTriggeredOrderGetAll(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + o1 := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + o2 := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + o3 := types.Order{ + Id: 3, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o2, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o3, "FOO", "BAR") + + orders := keeper.GetAllTriggeredOrdersForPair(ctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.Equal(t, len(orders), 2) + orders = keeper.GetAllTriggeredOrdersForPair(ctx, keepertest.TestContract, "FOO", "BAR") + require.Equal(t, len(orders), 1) +} + +func TestTriggeredOrderSetOverwrite(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + order := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + overwriteOrder := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLIMIT, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, order, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + got, found := keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, nullify.Fill(&order), nullify.Fill(&got)) + + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, overwriteOrder, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + got, found = keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, nullify.Fill(&overwriteOrder), nullify.Fill(&got)) +} + +func TestTriggeredOrderRemove(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + order := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, order, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + got, found := keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, nullify.Fill(&order), nullify.Fill(&got)) + + keeper.RemoveTriggeredOrder(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + + got, found = keeper.GetTriggeredOrderByID(ctx, keepertest.TestContract, 1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, !found) + require.Equal(t, types.Order{}, got) +} From 23ff5f9618f2449c5d3dcb6daa2971c7f6891968 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Wed, 12 Oct 2022 14:20:39 -0400 Subject: [PATCH 07/12] add querying methods --- x/dex/keeper/query/grpc_query_order.go | 14 +++++ x/dex/keeper/query/grpc_query_order_test.go | 60 ++++++++++++++++++++- x/dex/keeper/trigger_book.go | 15 ++++++ x/dex/keeper/trigger_book_test.go | 40 +++++++++++++- 4 files changed, 127 insertions(+), 2 deletions(-) diff --git a/x/dex/keeper/query/grpc_query_order.go b/x/dex/keeper/query/grpc_query_order.go index 6c1904857b..9a4331e5fc 100644 --- a/x/dex/keeper/query/grpc_query_order.go +++ b/x/dex/keeper/query/grpc_query_order.go @@ -52,6 +52,16 @@ func (k KeeperWrapper) GetOrder(c context.Context, req *types.QueryGetOrderByIDR } } } + + triggeredOrders := k.GetAllTriggeredOrders(ctx, req.ContractAddr) + for _, order := range triggeredOrders { + if order.Id == req.Id { + return &types.QueryGetOrderByIDResponse{ + Order: &order, + }, nil + } + } + return &types.QueryGetOrderByIDResponse{}, types.ErrInvalidOrderID } @@ -97,6 +107,10 @@ func (k KeeperWrapper) GetOrders(c context.Context, req *types.QueryGetOrdersReq } } } + triggeredOrders := k.GetAllTriggeredOrders(ctx, req.ContractAddr) + for _, order := range triggeredOrders { + orders = append(orders, &order) + } return &types.QueryGetOrdersResponse{Orders: orders}, nil } diff --git a/x/dex/keeper/query/grpc_query_order_test.go b/x/dex/keeper/query/grpc_query_order_test.go index f807a7e35f..9bce6cf984 100644 --- a/x/dex/keeper/query/grpc_query_order_test.go +++ b/x/dex/keeper/query/grpc_query_order_test.go @@ -64,11 +64,69 @@ func TestGetOrders(t *testing.T) { }, }, }) + + triggeredOrder := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, triggeredOrder, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + query := types.QueryGetOrdersRequest{ ContractAddr: keepertest.TestContract, Account: keepertest.TestAccount, } resp, err := wrapper.GetOrders(wctx, &query) require.Nil(t, err) - require.Equal(t, 1, len(resp.Orders)) + require.Equal(t, 2, len(resp.Orders)) +} + +func TestGetOrderByIdTriggeredOrder(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := query.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + // active order + keeper.SetLongBook(ctx, keepertest.TestContract, types.LongBook{ + Price: sdk.OneDec(), + Entry: &types.OrderEntry{ + Price: sdk.OneDec(), + Quantity: sdk.MustNewDecFromStr("2"), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Allocations: []*types.Allocation{ + { + Account: keepertest.TestAccount, + OrderId: 1, + Quantity: sdk.MustNewDecFromStr("2"), + }, + }, + }, + }) + + triggeredOrder := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, triggeredOrder, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + + query := types.QueryGetOrderByIDRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Id: 2, + } + resp, err := wrapper.GetOrder(wctx, &query) + require.Nil(t, err) + require.Equal(t, uint64(2), resp.Order.Id) + require.Equal(t, types.OrderStatus_PLACED, resp.Order.Status) + require.Equal(t, types.OrderType_STOPLOSS, resp.Order.OrderType) } diff --git a/x/dex/keeper/trigger_book.go b/x/dex/keeper/trigger_book.go index 43f8d52104..f54b81adfc 100644 --- a/x/dex/keeper/trigger_book.go +++ b/x/dex/keeper/trigger_book.go @@ -45,6 +45,21 @@ func (k Keeper) GetAllTriggeredOrdersForPair(ctx sdk.Context, contractAddr strin return } +func (k Keeper) GetAllTriggeredOrders(ctx sdk.Context, contractAddr string) (list []types.Order) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ContractKeyPrefix(types.TriggerBookKey, contractAddr)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Order + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return +} + func GetKeyForOrderID(orderID uint64) []byte { key := make([]byte, 8) binary.LittleEndian.PutUint64(key, orderID) diff --git a/x/dex/keeper/trigger_book_test.go b/x/dex/keeper/trigger_book_test.go index 438c6eba02..0e360ce50c 100644 --- a/x/dex/keeper/trigger_book_test.go +++ b/x/dex/keeper/trigger_book_test.go @@ -33,7 +33,7 @@ func TestTriggeredOrderGetByID(t *testing.T) { require.Equal(t, types.Order{}, got) } -func TestTriggeredOrderGetAll(t *testing.T) { +func TestTriggeredOrderGetAllPair(t *testing.T) { keeper, ctx := keepertest.DexKeeper(t) o1 := types.Order{ @@ -73,6 +73,44 @@ func TestTriggeredOrderGetAll(t *testing.T) { require.Equal(t, len(orders), 1) } +func TestTriggeredOrderGetAll(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + o1 := types.Order{ + Id: 1, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + o2 := types.Order{ + Id: 2, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + o3 := types.Order{ + Id: 3, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + Nominal: sdk.MustNewDecFromStr("1"), + OrderType: types.OrderType_STOPLOSS, + TriggerPrice: sdk.MustNewDecFromStr("4"), + TriggerStatus: false, + } + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o1, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o2, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + keeper.SetTriggeredOrder(ctx, keepertest.TestContract, o3, "FOO", "BAR") + + orders := keeper.GetAllTriggeredOrders(ctx, keepertest.TestContract) + require.Equal(t, len(orders), 3) +} + func TestTriggeredOrderSetOverwrite(t *testing.T) { keeper, ctx := keepertest.DexKeeper(t) From ae80e9d8b9497aeedf064af444c0386db365f08d Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Wed, 12 Oct 2022 14:37:00 -0400 Subject: [PATCH 08/12] remove un-necessary change --- x/oracle/simulation/operations.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/oracle/simulation/operations.go b/x/oracle/simulation/operations.go index a64072548d..2028e73625 100644 --- a/x/oracle/simulation/operations.go +++ b/x/oracle/simulation/operations.go @@ -65,6 +65,7 @@ func WeightedOperations( } // SimulateMsgAggregateExchangeRateVote generates a MsgAggregateExchangeRateVote with random values. +// nolint: funlen func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -121,6 +122,7 @@ func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankK } // SimulateMsgDelegateFeedConsent generates a MsgDelegateFeedConsent with random values. +// nolint: funlen func SimulateMsgDelegateFeedConsent(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, From 5396fdcd332fd942fd36200e01e480de8fa44532 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Wed, 12 Oct 2022 14:40:11 -0400 Subject: [PATCH 09/12] fix lint --- x/dex/keeper/query/grpc_query_order.go | 8 ++++---- x/oracle/simulation/operations.go | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/x/dex/keeper/query/grpc_query_order.go b/x/dex/keeper/query/grpc_query_order.go index 9a4331e5fc..8b2fcb1b03 100644 --- a/x/dex/keeper/query/grpc_query_order.go +++ b/x/dex/keeper/query/grpc_query_order.go @@ -54,10 +54,10 @@ func (k KeeperWrapper) GetOrder(c context.Context, req *types.QueryGetOrderByIDR } triggeredOrders := k.GetAllTriggeredOrders(ctx, req.ContractAddr) - for _, order := range triggeredOrders { + for i, order := range triggeredOrders { if order.Id == req.Id { return &types.QueryGetOrderByIDResponse{ - Order: &order, + Order: &triggeredOrders[i], }, nil } } @@ -108,8 +108,8 @@ func (k KeeperWrapper) GetOrders(c context.Context, req *types.QueryGetOrdersReq } } triggeredOrders := k.GetAllTriggeredOrders(ctx, req.ContractAddr) - for _, order := range triggeredOrders { - orders = append(orders, &order) + for i := range triggeredOrders { + orders = append(orders, &triggeredOrders[i]) } return &types.QueryGetOrdersResponse{Orders: orders}, nil diff --git a/x/oracle/simulation/operations.go b/x/oracle/simulation/operations.go index 2028e73625..3988c4b164 100644 --- a/x/oracle/simulation/operations.go +++ b/x/oracle/simulation/operations.go @@ -65,7 +65,7 @@ func WeightedOperations( } // SimulateMsgAggregateExchangeRateVote generates a MsgAggregateExchangeRateVote with random values. -// nolint: funlen +//nolint: funlen func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -122,7 +122,7 @@ func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankK } // SimulateMsgDelegateFeedConsent generates a MsgDelegateFeedConsent with random values. -// nolint: funlen +//nolint: funlen func SimulateMsgDelegateFeedConsent(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, From 9683364f761b4f0c8d823ecab253d0b0ee615af2 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Thu, 13 Oct 2022 12:26:03 -0400 Subject: [PATCH 10/12] fix lint --- x/dex/contract/execution.go | 2 -- x/oracle/simulation/operations.go | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/x/dex/contract/execution.go b/x/dex/contract/execution.go index ad1825d716..5734a3e0ae 100644 --- a/x/dex/contract/execution.go +++ b/x/dex/contract/execution.go @@ -111,8 +111,6 @@ func matchMarketOrderForPair( ) return marketBuyOutcome.Merge(&marketSellOutcome) } - - func MoveTriggeredOrderForPair( ctx sdk.Context, typedContractAddr dextypesutils.ContractAddress, diff --git a/x/oracle/simulation/operations.go b/x/oracle/simulation/operations.go index 3988c4b164..2028e73625 100644 --- a/x/oracle/simulation/operations.go +++ b/x/oracle/simulation/operations.go @@ -65,7 +65,7 @@ func WeightedOperations( } // SimulateMsgAggregateExchangeRateVote generates a MsgAggregateExchangeRateVote with random values. -//nolint: funlen +// nolint: funlen func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -122,7 +122,7 @@ func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankK } // SimulateMsgDelegateFeedConsent generates a MsgDelegateFeedConsent with random values. -//nolint: funlen +// nolint: funlen func SimulateMsgDelegateFeedConsent(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, From a347c993fdb36c96af16f70bc26fef8c1698f4f9 Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Thu, 13 Oct 2022 13:34:15 -0400 Subject: [PATCH 11/12] fix lint --- x/dex/contract/execution.go | 1 + x/oracle/simulation/operations.go | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x/dex/contract/execution.go b/x/dex/contract/execution.go index 5734a3e0ae..03d4858c22 100644 --- a/x/dex/contract/execution.go +++ b/x/dex/contract/execution.go @@ -111,6 +111,7 @@ func matchMarketOrderForPair( ) return marketBuyOutcome.Merge(&marketSellOutcome) } + func MoveTriggeredOrderForPair( ctx sdk.Context, typedContractAddr dextypesutils.ContractAddress, diff --git a/x/oracle/simulation/operations.go b/x/oracle/simulation/operations.go index 2028e73625..3988c4b164 100644 --- a/x/oracle/simulation/operations.go +++ b/x/oracle/simulation/operations.go @@ -65,7 +65,7 @@ func WeightedOperations( } // SimulateMsgAggregateExchangeRateVote generates a MsgAggregateExchangeRateVote with random values. -// nolint: funlen +//nolint: funlen func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, @@ -122,7 +122,7 @@ func SimulateMsgAggregateExchangeRateVote(ak types.AccountKeeper, bk types.BankK } // SimulateMsgDelegateFeedConsent generates a MsgDelegateFeedConsent with random values. -// nolint: funlen +//nolint: funlen func SimulateMsgDelegateFeedConsent(ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper) simtypes.Operation { return func( r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string, From 50cf51b81ca454a0b7b94adba3c8d209e14c23bd Mon Sep 17 00:00:00 2001 From: Eric Zhu Date: Fri, 14 Oct 2022 02:16:15 -0400 Subject: [PATCH 12/12] add testing based on PR comments --- x/dex/exchange/limit_order_test.go | 4 ++++ x/dex/exchange/market_order_test.go | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/x/dex/exchange/limit_order_test.go b/x/dex/exchange/limit_order_test.go index 91b0c3338b..6e5265f434 100644 --- a/x/dex/exchange/limit_order_test.go +++ b/x/dex/exchange/limit_order_test.go @@ -1179,8 +1179,12 @@ func TestMatchMultipleOrderFromMultipleLongBook(t *testing.T) { totalPrice := outcome.TotalNotional totalExecuted := outcome.TotalQuantity settlements := outcome.Settlements + minPrice := outcome.MinPrice + maxPrice := outcome.MaxPrice assert.Equal(t, totalPrice, sdk.NewDec(1216)) assert.Equal(t, totalExecuted, sdk.NewDec(12)) + assert.Equal(t, minPrice, sdk.NewDec(100)) + assert.Equal(t, maxPrice, sdk.NewDec(110)) assert.Equal(t, orderbook.Longs.DirtyEntries.Len(), 2) assert.Equal(t, orderbook.Shorts.DirtyEntries.Len(), 3) _, ok := orderbook.Longs.DirtyEntries.Load(sdk.MustNewDecFromStr("100").String()) diff --git a/x/dex/exchange/market_order_test.go b/x/dex/exchange/market_order_test.go index 9ee3659c06..36aa5cc780 100644 --- a/x/dex/exchange/market_order_test.go +++ b/x/dex/exchange/market_order_test.go @@ -1021,8 +1021,12 @@ func TestMatchMultipleMarketOrderFromMultipleLongBook(t *testing.T) { totalPrice := outcome.TotalNotional totalExecuted := outcome.TotalQuantity settlements := outcome.Settlements + minPrice := outcome.MinPrice + maxPrice := outcome.MaxPrice assert.Equal(t, totalPrice, sdk.NewDec(620)) assert.Equal(t, totalExecuted, sdk.NewDec(6)) + assert.Equal(t, minPrice, sdk.MustNewDecFromStr("103.333333333333333333")) + assert.Equal(t, maxPrice, sdk.MustNewDecFromStr("103.333333333333333333")) assert.Equal(t, entries.DirtyEntries.Len(), 2) _, ok := entries.DirtyEntries.Load(sdk.MustNewDecFromStr("100").String()) assert.True(t, ok)