diff --git a/.github/workflows/forge-test.yml b/.github/workflows/forge-test.yml index f104ac3b5..d3ee84877 100644 --- a/.github/workflows/forge-test.yml +++ b/.github/workflows/forge-test.yml @@ -31,10 +31,10 @@ jobs: - name: Run Forge build run: | forge --version - forge build --sizes + forge build --sizes --evm-version=cancun id: build - name: Run Forge tests run: | - forge test -vvv + forge test -vvv --evm-version=cancun id: test diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml new file mode 100644 index 000000000..01f3ef71a --- /dev/null +++ b/.github/workflows/fuzz.yml @@ -0,0 +1,40 @@ +name: Fuzzing + + +on: + push: + branches: + - main + pull_request: + branches: + - main + +defaults: + run: + shell: bash + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.21 + + - name: Fuzz Place Order Msg + run: go test github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver -fuzz FuzzPlaceOrders -fuzztime 30s + + - name: Fuzz Limit Order Matching + run: go test github.com/sei-protocol/sei-chain/x/dex/exchange -fuzz FuzzMatchLimitOrders -fuzztime 30s + + - name: Fuzz Market Order Matching + run: go test github.com/sei-protocol/sei-chain/x/dex/exchange -fuzz FuzzMatchMarketOrders -fuzztime 30s + + - name: Fuzz Limit Order Settlement + run: go test github.com/sei-protocol/sei-chain/x/dex/exchange -fuzz FuzzSettleLimitOrder -fuzztime 30s + + - name: Fuzz Market Order Settlement + run: go test github.com/sei-protocol/sei-chain/x/dex/exchange -fuzz FuzzSettleMarketOrder -fuzztime 30s diff --git a/CHANGELOG.md b/CHANGELOG.md index 81cff3fe9..578d175c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,19 @@ Ref: https://keepachangelog.com/en/1.0.0/ --> # Changelog +## v5.7.1 & v5.7.2 +sei-chain +* [#1779](https://github.com/sei-protocol/sei-chain/pull/1779) Fix subscribe logs empty params crash +* [#1783](https://github.com/sei-protocol/sei-chain/pull/1783) Add meaningful message for eth_call balance override overflow +* [#1783](https://github.com/sei-protocol/sei-chain/pull/1784) Fix log index on synthetic receipt +* [#1775](https://github.com/sei-protocol/sei-chain/pull/1775) Disallow sending to direct cast addr after association + +sei-wasmd +* [60](https://github.com/sei-protocol/sei-wasmd/pull/60) Query penalty fixes + +sei-tendermint +* [#237](https://github.com/sei-protocol/sei-tendermint/pull/237) Add metrics for total txs bytes in mempool + ## v5.7.0 sei-chain * [#1731](https://github.com/sei-protocol/sei-chain/pull/1731) Remove 1-hop limit diff --git a/aclmapping/bank/mappings.go b/aclmapping/bank/mappings.go index 140e9d463..047c9092a 100644 --- a/aclmapping/bank/mappings.go +++ b/aclmapping/bank/mappings.go @@ -18,6 +18,7 @@ var ErrorInvalidMsgType = fmt.Errorf("invalid message received for bank module") func GetBankDepedencyGenerator() aclkeeper.DependencyGeneratorMap { dependencyGeneratorMap := make(aclkeeper.DependencyGeneratorMap) + // dex place orders placeOrdersKey := acltypes.GenerateMessageKey(&banktypes.MsgSend{}) dependencyGeneratorMap[placeOrdersKey] = MsgSendDependencyGenerator diff --git a/aclmapping/dependency_generator.go b/aclmapping/dependency_generator.go index 2e83c1ca7..8a8cabe81 100644 --- a/aclmapping/dependency_generator.go +++ b/aclmapping/dependency_generator.go @@ -3,6 +3,7 @@ package aclmapping import ( aclkeeper "github.com/cosmos/cosmos-sdk/x/accesscontrol/keeper" aclbankmapping "github.com/sei-protocol/sei-chain/aclmapping/bank" + acldexmapping "github.com/sei-protocol/sei-chain/aclmapping/dex" aclevmmapping "github.com/sei-protocol/sei-chain/aclmapping/evm" acloraclemapping "github.com/sei-protocol/sei-chain/aclmapping/oracle" acltokenfactorymapping "github.com/sei-protocol/sei-chain/aclmapping/tokenfactory" @@ -20,6 +21,7 @@ func (customDepGen CustomDependencyGenerator) GetCustomDependencyGenerators(evmK dependencyGeneratorMap := make(aclkeeper.DependencyGeneratorMap) wasmDependencyGenerators := aclwasmmapping.NewWasmDependencyGenerator() + dependencyGeneratorMap = dependencyGeneratorMap.Merge(acldexmapping.GetDexDependencyGenerators()) dependencyGeneratorMap = dependencyGeneratorMap.Merge(aclbankmapping.GetBankDepedencyGenerator()) dependencyGeneratorMap = dependencyGeneratorMap.Merge(acltokenfactorymapping.GetTokenFactoryDependencyGenerators()) dependencyGeneratorMap = dependencyGeneratorMap.Merge(wasmDependencyGenerators.GetWasmDependencyGenerators()) diff --git a/aclmapping/dex/mappings.go b/aclmapping/dex/mappings.go new file mode 100644 index 000000000..df5350c12 --- /dev/null +++ b/aclmapping/dex/mappings.go @@ -0,0 +1,229 @@ +package acldexmapping + +import ( + "encoding/hex" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" + aclkeeper "github.com/cosmos/cosmos-sdk/x/accesscontrol/keeper" + acltypes "github.com/cosmos/cosmos-sdk/x/accesscontrol/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + dexkeeper "github.com/sei-protocol/sei-chain/x/dex/keeper" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" +) + +var ErrPlaceOrdersGenerator = fmt.Errorf("invalid message received for dex module") + +func GetDexDependencyGenerators() aclkeeper.DependencyGeneratorMap { + dependencyGeneratorMap := make(aclkeeper.DependencyGeneratorMap) + + // dex place orders + placeOrdersKey := acltypes.GenerateMessageKey(&dextypes.MsgPlaceOrders{}) + cancelOrdersKey := acltypes.GenerateMessageKey(&dextypes.MsgCancelOrders{}) + dependencyGeneratorMap[placeOrdersKey] = DexPlaceOrdersDependencyGenerator + dependencyGeneratorMap[cancelOrdersKey] = DexCancelOrdersDependencyGenerator + + return dependencyGeneratorMap +} + +func GetLongShortOrderBookOps(contractAddr string, priceDenom string, assetDenom string) []sdkacltypes.AccessOperation { + return []sdkacltypes.AccessOperation{ + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_CONTRACT_LONGBOOK, + IdentifierTemplate: hex.EncodeToString(dextypes.OrderBookPrefix(true, contractAddr, priceDenom, assetDenom)), + }, + + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_CONTRACT_SHORTBOOK, + IdentifierTemplate: hex.EncodeToString(dextypes.OrderBookPrefix(false, contractAddr, priceDenom, assetDenom)), + }, + } +} + +func DexPlaceOrdersDependencyGenerator(keeper aclkeeper.Keeper, _ sdk.Context, msg sdk.Msg) ([]sdkacltypes.AccessOperation, error) { + // TODO: read + write downstream, write contracts to process + placeOrdersMsg, ok := msg.(*dextypes.MsgPlaceOrders) + if !ok { + return []sdkacltypes.AccessOperation{}, ErrPlaceOrdersGenerator + } + + moduleAdr := keeper.AccountKeeper.GetModuleAddress(dextypes.ModuleName) + + senderBankAddrIdentifier := hex.EncodeToString(banktypes.CreateAccountBalancesPrefixFromBech32(placeOrdersMsg.Creator)) + contractAddr := placeOrdersMsg.ContractAddr + + aclOps := []sdkacltypes.AccessOperation{ + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_NEXT_ORDER_ID, + IdentifierTemplate: hex.EncodeToString(dextypes.NextOrderIDPrefix(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_DEX_NEXT_ORDER_ID, + IdentifierTemplate: hex.EncodeToString(dextypes.NextOrderIDPrefix(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_REGISTERED_PAIR, + IdentifierTemplate: hex.EncodeToString(dextypes.RegisteredPairPrefix(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_DEPOSIT, + IdentifierTemplate: hex.EncodeToString(append( + dextypes.MemDepositPrefix(contractAddr), + []byte(placeOrdersMsg.Creator)..., + )), + }, + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_DEPOSIT, + IdentifierTemplate: hex.EncodeToString(append( + dextypes.MemDepositPrefix(contractAddr), + []byte(placeOrdersMsg.Creator)..., + )), + }, + + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_ORDER, + IdentifierTemplate: hex.EncodeToString(dextypes.MemOrderPrefix(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_ORDER, + IdentifierTemplate: hex.EncodeToString(dextypes.MemOrderPrefix(contractAddr)), + }, + + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS, + IdentifierTemplate: hex.EncodeToString(dextypes.MemDownstreamContractsKey(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS, + IdentifierTemplate: hex.EncodeToString(dextypes.MemDownstreamContractsKey(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_CONTRACTS_TO_PROCESS, + IdentifierTemplate: hex.EncodeToString(dextypes.MemContractsToProcessKey(contractAddr)), + }, + + // Checks balance of sender + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_BANK_BALANCES, + IdentifierTemplate: senderBankAddrIdentifier, + }, + // Reduce the amount from the sender's balance + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_BANK_BALANCES, + IdentifierTemplate: senderBankAddrIdentifier, + }, + + // update the amounts for dex module balance + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_AUTH_ADDRESS_STORE, + IdentifierTemplate: hex.EncodeToString(authtypes.AddressStoreKey(moduleAdr)), + }, + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_BANK_BALANCES, + IdentifierTemplate: hex.EncodeToString(banktypes.CreateAccountBalancesPrefix(moduleAdr)), + }, + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_BANK_BALANCES, + IdentifierTemplate: hex.EncodeToString(banktypes.CreateAccountBalancesPrefix(moduleAdr)), + }, + + // Gets Account Info for the sender + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_AUTH_ADDRESS_STORE, + IdentifierTemplate: hex.EncodeToString(authtypes.CreateAddressStoreKeyFromBech32(placeOrdersMsg.Creator)), + }, + + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_CONTRACT, + IdentifierTemplate: hex.EncodeToString([]byte(dexkeeper.ContractPrefixKey)), + }, + + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_LONG_ORDER_COUNT, + IdentifierTemplate: hex.EncodeToString([]byte(dextypes.LongOrderCountKey)), + }, + + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_SHORT_ORDER_COUNT, + IdentifierTemplate: hex.EncodeToString([]byte(dextypes.ShortOrderCountKey)), + }, + } + + // Last Operation should always be a commit + aclOps = append(aclOps, *acltypes.CommitAccessOp()) + return aclOps, nil +} + +func DexCancelOrdersDependencyGenerator(_ aclkeeper.Keeper, _ sdk.Context, msg sdk.Msg) ([]sdkacltypes.AccessOperation, error) { + cancelOrdersMsg, ok := msg.(*dextypes.MsgCancelOrders) + if !ok { + return []sdkacltypes.AccessOperation{}, ErrPlaceOrdersGenerator + } + contractAddr := cancelOrdersMsg.ContractAddr + + aclOps := []sdkacltypes.AccessOperation{ + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_CANCEL, + IdentifierTemplate: hex.EncodeToString(dextypes.MemCancelPrefix(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_CANCEL, + IdentifierTemplate: hex.EncodeToString(dextypes.MemCancelPrefix(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_CONTRACT, + IdentifierTemplate: hex.EncodeToString([]byte(dexkeeper.ContractPrefixKey)), + }, + { + AccessType: sdkacltypes.AccessType_READ, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS, + IdentifierTemplate: hex.EncodeToString(dextypes.MemDownstreamContractsKey(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS, + IdentifierTemplate: hex.EncodeToString(dextypes.MemDownstreamContractsKey(contractAddr)), + }, + { + AccessType: sdkacltypes.AccessType_WRITE, + ResourceType: sdkacltypes.ResourceType_KV_DEX_MEM_CONTRACTS_TO_PROCESS, + IdentifierTemplate: hex.EncodeToString(dextypes.MemContractsToProcessKey(contractAddr)), + }, + } + + for _, order := range cancelOrdersMsg.GetCancellations() { + priceDenom := order.GetPriceDenom() + assetDenom := order.GetAssetDenom() + aclOps = append(aclOps, GetLongShortOrderBookOps(contractAddr, priceDenom, assetDenom)...) + } + + // Last Operation should always be a commit + aclOps = append(aclOps, *acltypes.CommitAccessOp()) + return aclOps, nil +} diff --git a/aclmapping/dex/mappings_test.go b/aclmapping/dex/mappings_test.go new file mode 100644 index 000000000..5e189ac8d --- /dev/null +++ b/aclmapping/dex/mappings_test.go @@ -0,0 +1,292 @@ +package acldexmapping_test + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + acltypes "github.com/cosmos/cosmos-sdk/x/accesscontrol/types" + "github.com/k0kubun/pp/v3" + dexacl "github.com/sei-protocol/sei-chain/aclmapping/dex" + aclutils "github.com/sei-protocol/sei-chain/aclmapping/utils" + "github.com/sei-protocol/sei-chain/app" + "github.com/sei-protocol/sei-chain/app/apptesting" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + dexmsgserver "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + oracletypes "github.com/sei-protocol/sei-chain/x/oracle/types" + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" +) + +type KeeperTestSuite struct { + apptesting.KeeperTestHelper + + queryClient dextypes.QueryClient + msgServer dextypes.MsgServer + defaultDenom string + defaultExchangeRate string + initialBalance sdk.Coins + creator string + contract string + + msgPlaceOrders *dextypes.MsgPlaceOrders + msgCancelOrders *dextypes.MsgCancelOrders +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +// Runs before each test case +func (suite *KeeperTestSuite) SetupTest() { + suite.Setup() +} + +// Explicitly only run once during setup +func (suite *KeeperTestSuite) PrepareTest() { + suite.defaultDenom = "usei" + suite.defaultExchangeRate = fmt.Sprintf("%dusei", sdk.NewDec(1700)) + + suite.initialBalance = sdk.Coins{sdk.NewInt64Coin(suite.defaultDenom, 100000000000)} + suite.initialBalance = sdk.Coins{sdk.NewInt64Coin("usei", 100000000000)} + suite.FundAcc(suite.TestAccs[0], suite.initialBalance) + + suite.queryClient = dextypes.NewQueryClient(suite.QueryHelper) + suite.msgServer = dexmsgserver.NewMsgServerImpl(suite.App.DexKeeper) + + msgValidator := sdkacltypes.NewMsgValidator(aclutils.StoreKeyToResourceTypePrefixMap) + suite.Ctx = suite.Ctx.WithMsgValidator(msgValidator) + + suite.Ctx = suite.Ctx.WithBlockHeight(10) + suite.Ctx = suite.Ctx.WithBlockTime(time.Unix(333, 0)) + + suite.creator = suite.TestAccs[0].String() + suite.contract = "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m" + + suite.App.DexKeeper.AddRegisteredPair(suite.Ctx, suite.contract, keepertest.TestPair) + suite.App.DexKeeper.SetPriceTickSizeForPair(suite.Ctx, suite.contract, keepertest.TestPair, *keepertest.TestPair.PriceTicksize) + suite.App.DexKeeper.SetQuantityTickSizeForPair(suite.Ctx, suite.contract, keepertest.TestPair, *keepertest.TestPair.PriceTicksize) + + suite.msgPlaceOrders = &types.MsgPlaceOrders{ + Creator: suite.creator, + ContractAddr: suite.contract, + Orders: []*types.Order{ + { + Price: sdk.MustNewDecFromStr("10"), + Quantity: sdk.MustNewDecFromStr("10"), + Data: "", + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_LIMIT, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + { + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_MARKET, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + }, + } + + suite.msgCancelOrders = &types.MsgCancelOrders{ + Creator: suite.creator, + ContractAddr: suite.contract, + Cancellations: []*types.Cancellation{ + { + Id: 1, + Price: sdk.MustNewDecFromStr("10"), + Creator: suite.creator, + PositionDirection: types.PositionDirection_LONG, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + { + Id: 2, + Creator: suite.creator, + Price: sdk.MustNewDecFromStr("20"), + PositionDirection: types.PositionDirection_SHORT, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + }, + } +} + +func (suite *KeeperTestSuite) TestMsgPlaceOrder() { + suite.PrepareTest() + tests := []struct { + name string + expectedError error + msg *dextypes.MsgPlaceOrders + dynamicDep bool + }{ + { + name: "default place order", + msg: suite.msgPlaceOrders, + expectedError: sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated"), + dynamicDep: true, + }, + { + name: "dont check synchronous", + msg: suite.msgPlaceOrders, + expectedError: sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated"), + dynamicDep: false, + }, + } + for _, tc := range tests { + suite.Run(fmt.Sprintf("Test Case: %s", tc.name), func() { + goCtx := context.WithValue(suite.Ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(suite.App.GetMemKey(dextypes.MemStoreKey))) + suite.Ctx = suite.Ctx.WithContext(goCtx) + + handlerCtx, cms := aclutils.CacheTxContext(suite.Ctx) + _, err := suite.msgServer.PlaceOrders( + sdk.WrapSDKContext(handlerCtx), + tc.msg, + ) + + depdenencies, _ := dexacl.DexPlaceOrdersDependencyGenerator( + suite.App.AccessControlKeeper, + handlerCtx, + tc.msg, + ) + + if !tc.dynamicDep { + depdenencies = sdkacltypes.SynchronousAccessOps() + } + + if tc.expectedError != nil { + suite.Require().EqualError(err, tc.expectedError.Error()) + } else { + suite.Require().NoError(err) + } + + missing := handlerCtx.MsgValidator().ValidateAccessOperations(depdenencies, cms.GetEvents()) + pp.Default.SetColoringEnabled(false) + + suite.Require().Empty(missing) + }) + } +} + +func (suite *KeeperTestSuite) TestMsgCancelOrder() { + suite.PrepareTest() + tests := []struct { + name string + expectedError error + msg *dextypes.MsgCancelOrders + dynamicDep bool + }{ + { + name: "default cancel order", + msg: suite.msgCancelOrders, + expectedError: sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated"), + dynamicDep: true, + }, + { + name: "dont check synchronous", + msg: suite.msgCancelOrders, + expectedError: sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated"), + dynamicDep: false, + }, + } + for _, tc := range tests { + suite.Run(fmt.Sprintf("Test Case: %s", tc.name), func() { + goCtx := context.WithValue(suite.Ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(suite.App.GetMemKey(dextypes.MemStoreKey))) + suite.Ctx = suite.Ctx.WithContext(goCtx) + + _, err := suite.msgServer.PlaceOrders( + sdk.WrapSDKContext(suite.Ctx), + suite.msgPlaceOrders, + ) + + handlerCtx, cms := aclutils.CacheTxContext(suite.Ctx) + _, err = suite.msgServer.CancelOrders( + sdk.WrapSDKContext(handlerCtx), + tc.msg, + ) + + depdenencies, _ := dexacl.DexCancelOrdersDependencyGenerator( + suite.App.AccessControlKeeper, + handlerCtx, + tc.msg, + ) + + if !tc.dynamicDep { + depdenencies = sdkacltypes.SynchronousAccessOps() + } + + if tc.expectedError != nil { + suite.Require().EqualError(err, tc.expectedError.Error()) + } else { + suite.Require().NoError(err) + } + + missing := handlerCtx.MsgValidator().ValidateAccessOperations(depdenencies, cms.GetEvents()) + suite.Require().Empty(missing) + }) + } +} + +func TestGeneratorInvalidMessageTypes(t *testing.T) { + tm := time.Now().UTC() + valPub := secp256k1.GenPrivKey().PubKey() + testWrapper := app.NewTestWrapper(t, tm, valPub, false) + + oracleVote := oracletypes.MsgAggregateExchangeRateVote{ + ExchangeRates: "1usei", + Feeder: "test", + Validator: "validator", + } + + _, err := dexacl.DexPlaceOrdersDependencyGenerator( + testWrapper.App.AccessControlKeeper, + testWrapper.Ctx, + &oracleVote, + ) + require.Error(t, err) + + _, err = dexacl.DexCancelOrdersDependencyGenerator( + testWrapper.App.AccessControlKeeper, + testWrapper.Ctx, + &oracleVote, + ) + require.Error(t, err) +} + +func (suite *KeeperTestSuite) TestMsgPlaceOrderGenerator() { + suite.PrepareTest() + + accessOps, err := dexacl.DexPlaceOrdersDependencyGenerator( + suite.App.AccessControlKeeper, + suite.Ctx, + suite.msgPlaceOrders, + ) + require.NoError(suite.T(), err) + err = acltypes.ValidateAccessOps(accessOps) + require.NoError(suite.T(), err) +} + +func (suite *KeeperTestSuite) TestMsgCancelOrderGenerator() { + suite.PrepareTest() + accessOps, err := dexacl.DexCancelOrdersDependencyGenerator( + suite.App.AccessControlKeeper, + suite.Ctx, + suite.msgCancelOrders, + ) + require.NoError(suite.T(), err) + err = acltypes.ValidateAccessOps(accessOps) + require.NoError(suite.T(), err) +} diff --git a/aclmapping/utils/resource_type.go b/aclmapping/utils/resource_type.go index 747cc086c..34fd3cbd6 100644 --- a/aclmapping/utils/resource_type.go +++ b/aclmapping/utils/resource_type.go @@ -11,6 +11,8 @@ import ( feegranttypes "github.com/cosmos/cosmos-sdk/x/feegrant" slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + dexkeeper "github.com/sei-protocol/sei-chain/x/dex/keeper" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" epochtypes "github.com/sei-protocol/sei-chain/x/epoch/types" evmtypes "github.com/sei-protocol/sei-chain/x/evm/types" oracletypes "github.com/sei-protocol/sei-chain/x/oracle/types" @@ -27,6 +29,40 @@ var StoreKeyToResourceTypePrefixMap = aclsdktypes.StoreKeyToResourceTypePrefixMa aclsdktypes.ResourceType_KV: aclsdktypes.EmptyPrefix, aclsdktypes.ResourceType_Mem: aclsdktypes.EmptyPrefix, }, + dextypes.StoreKey: { + aclsdktypes.ResourceType_KV_DEX: aclsdktypes.EmptyPrefix, + aclsdktypes.ResourceType_DexMem: aclsdktypes.EmptyPrefix, + aclsdktypes.ResourceType_KV_DEX_CONTRACT_LONGBOOK: dextypes.KeyPrefix(dextypes.LongBookKey), + aclsdktypes.ResourceType_KV_DEX_CONTRACT_SHORTBOOK: dextypes.KeyPrefix(dextypes.ShortBookKey), + // pricedenom and assetdenoms are the prefixes + aclsdktypes.ResourceType_KV_DEX_PAIR_PREFIX: aclsdktypes.EmptyPrefix, + aclsdktypes.ResourceType_KV_DEX_TWAP: dextypes.KeyPrefix(dextypes.TwapKey), + aclsdktypes.ResourceType_KV_DEX_PRICE: dextypes.KeyPrefix(dextypes.PriceKey), + aclsdktypes.ResourceType_KV_DEX_SETTLEMENT_ENTRY: dextypes.KeyPrefix(dextypes.SettlementEntryKey), + aclsdktypes.ResourceType_KV_DEX_REGISTERED_PAIR: dextypes.KeyPrefix(dextypes.RegisteredPairKey), + aclsdktypes.ResourceType_KV_DEX_ORDER: dextypes.KeyPrefix(dextypes.OrderKey), + aclsdktypes.ResourceType_KV_DEX_CANCEL: dextypes.KeyPrefix(dextypes.CancelKey), + aclsdktypes.ResourceType_KV_DEX_ACCOUNT_ACTIVE_ORDERS: dextypes.KeyPrefix(dextypes.AccountActiveOrdersKey), + aclsdktypes.ResourceType_KV_DEX_ASSET_LIST: dextypes.KeyPrefix(dextypes.AssetListKey), + aclsdktypes.ResourceType_KV_DEX_NEXT_ORDER_ID: dextypes.KeyPrefix(dextypes.NextOrderIDKey), + aclsdktypes.ResourceType_KV_DEX_NEXT_SETTLEMENT_ID: dextypes.KeyPrefix(dextypes.NextSettlementIDKey), + aclsdktypes.ResourceType_KV_DEX_MATCH_RESULT: dextypes.KeyPrefix(dextypes.MatchResultKey), + aclsdktypes.ResourceType_KV_DEX_CONTRACT: dextypes.KeyPrefix(dexkeeper.ContractPrefixKey), + aclsdktypes.ResourceType_KV_DEX_ORDER_BOOK: dextypes.KeyPrefix(dextypes.NextOrderIDKey), + aclsdktypes.ResourceType_KV_DEX_LONG_ORDER_COUNT: dextypes.KeyPrefix(dextypes.LongOrderCountKey), + aclsdktypes.ResourceType_KV_DEX_SHORT_ORDER_COUNT: dextypes.KeyPrefix(dextypes.ShortOrderCountKey), + // SETTLEMENT keys are prefixed with account and order id + aclsdktypes.ResourceType_KV_DEX_SETTLEMENT_ORDER_ID: aclsdktypes.EmptyPrefix, + aclsdktypes.ResourceType_KV_DEX_SETTLEMENT: aclsdktypes.EmptyPrefix, + }, + dextypes.MemStoreKey: { + // mem + aclsdktypes.ResourceType_KV_DEX_MEM_ORDER: dextypes.KeyPrefix(dextypes.MemOrderKey), + aclsdktypes.ResourceType_KV_DEX_MEM_CANCEL: dextypes.KeyPrefix(dextypes.MemCancelKey), + aclsdktypes.ResourceType_KV_DEX_MEM_DEPOSIT: dextypes.KeyPrefix(dextypes.MemDepositKey), + aclsdktypes.ResourceType_KV_DEX_MEM_CONTRACTS_TO_PROCESS: dextypes.KeyPrefix(dextypes.MemContractsToProcess), + aclsdktypes.ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS: dextypes.KeyPrefix(dextypes.MemDownstreamContracts), + }, banktypes.StoreKey: { aclsdktypes.ResourceType_KV_BANK: aclsdktypes.EmptyPrefix, aclsdktypes.ResourceType_KV_BANK_BALANCES: banktypes.BalancesPrefix, @@ -137,6 +173,40 @@ var StoreKeyToResourceTypePrefixMap = aclsdktypes.StoreKeyToResourceTypePrefixMa // ResourceTypeToStoreKeyMap this maps between resource types and their respective storekey var ResourceTypeToStoreKeyMap = aclsdktypes.ResourceTypeToStoreKeyMap{ // ANY, KV, and MEM are intentionally excluded because they don't map to a specific store key + + // ~~~~ DEX Resource Types ~~~~ + aclsdktypes.ResourceType_KV_DEX: dextypes.StoreKey, + aclsdktypes.ResourceType_DexMem: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_CONTRACT_LONGBOOK: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_CONTRACT_SHORTBOOK: dextypes.StoreKey, + // pricedenom and assetdenoms are the prefixes + aclsdktypes.ResourceType_KV_DEX_PAIR_PREFIX: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_TWAP: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_PRICE: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_SETTLEMENT_ENTRY: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_REGISTERED_PAIR: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_ORDER: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_CANCEL: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_ACCOUNT_ACTIVE_ORDERS: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_ASSET_LIST: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_NEXT_ORDER_ID: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_NEXT_SETTLEMENT_ID: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_MATCH_RESULT: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_CONTRACT: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_ORDER_BOOK: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_LONG_ORDER_COUNT: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_SHORT_ORDER_COUNT: dextypes.StoreKey, + // SETTLEMENT keys are prefixed with account and order id + aclsdktypes.ResourceType_KV_DEX_SETTLEMENT_ORDER_ID: dextypes.StoreKey, + aclsdktypes.ResourceType_KV_DEX_SETTLEMENT: dextypes.StoreKey, + + // ~~~~ DEX MEM Resource Types ~~~~ + aclsdktypes.ResourceType_KV_DEX_MEM_ORDER: dextypes.MemStoreKey, + aclsdktypes.ResourceType_KV_DEX_MEM_CANCEL: dextypes.MemStoreKey, + aclsdktypes.ResourceType_KV_DEX_MEM_DEPOSIT: dextypes.MemStoreKey, + aclsdktypes.ResourceType_KV_DEX_MEM_CONTRACTS_TO_PROCESS: dextypes.MemStoreKey, + aclsdktypes.ResourceType_KV_DEX_MEM_DOWNSTREAM_CONTRACTS: dextypes.MemStoreKey, + // ~~~~ BANK Resource Types ~~~~ aclsdktypes.ResourceType_KV_BANK: banktypes.StoreKey, aclsdktypes.ResourceType_KV_BANK_BALANCES: banktypes.StoreKey, diff --git a/app/ante.go b/app/ante.go index 73fe48a61..3106816df 100644 --- a/app/ante.go +++ b/app/ante.go @@ -14,6 +14,9 @@ import ( ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper" "github.com/sei-protocol/sei-chain/app/antedecorators" "github.com/sei-protocol/sei-chain/app/antedecorators/depdecorators" + "github.com/sei-protocol/sei-chain/x/dex" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + dexkeeper "github.com/sei-protocol/sei-chain/x/dex/keeper" evmante "github.com/sei-protocol/sei-chain/x/evm/ante" evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper" "github.com/sei-protocol/sei-chain/x/oracle" @@ -29,9 +32,11 @@ type HandlerOptions struct { WasmConfig *wasmtypes.WasmConfig WasmKeeper *wasm.Keeper OracleKeeper *oraclekeeper.Keeper + DexKeeper *dexkeeper.Keeper AccessControlKeeper *aclkeeper.Keeper EVMKeeper *evmkeeper.Keeper TXCounterStoreKey sdk.StoreKey + CheckTxMemState *dexcache.MemState LatestCtxGetter func() sdk.Context TracingInfo *tracing.Info @@ -65,6 +70,9 @@ func NewAnteHandlerAndDepGenerator(options HandlerOptions) (sdk.AnteHandler, sdk if options.TracingInfo == nil { return nil, nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "tracing info is required for ante builder") } + if options.CheckTxMemState == nil { + return nil, nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "checktx memstate is required for ante builder") + } if options.EVMKeeper == nil { return nil, nil, sdkerrors.Wrap(sdkerrors.ErrLogic, "evm keeper is required for ante builder") } @@ -101,6 +109,8 @@ func NewAnteHandlerAndDepGenerator(options HandlerOptions) (sdk.AnteHandler, sdk sdk.DefaultWrappedAnteDecorator(evmante.NewEVMAddressDecorator(options.EVMKeeper, options.EVMKeeper.AccountKeeper())), sdk.DefaultWrappedAnteDecorator(antedecorators.NewAuthzNestedMessageDecorator()), sdk.DefaultWrappedAnteDecorator(ibcante.NewAnteDecorator(options.IBCKeeper)), + sdk.DefaultWrappedAnteDecorator(dex.NewTickSizeMultipleDecorator(*options.DexKeeper)), + dex.NewCheckDexGasDecorator(*options.DexKeeper, options.CheckTxMemState), antedecorators.NewACLWasmDependencyDecorator(*options.AccessControlKeeper, *options.WasmKeeper), } diff --git a/app/ante_test.go b/app/ante_test.go index dfbf7a533..a433e5d83 100644 --- a/app/ante_test.go +++ b/app/ante_test.go @@ -99,8 +99,10 @@ func (suite *AnteTestSuite) SetupTest(isCheckTx bool) { WasmConfig: &wasmConfig, WasmKeeper: &suite.App.WasmKeeper, OracleKeeper: &suite.App.OracleKeeper, + DexKeeper: &suite.App.DexKeeper, AccessControlKeeper: &suite.App.AccessControlKeeper, TracingInfo: tracingInfo, + CheckTxMemState: suite.App.CheckTxMemState, EVMKeeper: &suite.App.EvmKeeper, LatestCtxGetter: func() sdk.Context { return suite.Ctx }, }, diff --git a/app/antedecorators/gasless.go b/app/antedecorators/gasless.go index 2835b93ba..f71798b1d 100644 --- a/app/antedecorators/gasless.go +++ b/app/antedecorators/gasless.go @@ -1,6 +1,7 @@ package antedecorators import ( + "bytes" "encoding/hex" storetypes "github.com/cosmos/cosmos-sdk/store/types" @@ -8,6 +9,7 @@ import ( sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper" evmtypes "github.com/sei-protocol/sei-chain/x/evm/types" oraclekeeper "github.com/sei-protocol/sei-chain/x/oracle/keeper" @@ -116,6 +118,15 @@ func IsTxGasless(tx sdk.Tx, ctx sdk.Context, oracleKeeper oraclekeeper.Keeper, e } for _, msg := range tx.GetMsgs() { switch m := msg.(type) { + case *dextypes.MsgPlaceOrders: + if !dexPlaceOrdersIsGasless(m) { + return false, nil + } + + case *dextypes.MsgCancelOrders: + if !dexCancelOrdersIsGasless(m) { + return false, nil + } case *oracletypes.MsgAggregateExchangeRateVote: isGasless, err := oracleVoteIsGasless(m, ctx, oracleKeeper) if err != nil || !isGasless { @@ -132,6 +143,33 @@ func IsTxGasless(tx sdk.Tx, ctx sdk.Context, oracleKeeper oraclekeeper.Keeper, e return true, nil } +func dexPlaceOrdersIsGasless(_ *dextypes.MsgPlaceOrders) bool { + return false +} + +// WhitelistedGaslessCancellationAddrs TODO: migrate this into params state +var WhitelistedGaslessCancellationAddrs = []sdk.AccAddress{} + +func dexCancelOrdersIsGasless(msg *dextypes.MsgCancelOrders) bool { + return allSignersWhitelisted(msg) +} + +func allSignersWhitelisted(msg *dextypes.MsgCancelOrders) bool { + for _, signer := range msg.GetSigners() { + isWhitelisted := false + for _, whitelisted := range WhitelistedGaslessCancellationAddrs { + if bytes.Compare(signer, whitelisted) == 0 { //nolint:gosimple + isWhitelisted = true + break + } + } + if !isWhitelisted { + return false + } + } + return true +} + func oracleVoteIsGasless(msg *oracletypes.MsgAggregateExchangeRateVote, ctx sdk.Context, keeper oraclekeeper.Keeper) (bool, error) { feederAddr, err := sdk.AccAddressFromBech32(msg.Feeder) if err != nil { diff --git a/app/antedecorators/gasless_test.go b/app/antedecorators/gasless_test.go index 8152dceab..58143c1ce 100644 --- a/app/antedecorators/gasless_test.go +++ b/app/antedecorators/gasless_test.go @@ -8,10 +8,12 @@ import ( "github.com/cosmos/cosmos-sdk/types/accesscontrol" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/sei-protocol/sei-chain/app/antedecorators" + "github.com/sei-protocol/sei-chain/x/dex/types" evmkeeper "github.com/sei-protocol/sei-chain/x/evm/keeper" oraclekeeper "github.com/sei-protocol/sei-chain/x/oracle/keeper" oracletypes "github.com/sei-protocol/sei-chain/x/oracle/types" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto/secp256k1" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) @@ -149,11 +151,40 @@ func TestOracleVoteGasless(t *testing.T) { require.True(t, gasless) } +func TestDexCancelOrderGasless(t *testing.T) { + addr1 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + addr2 := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) + + antedecorators.WhitelistedGaslessCancellationAddrs = []sdk.AccAddress{ + addr2, + } + + cancelMsg1 := types.MsgCancelOrders{ + Creator: addr1.String(), + } + cancelMsg2 := types.MsgCancelOrders{ + Creator: addr2.String(), + } + // not whitelisted + // reset gasless + gasless = true + err := CallGaslessDecoratorWithMsg(sdk.NewContext(nil, tmproto.Header{}, false, nil).WithIsCheckTx(true), &cancelMsg1, oraclekeeper.Keeper{}, nil) + require.NoError(t, err) + require.False(t, gasless) + + // whitelisted + // reset gasless + gasless = true + err = CallGaslessDecoratorWithMsg(sdk.NewContext(nil, tmproto.Header{}, false, nil).WithIsCheckTx(true), &cancelMsg2, oraclekeeper.Keeper{}, nil) + require.NoError(t, err) + require.True(t, gasless) +} + func TestNonGaslessMsg(t *testing.T) { // this needs to be updated if its changed from constant true // reset gasless gasless = true - err := CallGaslessDecoratorWithMsg(sdk.NewContext(nil, tmproto.Header{}, false, nil).WithIsCheckTx(true), &oracletypes.MsgDelegateFeedConsent{}, oraclekeeper.Keeper{}, nil) + err := CallGaslessDecoratorWithMsg(sdk.NewContext(nil, tmproto.Header{}, false, nil).WithIsCheckTx(true), &types.MsgRegisterContract{}, oraclekeeper.Keeper{}, nil) require.NoError(t, err) require.False(t, gasless) } diff --git a/app/antedecorators/priority_test.go b/app/antedecorators/priority_test.go index 4083fac1e..bc5ceff19 100644 --- a/app/antedecorators/priority_test.go +++ b/app/antedecorators/priority_test.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sei-protocol/sei-chain/app/antedecorators" + "github.com/sei-protocol/sei-chain/x/dex/types" oracletypes "github.com/sei-protocol/sei-chain/x/oracle/types" "github.com/stretchr/testify/require" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -41,7 +42,7 @@ func TestPriorityAnteDecoratorTooHighPriority(t *testing.T) { ctx.WithPriority(math.MaxInt64-50), FakeTx{ FakeMsgs: []sdk.Msg{ - &oracletypes.MsgDelegateFeedConsent{}, + &types.MsgPlaceOrders{}, }, }, false, diff --git a/app/app.go b/app/app.go index 91a0f85be..9d2caa80d 100644 --- a/app/app.go +++ b/app/app.go @@ -47,9 +47,11 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" - sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/module" "github.com/cosmos/cosmos-sdk/version" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + genesistypes "github.com/cosmos/cosmos-sdk/types/genesis" aclmodule "github.com/cosmos/cosmos-sdk/x/accesscontrol" aclclient "github.com/cosmos/cosmos-sdk/x/accesscontrol/client" aclconstants "github.com/cosmos/cosmos-sdk/x/accesscontrol/constants" @@ -148,6 +150,12 @@ import ( "github.com/sei-protocol/sei-chain/utils/metrics" + dexmodule "github.com/sei-protocol/sei-chain/x/dex" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + dexmodulekeeper "github.com/sei-protocol/sei-chain/x/dex/keeper" + dexmoduletypes "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + oraclemodule "github.com/sei-protocol/sei-chain/x/oracle" oraclekeeper "github.com/sei-protocol/sei-chain/x/oracle/keeper" oracletypes "github.com/sei-protocol/sei-chain/x/oracle/types" @@ -219,6 +227,7 @@ var ( oraclemodule.AppModuleBasic{}, evm.AppModuleBasic{}, wasm.AppModuleBasic{}, + dexmodule.AppModuleBasic{}, epochmodule.AppModuleBasic{}, tokenfactorymodule.AppModuleBasic{}, // this line is used by starport scaffolding # stargate/app/moduleBasic @@ -237,6 +246,7 @@ var ( oracletypes.ModuleName: nil, wasm.ModuleName: {authtypes.Burner}, evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, + dexmoduletypes.ModuleName: {authtypes.Burner}, tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // this line is used by starport scaffolding # stargate/app/maccPerms } @@ -350,6 +360,8 @@ type App struct { ScopedTransferKeeper capabilitykeeper.ScopedKeeper ScopedWasmKeeper capabilitykeeper.ScopedKeeper + DexKeeper dexmodulekeeper.Keeper + EpochKeeper epochmodulekeeper.Keeper TokenFactoryKeeper tokenfactorykeeper.Keeper @@ -374,6 +386,10 @@ type App struct { mounter func() + CheckTxMemState *dexcache.MemState + ProcessProposalMemState *dexcache.MemState + MemState *dexcache.MemState + HardForkManager *upgrades.HardForkManager encodingConfig appparams.EncodingConfig @@ -381,6 +397,8 @@ type App struct { evmTracer *tracing.Hooks lightInvarianceConfig LightInvarianceConfig + genesisImportConfig genesistypes.GenesisImportConfig + receiptStore seidb.StateStore } @@ -422,12 +440,13 @@ func New( govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey, oracletypes.StoreKey, evmtypes.StoreKey, wasm.StoreKey, + dexmoduletypes.StoreKey, epochmoduletypes.StoreKey, tokenfactorytypes.StoreKey, // this line is used by starport scaffolding # stargate/app/storeKey ) tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientStoreKey) - memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, banktypes.DeferredCacheStoreKey, oracletypes.MemStoreKey) + memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, dexmoduletypes.MemStoreKey, banktypes.DeferredCacheStoreKey, oracletypes.MemStoreKey) app := &App{ BaseApp: bApp, @@ -544,7 +563,15 @@ func New( app.GetSubspace(epochmoduletypes.ModuleName), ).SetHooks(epochmoduletypes.NewMultiEpochHooks( app.MintKeeper.Hooks())) - + app.DexKeeper = *dexmodulekeeper.NewKeeper( + appCodec, + keys[dexmoduletypes.StoreKey], + memKeys[dexmoduletypes.MemStoreKey], + app.GetSubspace(dexmoduletypes.ModuleName), + app.EpochKeeper, + app.BankKeeper, + app.AccountKeeper, + ) app.TokenFactoryKeeper = tokenfactorykeeper.NewKeeper( appCodec, app.keys[tokenfactorytypes.StoreKey], @@ -560,6 +587,7 @@ func New( wasmOpts = append( wasmbinding.RegisterCustomPlugins( &app.OracleKeeper, + &app.DexKeeper, &app.EpochKeeper, &app.TokenFactoryKeeper, &app.AccountKeeper, @@ -611,6 +639,7 @@ func New( tkeys[evmtypes.TransientStoreKey], app.GetSubspace(evmtypes.ModuleName), app.receiptStore, app.BankKeeper, &app.AccountKeeper, &app.StakingKeeper, app.TransferKeeper, wasmkeeper.NewDefaultPermissionKeeper(app.WasmKeeper), &app.WasmKeeper) + app.BankKeeper.RegisterRecipientChecker(app.EvmKeeper.CanAddressReceive) bApp.SetPreCommitHandler(app.HandlePreCommit) bApp.SetCloseHandler(app.HandleClose) @@ -647,6 +676,12 @@ func New( } app.lightInvarianceConfig = lightInvarianceConfig + genesisImportConfig, err := ReadGenesisImportConfig(appOpts) + if err != nil { + panic(fmt.Sprintf("error reading genesis import config due to %s", err)) + } + app.genesisImportConfig = genesisImportConfig + customDependencyGenerators := aclmapping.NewCustomDependencyGenerator() aclOpts = append(aclOpts, aclkeeper.WithResourceTypeToStoreKeyMap(aclutils.ResourceTypeToStoreKeyMap)) aclOpts = append(aclOpts, aclkeeper.WithDependencyGeneratorMappings(customDependencyGenerators.GetCustomDependencyGenerators(app.EvmKeeper))) @@ -659,6 +694,8 @@ func New( aclOpts..., ) + app.DexKeeper.SetWasmKeeper(&app.WasmKeeper) + dexModule := dexmodule.NewAppModule(appCodec, app.DexKeeper, app.AccountKeeper, app.BankKeeper, app.WasmKeeper, app.GetBaseApp().TracingInfo) epochModule := epochmodule.NewAppModule(appCodec, app.EpochKeeper, app.AccountKeeper, app.BankKeeper) // register the proposal types @@ -668,6 +705,7 @@ func New( AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)). AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)). AddRoute(ibcclienttypes.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper)). + AddRoute(dexmoduletypes.RouterKey, dexmodule.NewProposalHandler(app.DexKeeper)). AddRoute(minttypes.RouterKey, mint.NewProposalHandler(app.MintKeeper)). AddRoute(tokenfactorytypes.RouterKey, tokenfactorymodule.NewProposalHandler(app.TokenFactoryKeeper)). AddRoute(acltypes.ModuleName, aclmodule.NewProposalHandler(app.AccessControlKeeper)). @@ -746,6 +784,7 @@ func New( wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), evm.NewAppModule(appCodec, &app.EvmKeeper), transferModule, + dexModule, epochModule, tokenfactorymodule.NewAppModule(app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry), @@ -777,6 +816,7 @@ func New( ibchost.ModuleName, ibctransfertypes.ModuleName, oracletypes.ModuleName, + dexmoduletypes.ModuleName, evmtypes.ModuleName, wasm.ModuleName, tokenfactorytypes.ModuleName, @@ -808,6 +848,7 @@ func New( ibctransfertypes.ModuleName, oracletypes.ModuleName, epochmoduletypes.ModuleName, + dexmoduletypes.ModuleName, evmtypes.ModuleName, wasm.ModuleName, tokenfactorytypes.ModuleName, @@ -833,6 +874,7 @@ func New( vestingtypes.ModuleName, crisistypes.ModuleName, ibchost.ModuleName, + dexmoduletypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, ibctransfertypes.ModuleName, @@ -869,6 +911,7 @@ func New( wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper), ibc.NewAppModule(app.IBCKeeper), transferModule, + dexModule, epochModule, tokenfactorymodule.NewAppModule(app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper), // this line is used by starport scaffolding # stargate/app/appModule @@ -886,6 +929,10 @@ func New( } app.mounter() + app.CheckTxMemState = dexcache.NewMemState(app.GetMemKey(dexmoduletypes.MemStoreKey)) + app.ProcessProposalMemState = dexcache.NewMemState(app.GetMemKey(dexmoduletypes.MemStoreKey)) + app.MemState = dexcache.NewMemState(app.GetMemKey(dexmoduletypes.MemStoreKey)) + // initialize BaseApp app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) @@ -909,9 +956,11 @@ func New( WasmConfig: &wasmConfig, WasmKeeper: &app.WasmKeeper, OracleKeeper: &app.OracleKeeper, + DexKeeper: &app.DexKeeper, EVMKeeper: &app.EvmKeeper, TracingInfo: app.GetBaseApp().TracingInfo, AccessControlKeeper: &app.AccessControlKeeper, + CheckTxMemState: app.CheckTxMemState, LatestCtxGetter: func() sdk.Context { return app.GetCheckCtx() }, @@ -1052,16 +1101,6 @@ func (app *App) SetStoreUpgradeHandlers() { Added: []string{evmtypes.StoreKey}, } - // configure store loader that checks if version == upgradeHeight and applies store upgrades - app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) - } - // TODO: change this upgrade name if the planned upgrade version number ends up changing more - if upgradeInfo.Name == "v5.7.1" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { - dexStoreKeyName := "dex" - storeUpgrades := storetypes.StoreUpgrades{ - Deleted: []string{dexStoreKeyName}, - } - // configure store loader that checks if version == upgradeHeight and applies store upgrades app.SetStoreLoader(upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) } @@ -1096,11 +1135,14 @@ func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.Respo // InitChainer application update at chain initialization func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { var genesisState GenesisState - if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil { - panic(err) + if !app.genesisImportConfig.StreamGenesisImport { + if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil { + panic(err) + } } + ctx = ctx.WithContext(app.decorateContextWithDexMemState(ctx.Context())) app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap()) - return app.mm.InitGenesis(ctx, app.appCodec, genesisState) + return app.mm.InitGenesis(ctx, app.appCodec, genesisState, app.genesisImportConfig) } func (app *App) PrepareProposalHandler(_ sdk.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) { @@ -1145,6 +1187,7 @@ func (app *App) ProcessProposalHandler(ctx sdk.Context, req *abci.RequestProcess app.optimisticProcessingInfo.Completion <- struct{}{} } else { go func() { + ctx = ctx.WithContext(app.decorateProcessProposalContextWithDexMemState(ctx.Context())) events, txResults, endBlockResp, _ := app.ProcessBlock(ctx, req.Txs, req, req.ProposedLastCommit) optimisticProcessingInfo.Events = events optimisticProcessingInfo.TxRes = txResults @@ -1184,6 +1227,8 @@ func (app *App) FinalizeBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock) } metrics.IncrementOptimisticProcessingCounter(false) ctx.Logger().Info("optimistic processing ineligible") + ctx = ctx.WithContext(app.decorateContextWithDexMemState(ctx.Context())) + events, txResults, endBlockResp, _ := app.ProcessBlock(ctx, req.Txs, req, req.DecidedLastCommit) app.SetDeliverStateToCommit() @@ -1392,6 +1437,7 @@ func (app *App) ProcessTxs( dependencyDag.TxMsgAccessOpMapping, absoluteTxIndices, ) + oldDexMemState := dexutils.GetMemState(ctx.Context()).DeepCopy() if ok { // Write the results back to the concurrent contexts - if concurrent execution fails, // this should not be called and the state is rolled back and retried with synchronous execution @@ -1402,6 +1448,13 @@ func (app *App) ProcessTxs( ctx = app.addBadWasmDependenciesToContext(ctx, concurrentResults) ctx.Logger().Error("Concurrent Execution failed, retrying with Synchronous") + oldDexMemStateCtx := context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, oldDexMemState) + ctx = ctx.WithContext(oldDexMemStateCtx) + + dexMemState := dexutils.GetMemState(ctx.Context()) + dexMemState.Clear(ctx) + dexMemState.ClearContractToDependencies(ctx) + txResults := app.ProcessBlockSynchronous(ctx, txs, typedTxs, absoluteTxIndices) processBlockCache.Write() return txResults, ctx @@ -1427,6 +1480,12 @@ func (app *App) PartitionPrioritizedTxs(_ sdk.Context, txs [][]byte, typedTxs [] switch msg.(type) { case *oracletypes.MsgAggregateExchangeRateVote: prioritized = true + case *dexmoduletypes.MsgRegisterContract: + prioritized = true + case *dexmoduletypes.MsgUnregisterContract: + prioritized = true + case *dexmoduletypes.MsgUnsuspendContract: + prioritized = true default: prioritized = false break msgLoop @@ -1557,6 +1616,8 @@ func (app *App) BuildDependenciesAndRunTxs(ctx sdk.Context, txs [][]byte, typedT func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequest, lastCommit abci.CommitInfo) (events []abci.Event, txResults []*abci.ExecTxResult, endBlockResp abci.ResponseEndBlock, err error) { ctx = ctx.WithIsOCCEnabled(app.OccEnabled()) + goCtx := app.decorateContextWithDexMemState(ctx.Context()) + ctx = ctx.WithContext(goCtx) if app.evmTracer != nil { ctx = evmtracers.SetCtxBlockchainTracer(ctx, app.evmTracer) @@ -1947,6 +2008,7 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(oracletypes.ModuleName) paramsKeeper.Subspace(wasm.ModuleName) paramsKeeper.Subspace(evmtypes.ModuleName) + paramsKeeper.Subspace(dexmoduletypes.ModuleName) paramsKeeper.Subspace(epochmoduletypes.ModuleName) paramsKeeper.Subspace(tokenfactorytypes.ModuleName) // this line is used by starport scaffolding # stargate/app/paramSubspace @@ -1973,6 +2035,14 @@ func (app *App) SetTxDecoder(txDecoder sdk.TxDecoder) { app.txDecoder = txDecoder } +func (app *App) decorateProcessProposalContextWithDexMemState(base context.Context) context.Context { + return context.WithValue(base, dexutils.DexMemStateContextKey, app.ProcessProposalMemState) +} + +func (app *App) decorateContextWithDexMemState(base context.Context) context.Context { + return context.WithValue(base, dexutils.DexMemStateContextKey, app.MemState) +} + func init() { // override max wasm size to 2MB wasmtypes.MaxWasmSize = 2 * 1024 * 1024 diff --git a/app/app_test.go b/app/app_test.go index 09da0963d..b28160188 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -28,6 +28,7 @@ import ( "github.com/k0kubun/pp/v3" "github.com/sei-protocol/sei-chain/app" testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" "github.com/sei-protocol/sei-chain/x/evm/config" evmtypes "github.com/sei-protocol/sei-chain/x/evm/types" "github.com/sei-protocol/sei-chain/x/evm/types/ethtx" @@ -136,6 +137,25 @@ func TestPartitionPrioritizedTxs(t *testing.T) { Validator: validator, } + contractRegisterMsg := &dextypes.MsgRegisterContract{ + Creator: account, + Contract: &dextypes.ContractInfoV2{ + CodeId: 1, + ContractAddr: "sei1dc34p57spmhguak2ns88u3vxmt73gnu3c0j6phqv5ukfytklkqjsgepv26", + NeedOrderMatching: true, + }, + } + + contractUnregisterMsg := &dextypes.MsgUnregisterContract{ + Creator: account, + ContractAddr: "sei1dc34p57spmhguak2ns88u3vxmt73gnu3c0j6phqv5ukfytklkqjsgepv26", + } + + contractUnsuspendMsg := &dextypes.MsgUnsuspendContract{ + Creator: account, + ContractAddr: "sei1dc34p57spmhguak2ns88u3vxmt73gnu3c0j6phqv5ukfytklkqjsgepv26", + } + otherMsg := &stakingtypes.MsgDelegate{ DelegatorAddress: account, ValidatorAddress: validator, @@ -144,6 +164,9 @@ func TestPartitionPrioritizedTxs(t *testing.T) { txEncoder := app.MakeEncodingConfig().TxConfig.TxEncoder() oracleTxBuilder := app.MakeEncodingConfig().TxConfig.NewTxBuilder() + contractRegisterBuilder := app.MakeEncodingConfig().TxConfig.NewTxBuilder() + contractUnregisterBuilder := app.MakeEncodingConfig().TxConfig.NewTxBuilder() + contractUnsuspendBuilder := app.MakeEncodingConfig().TxConfig.NewTxBuilder() otherTxBuilder := app.MakeEncodingConfig().TxConfig.NewTxBuilder() mixedTxBuilder := app.MakeEncodingConfig().TxConfig.NewTxBuilder() @@ -152,6 +175,21 @@ func TestPartitionPrioritizedTxs(t *testing.T) { oracleTx, err := txEncoder(oracleTxBuilder.GetTx()) require.NoError(t, err) + err = contractRegisterBuilder.SetMsgs(contractRegisterMsg) + require.NoError(t, err) + contractRegisterTx, err := txEncoder(contractRegisterBuilder.GetTx()) + require.NoError(t, err) + + err = contractUnregisterBuilder.SetMsgs(contractUnregisterMsg) + require.NoError(t, err) + contractUnregisterTx, err := txEncoder(contractUnregisterBuilder.GetTx()) + require.NoError(t, err) + + err = contractUnsuspendBuilder.SetMsgs(contractUnsuspendMsg) + require.NoError(t, err) + contractSuspendTx, err := txEncoder(contractUnsuspendBuilder.GetTx()) + require.NoError(t, err) + err = otherTxBuilder.SetMsgs(otherMsg) require.NoError(t, err) otherTx, err := txEncoder(otherTxBuilder.GetTx()) @@ -165,40 +203,52 @@ func TestPartitionPrioritizedTxs(t *testing.T) { txs := [][]byte{ oracleTx, + contractRegisterTx, + contractUnregisterTx, + contractSuspendTx, otherTx, mixedTx, } typedTxs := []sdk.Tx{ oracleTxBuilder.GetTx(), + contractRegisterBuilder.GetTx(), + contractUnregisterBuilder.GetTx(), + contractUnsuspendBuilder.GetTx(), otherTxBuilder.GetTx(), mixedTxBuilder.GetTx(), } prioritizedTxs, otherTxs, prioritizedTypedTxs, otherTypedTxs, prioIdxs, otherIdxs := testWrapper.App.PartitionPrioritizedTxs(testWrapper.Ctx, txs, typedTxs) - require.Equal(t, [][]byte{oracleTx}, prioritizedTxs) + require.Equal(t, [][]byte{oracleTx, contractRegisterTx, contractUnregisterTx, contractSuspendTx}, prioritizedTxs) require.Equal(t, [][]byte{otherTx, mixedTx}, otherTxs) - require.Equal(t, []int{0}, prioIdxs) - require.Equal(t, []int{1, 2}, otherIdxs) - require.Equal(t, 1, len(prioritizedTypedTxs)) + require.Equal(t, []int{0, 1, 2, 3}, prioIdxs) + require.Equal(t, []int{4, 5}, otherIdxs) + require.Equal(t, 4, len(prioritizedTypedTxs)) require.Equal(t, 2, len(otherTypedTxs)) diffOrderTxs := [][]byte{ - otherTx, oracleTx, + otherTx, + contractRegisterTx, + contractUnregisterTx, mixedTx, + contractSuspendTx, } differOrderTypedTxs := []sdk.Tx{ - otherTxBuilder.GetTx(), oracleTxBuilder.GetTx(), + otherTxBuilder.GetTx(), + contractRegisterBuilder.GetTx(), + contractUnregisterBuilder.GetTx(), mixedTxBuilder.GetTx(), + contractUnsuspendBuilder.GetTx(), } prioritizedTxs, otherTxs, prioritizedTypedTxs, otherTypedTxs, prioIdxs, otherIdxs = testWrapper.App.PartitionPrioritizedTxs(testWrapper.Ctx, diffOrderTxs, differOrderTypedTxs) - require.Equal(t, [][]byte{oracleTx}, prioritizedTxs) + require.Equal(t, [][]byte{oracleTx, contractRegisterTx, contractUnregisterTx, contractSuspendTx}, prioritizedTxs) require.Equal(t, [][]byte{otherTx, mixedTx}, otherTxs) - require.Equal(t, []int{1}, prioIdxs) - require.Equal(t, []int{0, 2}, otherIdxs) - require.Equal(t, 1, len(prioritizedTypedTxs)) + require.Equal(t, []int{0, 2, 3, 5}, prioIdxs) + require.Equal(t, []int{1, 4}, otherIdxs) + require.Equal(t, 4, len(prioritizedTypedTxs)) require.Equal(t, 2, len(otherTypedTxs)) } diff --git a/app/apptesting/test_suite.go b/app/apptesting/test_suite.go index 26ec97dd3..9d72cc9f6 100644 --- a/app/apptesting/test_suite.go +++ b/app/apptesting/test_suite.go @@ -16,6 +16,7 @@ import ( slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types" "github.com/cosmos/cosmos-sdk/x/staking/teststaking" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" @@ -39,6 +40,7 @@ type KeeperTestHelper struct { func (s *KeeperTestHelper) Setup() { s.App = app.Setup(false, false) s.Ctx = s.App.BaseApp.NewContext(false, tmtypes.Header{Height: 1, ChainID: "sei-test", Time: time.Now().UTC()}) + s.Ctx = s.Ctx.WithContext(context.WithValue(s.Ctx.Context(), dexutils.DexMemStateContextKey, s.App.MemState)) s.QueryHelper = &baseapp.QueryServiceTestHelper{ GRPCQueryRouter: s.App.GRPCQueryRouter(), Ctx: s.Ctx, diff --git a/app/export.go b/app/export.go index b2e33f633..6c6bfca48 100644 --- a/app/export.go +++ b/app/export.go @@ -2,7 +2,9 @@ package app import ( "encoding/json" + "fmt" "log" + "os" "github.com/cosmos/cosmos-sdk/types/kv" @@ -49,6 +51,41 @@ func (app *App) ExportAppStateAndValidators( }, nil } +func (app *App) ExportAppToFileStateAndValidators( + forZeroHeight bool, jailAllowedAddrs []string, file *os.File, +) (servertypes.ExportedApp, error) { + // as if they could withdraw from the start of the next block + ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}) + + // We export at last height + 1, because that's the height at which + // Tendermint will start InitChain. + height := app.LastBlockHeight() + 1 + if forZeroHeight { + height = 0 + app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs) + } + err := app.mm.ProcessGenesisPerModule(ctx, app.appCodec, func(moduleName string, moduleJson json.RawMessage) error { + _, err := file.Write([]byte(fmt.Sprintf("{\"app_state\": {\"module\":\"%s\",\"data\":%s}}\n", moduleName, string(moduleJson)))) + if err != nil { + return err + } + return nil + }) + if err != nil { + return servertypes.ExportedApp{}, err + } + validators, err := staking.WriteValidators(ctx, app.StakingKeeper) + if err != nil { + return servertypes.ExportedApp{}, err + } + + return servertypes.ExportedApp{ + Validators: validators, + Height: height, + ConsensusParams: app.BaseApp.GetConsensusParams(ctx), + }, nil +} + // AddressFromValidatorsKey creates the validator operator address from ValidatorsKey func AddressFromValidatorsKey(key []byte) []byte { kv.AssertKeyAtLeastLength(key, 3) diff --git a/app/genesis.go b/app/genesis.go index 8e89ec8d4..489104839 100644 --- a/app/genesis.go +++ b/app/genesis.go @@ -4,11 +4,39 @@ import ( "encoding/json" "github.com/cosmos/cosmos-sdk/codec" + genesistypes "github.com/cosmos/cosmos-sdk/types/genesis" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" sdk "github.com/cosmos/cosmos-sdk/types" + + servertypes "github.com/cosmos/cosmos-sdk/server/types" + "github.com/spf13/cast" +) + +var DefaultGenesisConfig = genesistypes.GenesisImportConfig{ + StreamGenesisImport: false, + GenesisStreamFile: "", +} + +const ( + flagGenesisStreamImport = "genesis.stream-import" + flagGenesisImportFile = "genesis.import-file" ) +func ReadGenesisImportConfig(opts servertypes.AppOptions) (genesistypes.GenesisImportConfig, error) { + cfg := DefaultGenesisConfig // copy + var err error + if v := opts.Get(flagGenesisStreamImport); v != nil { + if cfg.StreamGenesisImport, err = cast.ToBoolE(v); err != nil { + return cfg, err + } + } + if v := opts.Get(flagGenesisImportFile); v != nil { + cfg.GenesisStreamFile = v.(string) + } + return cfg, nil +} + // The genesis state of the blockchain is represented here as a map of raw json // messages key'd by a identifier string. // The identifier is used to determine which module genesis information belongs diff --git a/app/test_helpers.go b/app/test_helpers.go index 16c1c80c1..e80e7f357 100644 --- a/app/test_helpers.go +++ b/app/test_helpers.go @@ -22,6 +22,7 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" dbm "github.com/tendermint/tm-db" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" minttypes "github.com/sei-protocol/sei-chain/x/mint/types" ) @@ -81,6 +82,7 @@ func newTestWrapper(t *testing.T, tm time.Time, valPub crptotypes.PubKey, enable appPtr = Setup(false, enableEVMCustomPrecompiles, baseAppOptions...) } ctx := appPtr.BaseApp.NewContext(false, tmproto.Header{Height: 1, ChainID: "sei-test", Time: tm}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, appPtr.MemState)) wrapper := &TestWrapper{ App: appPtr, Ctx: ctx, diff --git a/app/upgrades.go b/app/upgrades.go index 0214791b9..14233f12f 100644 --- a/app/upgrades.go +++ b/app/upgrades.go @@ -103,8 +103,12 @@ var upgradesList = []string{ "v5.5.2", "v5.5.5", "v5.6.0", + "v5.6.2", "v5.7.0", "v5.7.1", + "v5.7.2", + "v5.7.4", + "v5.7.5", } // if there is an override list, use that instead, for integration tests diff --git a/cmd/seid/cmd/debug.go b/cmd/seid/cmd/debug.go index ed95da572..d0a7e3240 100644 --- a/cmd/seid/cmd/debug.go +++ b/cmd/seid/cmd/debug.go @@ -26,7 +26,7 @@ const ( ) var modules = []string{ - "wasm", "aclaccesscontrol", "oracle", "epoch", "mint", "acc", "bank", "crisis", "feegrant", "staking", "distribution", "slashing", "gov", "params", "ibc", "upgrade", "evidence", "transfer", "tokenfactory", + "dex", "wasm", "aclaccesscontrol", "oracle", "epoch", "mint", "acc", "bank", "crisis", "feegrant", "staking", "distribution", "slashing", "gov", "params", "ibc", "upgrade", "evidence", "transfer", "tokenfactory", } func DumpIavlCmd() *cobra.Command { diff --git a/cmd/seid/cmd/iavl_parser.go b/cmd/seid/cmd/iavl_parser.go index 345332f53..fcb54a182 100644 --- a/cmd/seid/cmd/iavl_parser.go +++ b/cmd/seid/cmd/iavl_parser.go @@ -9,6 +9,8 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/sei-protocol/sei-chain/app/params" + dexkeeper "github.com/sei-protocol/sei-chain/x/dex/keeper" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" minttypes "github.com/sei-protocol/sei-chain/x/mint/types" ) @@ -19,6 +21,7 @@ const UNRECOGNIZED = "Unrecognized Prefix" var ModuleParserMap = map[string]ModuleParser{ "bank": BankParser, "mint": MintParser, + "dex": DexParser, "staking": StakingParser, "acc": AccountParser, } @@ -81,6 +84,64 @@ func BankParser(key []byte) ([]string, error) { return keyItems, nil } +func DexParser(key []byte) ([]string, error) { + keyItems := []string{} + if matched, items, _, err := MatchAndExtractDexAddressPrefixKeys(key); matched { + if err != nil { + return keyItems, err + } + keyItems = append(keyItems, items...) + return keyItems, nil + } + switch { + case bytes.HasPrefix(key, []byte(dexkeeper.EpochKey)): + // do nothing since the key is a string and no other data to be parsed + default: + keyItems = append(keyItems, UNRECOGNIZED) + } + return keyItems, nil +} + +func MatchAndExtractDexAddressPrefixKeys(key []byte) (bool, []string, []byte, error) { + keyItems := []string{} + keysToMatch := []string{ + // Source of truth: github.com/sei-protocol/sei-chain/x/dex/types/keys.go - contains key constants represented here + dextypes.LongBookKey, + dextypes.ShortBookKey, + dextypes.PriceKey, + dextypes.TwapKey, + dextypes.SettlementEntryKey, + dextypes.RegisteredPairKey, + dextypes.OrderKey, + dextypes.CancelKey, + dextypes.AccountActiveOrdersKey, + dextypes.NextOrderIDKey, + dextypes.NextSettlementIDKey, + dextypes.MatchResultKey, + dextypes.MemOrderKey, + dextypes.MemCancelKey, + dextypes.MemDepositKey, + dexkeeper.ContractPrefixKey, + } + + for _, prefix := range keysToMatch { + if bytes.HasPrefix(key, dextypes.KeyPrefix(prefix)) { + keyItems = append(keyItems, prefix) + remaining := bytes.TrimPrefix(key, dextypes.KeyPrefix(prefix)) + items, remaining, err := parseLengthPrefixedAddress(remaining) + if err != nil { + return true, keyItems, remaining, err + } + keyItems = append(keyItems, items...) + if len(remaining) > 0 { + keyItems = append(keyItems, fmt.Sprintf("RemainingString: %s", string(remaining))) + } + return true, keyItems, remaining, nil + } + } + return false, keyItems, key, nil +} + func parseLengthPrefixedAddress(remainingKey []byte) ([]string, []byte, error) { keyItems := []string{} lengthPrefix, remaining := int(remainingKey[0]), remainingKey[1:] diff --git a/cmd/seid/cmd/root.go b/cmd/seid/cmd/root.go index f8f5a51f6..df8ed1fe1 100644 --- a/cmd/seid/cmd/root.go +++ b/cmd/seid/cmd/root.go @@ -313,7 +313,33 @@ func appExport( forZeroHeight bool, jailAllowedAddrs []string, appOpts servertypes.AppOptions, + file *os.File, ) (servertypes.ExportedApp, error) { + exportableApp, err := getExportableApp( + logger, + db, + traceStore, + height, + appOpts, + ) + if err != nil { + return servertypes.ExportedApp{}, err + } + + if file == nil { + return exportableApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) + } else { + return exportableApp.ExportAppToFileStateAndValidators(forZeroHeight, jailAllowedAddrs, file) + } +} + +func getExportableApp( + logger log.Logger, + db dbm.DB, + traceStore io.Writer, + height int64, + appOpts servertypes.AppOptions, +) (*app.App, error) { encCfg := app.MakeEncodingConfig() encCfg.Marshaler = codec.NewProtoCodec(encCfg.InterfaceRegistry) @@ -321,19 +347,19 @@ func appExport( homePath, ok := appOpts.Get(flags.FlagHome).(string) if !ok || homePath == "" { - return servertypes.ExportedApp{}, errors.New("application home not set") + return nil, errors.New("application home not set") } if height != -1 { exportableApp = app.New(logger, db, traceStore, false, map[int64]bool{}, cast.ToString(appOpts.Get(flags.FlagHome)), uint(1), true, nil, encCfg, app.GetWasmEnabledProposals(), appOpts, app.EmptyWasmOpts, app.EmptyACLOpts, app.EmptyAppOptions) if err := exportableApp.LoadHeight(height); err != nil { - return servertypes.ExportedApp{}, err + return nil, err } } else { exportableApp = app.New(logger, db, traceStore, true, map[int64]bool{}, cast.ToString(appOpts.Get(flags.FlagHome)), uint(1), true, nil, encCfg, app.GetWasmEnabledProposals(), appOpts, app.EmptyWasmOpts, app.EmptyACLOpts, app.EmptyAppOptions) } + return exportableApp, nil - return exportableApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs) } func getPrimeNums(lo int, hi int) []int { diff --git a/contracts/hardhat.config.js b/contracts/hardhat.config.js index 9bf1ab2b5..3088f6320 100644 --- a/contracts/hardhat.config.js +++ b/contracts/hardhat.config.js @@ -5,8 +5,9 @@ require('@openzeppelin/hardhat-upgrades'); /** @type import('hardhat/config').HardhatUserConfig */ module.exports = { solidity: { - version: "0.8.20", + version: "0.8.25", settings: { + evmVersion: "cancun", optimizer: { enabled: true, runs: 1000, diff --git a/contracts/src/EVMCompatibilityTester.sol b/contracts/src/EVMCompatibilityTester.sol index 0331ffc9f..6c2ef8385 100644 --- a/contracts/src/EVMCompatibilityTester.sol +++ b/contracts/src/EVMCompatibilityTester.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.25; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; @@ -173,5 +173,12 @@ contract EVMCompatibilityTester { bytesVar = value; emit BytesSet(msg.sender, value); } + + function getBlobBaseFee() public view returns (uint256 fee) { + assembly { + fee := blobbasefee() + } + return fee; + } } diff --git a/contracts/test/AssociateTest.js b/contracts/test/AssociateTest.js index 04e35eda1..40c4af735 100644 --- a/contracts/test/AssociateTest.js +++ b/contracts/test/AssociateTest.js @@ -14,7 +14,8 @@ describe("Associate Balances", function () { }, "test3": { seiAddress: 'sei1qkawqt7dw09rkvn53lm2deamtfcpuq9v0h6zur', - evmAddress: '0xCb2FB25A6a34Ca874171Ac0406d05A49BC45a1cF' + evmAddress: '0xCb2FB25A6a34Ca874171Ac0406d05A49BC45a1cF', + castAddress: 'sei1evhmykn2xn9gwst34szqd5z6fx7ytgw0l7g0vs', } } @@ -81,7 +82,12 @@ describe("Associate Balances", function () { await verifyAssociation(addr.seiAddress, addr.evmAddress, async function(){ await associateKey("test3") return BigInt(0) - }) + }); + + // it should not be able to send funds to the cast address after association + expect(await getSeiBalance(addr.castAddress)).to.equal(0); + await fundSeiAddress(addr.castAddress, "100"); + expect(await getSeiBalance(addr.castAddress)).to.equal(0); }); }) \ No newline at end of file diff --git a/contracts/test/EVMCompatabilityTest.js b/contracts/test/EVMCompatabilityTest.js index a5f37c9a1..8ab8220ec 100644 --- a/contracts/test/EVMCompatabilityTest.js +++ b/contracts/test/EVMCompatabilityTest.js @@ -5,6 +5,7 @@ const { ethers, upgrades } = require('hardhat'); const { getImplementationAddress } = require('@openzeppelin/upgrades-core'); const { deployEvmContract, setupSigners, fundAddress, getCosmosTx, getEvmTx} = require("./lib") const axios = require("axios"); +const { default: BigNumber } = require("bignumber.js"); function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); @@ -398,6 +399,12 @@ describe("EVM Test", function () { const retrievedAmount = await evmTester.readFromStorage(0); expect(retrievedAmount).to.equal(BigInt(testAmount)); }); + + it("Should work for BLOBBASEFEE opcode", async function () { + + const blobBaseFee = await evmTester.getBlobBaseFee(); + expect(blobBaseFee).to.deep.equal(BigInt(1)); + }); }) describe("Historical query test", function() { @@ -814,7 +821,7 @@ describe("EVM Test", function () { fromBlock: blockStart, toBlock: blockEnd, }; - + const logs = await ethers.provider.getLogs(filter); expect(logs).to.be.an('array'); expect(logs.length).to.equal(numTxs); @@ -826,7 +833,7 @@ describe("EVM Test", function () { toBlock: blockEnd, topics: [ethers.id("DummyEvent(string,bool,address,uint256,bytes)")] }; - + const logs = await ethers.provider.getLogs(filter); expect(logs).to.be.an('array'); expect(logs.length).to.equal(numTxs); @@ -839,7 +846,7 @@ describe("EVM Test", function () { toBlock: blockEnd, topics: [ethers.id("DummyEvent(string,bool,address,uint256,bytes)")] }; - + const logs = await ethers.provider.getLogs(filter); const blockHash = logs[0].blockHash; @@ -867,9 +874,9 @@ describe("EVM Test", function () { paddedOwnerAddr, ] }; - + const logs = await ethers.provider.getLogs(filter1); - + expect(logs).to.be.an('array'); expect(logs.length).to.equal(numTxs); @@ -885,7 +892,7 @@ describe("EVM Test", function () { }; const logs2 = await ethers.provider.getLogs(filter1); - + expect(logs2).to.be.an('array'); expect(logs2.length).to.equal(numTxs); }); @@ -901,7 +908,7 @@ describe("EVM Test", function () { "0x0000000000000000000000000000000000000000000000000000000000000003", ] }; - + const logs1 = await ethers.provider.getLogs(filter1); expect(logs1).to.be.an('array'); expect(logs1.length).to.equal(1); @@ -948,7 +955,7 @@ describe("EVM Test", function () { ethers.id("nonexistent event string"), ] }; - + const logs = await ethers.provider.getLogs(filter); expect(logs).to.be.an('array'); expect(logs.length).to.equal(0); @@ -1052,7 +1059,7 @@ describe("EVM Test", function () { value: usei, }); await txResponse.wait(); // Wait for the transaction to be mined - + // Check that the contract received the ETH const contractBalance = await ethers.provider.getBalance(evmAddr); expect(contractBalance - initialBalance).to.equal(usei); diff --git a/evmrpc/setup_test.go b/evmrpc/setup_test.go index 73b861e38..3d6ff7ddb 100644 --- a/evmrpc/setup_test.go +++ b/evmrpc/setup_test.go @@ -871,6 +871,12 @@ func formatParam(p interface{}) string { kvs = append(kvs, fmt.Sprintf("\"%s\":%s", k, formatParam(v))) } return fmt.Sprintf("{%s}", strings.Join(kvs, ",")) + case map[string]map[string]interface{}: + kvs := []string{} + for k, v := range v { + kvs = append(kvs, fmt.Sprintf("\"%s\":%s", k, formatParam(v))) + } + return fmt.Sprintf("{%s}", strings.Join(kvs, ",")) default: panic("did not match on type") } diff --git a/evmrpc/simulate.go b/evmrpc/simulate.go index fe1b75567..428ebc0ac 100644 --- a/evmrpc/simulate.go +++ b/evmrpc/simulate.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "strings" "time" "github.com/sei-protocol/sei-chain/utils/helpers" @@ -90,6 +91,15 @@ func (s *SimulationAPI) EstimateGas(ctx context.Context, args ethapi.Transaction func (s *SimulationAPI) Call(ctx context.Context, args ethapi.TransactionArgs, blockNrOrHash *rpc.BlockNumberOrHash, overrides *ethapi.StateOverride, blockOverrides *ethapi.BlockOverrides) (result hexutil.Bytes, returnErr error) { startTime := time.Now() defer recordMetrics("eth_call", s.connectionType, startTime, returnErr == nil) + defer func() { + if r := recover(); r != nil { + if strings.Contains(fmt.Sprintf("%s", r), "Int overflow") { + returnErr = errors.New("error: balance override overflow") + } else { + returnErr = fmt.Errorf("something went wrong: %v", r) + } + } + }() if blockNrOrHash == nil { latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) blockNrOrHash = &latest @@ -400,12 +410,14 @@ func (b *Backend) getBlockHeight(ctx context.Context, blockNrOrHash rpc.BlockNum } func (b *Backend) getHeader(blockNumber *big.Int) *ethtypes.Header { + zeroExcessBlobGas := uint64(0) header := ðtypes.Header{ - Difficulty: common.Big0, - Number: blockNumber, - BaseFee: b.keeper.GetBaseFeePerGas(b.ctxProvider(LatestCtxHeight)).BigInt(), - GasLimit: b.config.GasCap, - Time: uint64(time.Now().Unix()), + Difficulty: common.Big0, + Number: blockNumber, + BaseFee: b.keeper.GetBaseFeePerGas(b.ctxProvider(LatestCtxHeight)).BigInt(), + GasLimit: b.config.GasCap, + Time: uint64(time.Now().Unix()), + ExcessBlobGas: &zeroExcessBlobGas, } number := blockNumber.Int64() block, err := blockByNumber(context.Background(), b.tmClient, &number) diff --git a/evmrpc/simulate_test.go b/evmrpc/simulate_test.go index b626ba637..5375722f6 100644 --- a/evmrpc/simulate_test.go +++ b/evmrpc/simulate_test.go @@ -132,6 +132,31 @@ func TestCall(t *testing.T) { Ctx = Ctx.WithBlockHeight(8) } +func TestEthCallHighAmount(t *testing.T) { + Ctx = Ctx.WithBlockHeight(1) + _, from := testkeeper.MockAddressPair() + _, to := testkeeper.MockAddressPair() + txArgs := map[string]interface{}{ + "from": from.Hex(), + "to": to.Hex(), + "value": "0x0", + "nonce": "0x2", + "chainId": fmt.Sprintf("%#x", EVMKeeper.ChainID(Ctx)), + } + + overrides := map[string]map[string]interface{}{ + from.Hex(): {"balance": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"}, + } + resObj := sendRequestGood(t, "call", txArgs, "latest", overrides) + fmt.Println("resObj = ", resObj) + errMap := resObj["error"].(map[string]interface{}) + result := errMap["message"] + fmt.Println("res = ", result) + require.Equal(t, result, "error: balance override overflow") + + Ctx = Ctx.WithBlockHeight(8) +} + func TestNewRevertError(t *testing.T) { err := evmrpc.NewRevertError(&core.ExecutionResult{}) require.NotNil(t, err) diff --git a/evmrpc/subscribe.go b/evmrpc/subscribe.go index f7b2bbe0b..35c8e2c3c 100644 --- a/evmrpc/subscribe.go +++ b/evmrpc/subscribe.go @@ -144,7 +144,10 @@ func (a *SubscriptionAPI) Logs(ctx context.Context, filter *filters.FilterCriter if !supported { return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported } - + // create empty filter if filter does not exist + if filter == nil { + filter = &filters.FilterCriteria{} + } rpcSub := notifier.CreateSubscription() if filter.BlockHash != nil { diff --git a/evmrpc/subscribe_test.go b/evmrpc/subscribe_test.go index f64e44fc8..effaf5fc3 100644 --- a/evmrpc/subscribe_test.go +++ b/evmrpc/subscribe_test.go @@ -83,6 +83,24 @@ func TestSubscribeNewHeads(t *testing.T) { } } +func TestSubscribeEmptyLogs(t *testing.T) { + t.Parallel() + recvCh, done := sendWSRequestGood(t, "subscribe", "logs") + defer func() { done <- struct{}{} }() + + timer := time.NewTimer(2 * time.Second) + + // just testing to see that we don't crash when no params are provided + for { + select { + case _ = <-recvCh: + return + case <-timer.C: + t.Fatal("No message received within 5 seconds") + } + } +} + func TestSubscribeNewLogs(t *testing.T) { t.Parallel() data := map[string]interface{}{ diff --git a/go.mod b/go.mod index ce783d759..16142d8af 100644 --- a/go.mod +++ b/go.mod @@ -42,6 +42,7 @@ require ( go.opentelemetry.io/otel/trace v1.9.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/sync v0.7.0 + golang.org/x/text v0.15.0 golang.org/x/time v0.3.0 google.golang.org/genproto/googleapis/api v0.0.0-20240513163218-0867130af1f8 google.golang.org/grpc v1.64.0 @@ -318,7 +319,6 @@ require ( golang.org/x/net v0.25.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/term v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect golang.org/x/tools v0.21.0 // indirect google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240513163218-0867130af1f8 // indirect @@ -344,17 +344,17 @@ require ( ) replace ( - github.com/CosmWasm/wasmd => github.com/sei-protocol/sei-wasmd v0.2.0 + github.com/CosmWasm/wasmd => github.com/sei-protocol/sei-wasmd v0.2.3 github.com/confio/ics23/go => github.com/cosmos/cosmos-sdk/ics23/go v0.8.0 - github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.3.26 + github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.3.31 github.com/cosmos/iavl => github.com/sei-protocol/sei-iavl v0.1.9 - github.com/cosmos/ibc-go/v3 => github.com/sei-protocol/sei-ibc-go/v3 v3.3.1 + github.com/cosmos/ibc-go/v3 => github.com/sei-protocol/sei-ibc-go/v3 v3.3.2 github.com/ethereum/go-ethereum => github.com/sei-protocol/go-ethereum v1.13.5-sei-22 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/sei-protocol/sei-db => github.com/sei-protocol/sei-db v0.0.40 // Latest goleveldb is broken, we have to stick to this version github.com/syndtr/goleveldb => github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 - github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.3.4 + github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.3.6 github.com/tendermint/tm-db => github.com/sei-protocol/tm-db v0.0.4 google.golang.org/grpc => google.golang.org/grpc v1.33.2 ) diff --git a/go.sum b/go.sum index 8d13fd510..d35f21e68 100644 --- a/go.sum +++ b/go.sum @@ -1347,20 +1347,20 @@ github.com/sei-protocol/go-ethereum v1.13.5-sei-22 h1:t/m1qXER+DEMrcpqgoYmUxifkA github.com/sei-protocol/go-ethereum v1.13.5-sei-22/go.mod h1:kcRZmuzRn1lVejiFNTz4l4W7imnpq1bDAnuKS/RyhbQ= github.com/sei-protocol/goutils v0.0.2 h1:Bfa7Sv+4CVLNM20QcpvGb81B8C5HkQC/kW1CQpIbXDA= github.com/sei-protocol/goutils v0.0.2/go.mod h1:iYE2DuJfEnM+APPehr2gOUXfuLuPsVxorcDO+Tzq9q8= -github.com/sei-protocol/sei-cosmos v0.3.26 h1:brYESCnbYI7gr/O8QEHxIyntZrIZp4ONA7m0xfDn6eI= -github.com/sei-protocol/sei-cosmos v0.3.26/go.mod h1:og/KbejR/zSQ8otapODEDU9zYNhFSUDbq9+tgeYePyU= -github.com/sei-protocol/sei-db v0.0.39 h1:/XwwlObPhWnX8zH8GDbDvyn+a/K2911HZlmlBZzN+gQ= -github.com/sei-protocol/sei-db v0.0.39/go.mod h1:F/ZKZA8HJPcUzSZPA8yt6pfwlGriJ4RDR4eHKSGLStI= +github.com/sei-protocol/sei-cosmos v0.3.31 h1:8qnubgQd83F2/Pxx5DmNH2vnl1XtTOAFbW44cEHbeCo= +github.com/sei-protocol/sei-cosmos v0.3.31/go.mod h1:og/KbejR/zSQ8otapODEDU9zYNhFSUDbq9+tgeYePyU= +github.com/sei-protocol/sei-db v0.0.40 h1:s6B3u9u0r2Ypd67P8Lrz2IR/QU/FXwtS2X/fnYEix2g= +github.com/sei-protocol/sei-db v0.0.40/go.mod h1:F/ZKZA8HJPcUzSZPA8yt6pfwlGriJ4RDR4eHKSGLStI= github.com/sei-protocol/sei-iavl v0.1.9 h1:y4mVYftxLNRs6533zl7N0/Ch+CzRQc04JDfHolIxgBE= github.com/sei-protocol/sei-iavl v0.1.9/go.mod h1:7PfkEVT5dcoQE+s/9KWdoXJ8VVVP1QpYYPLdxlkSXFk= -github.com/sei-protocol/sei-ibc-go/v3 v3.3.1 h1:BPG9LWe27x3SATpY9nj8JPe+0igyKyrcpB0z2ZvdcXQ= -github.com/sei-protocol/sei-ibc-go/v3 v3.3.1/go.mod h1:VwB/vWu4ysT5DN2aF78d17LYmx3omSAdq6gpKvM7XRA= -github.com/sei-protocol/sei-tendermint v0.3.4 h1:pAMXB2Cd0/rmmEkPgcEdIEjw7k64K7+cR2/2IuWBmM4= -github.com/sei-protocol/sei-tendermint v0.3.4/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= +github.com/sei-protocol/sei-ibc-go/v3 v3.3.2 h1:BaMZ6gjwqe3R/5dLmcJ1TkSZ3omcWy2TjaAZAeOJH44= +github.com/sei-protocol/sei-ibc-go/v3 v3.3.2/go.mod h1:VwB/vWu4ysT5DN2aF78d17LYmx3omSAdq6gpKvM7XRA= +github.com/sei-protocol/sei-tendermint v0.3.6 h1:bvvyWHyJcdCo6+b5Da8p9STyC+7tSNKAI9XPQsYgBuU= +github.com/sei-protocol/sei-tendermint v0.3.6/go.mod h1:4LSlJdhl3nf3OmohliwRNUFLOB1XWlrmSodrIP7fLh4= github.com/sei-protocol/sei-tm-db v0.0.5 h1:3WONKdSXEqdZZeLuWYfK5hP37TJpfaUa13vAyAlvaQY= github.com/sei-protocol/sei-tm-db v0.0.5/go.mod h1:Cpa6rGyczgthq7/0pI31jys2Fw0Nfrc+/jKdP1prVqY= -github.com/sei-protocol/sei-wasmd v0.2.0 h1:DiR5u7ZRtRKMYjvGPsH+/nMnJAprcFovbaITLf1Et0Y= -github.com/sei-protocol/sei-wasmd v0.2.0/go.mod h1:EnQkqvUA3tYpdgXjqatHK8ym9LCm1z+lM7XMqR9SA3o= +github.com/sei-protocol/sei-wasmd v0.2.3 h1:txB7LIx4Luh7+fxVN4/PiHEAjYnkutKyrpsuIFW8lmA= +github.com/sei-protocol/sei-wasmd v0.2.3/go.mod h1:EnQkqvUA3tYpdgXjqatHK8ym9LCm1z+lM7XMqR9SA3o= github.com/sei-protocol/tm-db v0.0.4 h1:7Y4EU62Xzzg6wKAHEotm7SXQR0aPLcGhKHkh3qd0tnk= github.com/sei-protocol/tm-db v0.0.4/go.mod h1:PWsIWOTwdwC7Ow/GUvx8HgUJTO691pBuorIQD8JvwAs= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= diff --git a/integration_test/dex_module/cancel_order_test.yaml b/integration_test/dex_module/cancel_order_test.yaml new file mode 100644 index 000000000..31496bd87 --- /dev/null +++ b/integration_test/dex_module/cancel_order_test.yaml @@ -0,0 +1,25 @@ +- name: Test cancel a placed order and query the cancelled order + inputs: + # Get contract address, this requires contract already deployed + - cmd: tail -1 integration_test/contracts/mars-addr.txt + env: CONTRACT_ADDR + # Prepare parameter to first place the order + - cmd: echo "LONG?1.01?5?SEI?ATOM?LIMIT?{\"leverage\":\"1\",\"position_effect\":\"Open\"}" + env: PARAMS + # Place an order and set ORDER_ID + - cmd: printf "12345678\n" | seid tx dex place-orders $CONTRACT_ADDR $PARAMS --amount=1000000000usei -y --from=admin --chain-id=sei --fees=1000000usei --gas=500000 --broadcast-mode=block --output json|jq -M -r ".logs[].events[].attributes[] | select(.key == \"order_id\").value" + env: ORDER_ID + # Prepare parameter to cancel the placed order + - cmd: echo $ORDER_ID"?LONG?1.01?SEI?ATOM" + env: PARAMS + # Cancel the order + - cmd: printf "12345678\n" | seid tx dex cancel-orders $CONTRACT_ADDR $PARAMS -y --from=admin --chain-id=sei --fees=1000000usei --gas=5000000 --broadcast-mode=block --output json + env: RES + - cmd: printf "12345678\n" | seid keys show admin --output json |jq -r .address + env: ADMIN_ADDR + # Query the order by id + - cmd: seid q dex get-orders $CONTRACT_ADDR $ADMIN_ADDR --output json |jq ".[] | length" + env: NUMORDER + verifiers: + - type: eval + expr: NUMORDER == 4 # placed from the place_order test diff --git a/integration_test/dex_module/place_order_test.yaml b/integration_test/dex_module/place_order_test.yaml new file mode 100644 index 000000000..168d4080c --- /dev/null +++ b/integration_test/dex_module/place_order_test.yaml @@ -0,0 +1,46 @@ +- name: Test placing a new order and query the placed order + inputs: + # Get contract address, this requires contract already deployed + - cmd: tail -1 integration_test/contracts/mars-addr.txt + env: CONTRACT_ADDR + # Prepare parameter + - cmd: echo "LONG?1.01?5?SEI?ATOM?LIMIT?{\"leverage\":\"1\",\"position_effect\":\"Open\"}" + env: PARAMS + # Place an order and set ORDER_ID + - cmd: printf "12345678\n" | seid tx dex place-orders $CONTRACT_ADDR $PARAMS --amount=1000000000usei -y --from=admin --chain-id=sei --fees=1000000usei --gas=500000 --broadcast-mode=block --output json|jq -M -r ".logs[].events[].attributes[] | select(.key == \"order_id\").value" + env: ORDER_ID + # Query the order by id + - cmd: seid q dex get-orders-by-id $CONTRACT_ADDR SEI ATOM $ORDER_ID --output json |jq .order.status + env: RESULT + verifiers: + # Order ids should be greater or equal to 0 + - type: eval + expr: ORDER_ID >= 0 + # Order status should be something like PLACED + - type: regex + result: RESULT + expr: '^.*PLACED.*' + +- name: Test place multiple orders should give the correct asset denom + inputs: + # Get contract address, this requires contract already deployed + - cmd: tail -1 integration_test/contracts/mars-addr.txt + env: CONTRACT_ADDR + # Get admin account address + - cmd: printf "12345678\n" | seid keys show admin --output json |jq -r .address + env: ADMIN_ADDR + - cmd: seid q dex get-orders $CONTRACT_ADDR $ADMIN_ADDR --output json |jq ".[] | length" + env: ORDER_COUNT_BEFORE + # Prepare parameter + - cmd: echo "LONG?1.0?10?usei?uatom?LIMIT? LONG?3.0?3000?usei?uatomatomatom?LIMIT? LONG?3.0?1000?usei?uatomatom?LIMIT?" + env: PARAMS + # Place 3 orders + - cmd: printf "12345678\n" | seid tx dex place-orders $CONTRACT_ADDR $PARAMS --amount=1000000000usei -y --from=admin --chain-id=sei --fees=1000000usei --gas=500000 --broadcast-mode=block --output json| jq .code + + # Query all the orders + - cmd: seid q dex get-orders $CONTRACT_ADDR $ADMIN_ADDR --output json |jq ".[] | length" + env: ORDER_COUNT_AFTER + verifiers: + # Verify we should only see 3 orders + - type: eval + expr: ( ORDER_COUNT_AFTER - ORDER_COUNT_BEFORE ) == 3 diff --git a/integration_test/staking_module/staking_test.yaml b/integration_test/staking_module/staking_test.yaml index 370e518d4..8b07e1250 100644 --- a/integration_test/staking_module/staking_test.yaml +++ b/integration_test/staking_module/staking_test.yaml @@ -83,7 +83,7 @@ - cmd: seid q staking validator $SEI_NODE_1_VAL_ADDR --output json | jq -r ".tokens" env: BEFORE_STAKED_TOKENS - - cmd: printf "12345678\n" | seid tx staking unbond $SEI_NODE_1_VAL_ADDR 1sei --fees 2000usei --from admin -b block -y --output json | jq -r ".code" + - cmd: printf "12345678\n" | seid tx staking unbond $SEI_NODE_1_VAL_ADDR 1sei --fees 4000usei --gas 400000 --from admin -b block -y --output json | jq -r ".code" env: DELEGATE_RESPONSE_CODE # state after staking diff --git a/loadtest/main.go b/loadtest/main.go index 938b19061..1b094892d 100644 --- a/loadtest/main.go +++ b/loadtest/main.go @@ -39,6 +39,7 @@ import ( "github.com/sei-protocol/sei-chain/app" "github.com/sei-protocol/sei-chain/utils/metrics" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" tokenfactorytypes "github.com/sei-protocol/sei-chain/x/tokenfactory/types" ) @@ -329,6 +330,10 @@ func (c *LoadTestClient) generateMessage(key cryptotypes.PrivKey, msgType string } switch msgType { + case Vortex: + price := config.PriceDistr.Sample() + quantity := config.QuantityDistr.Sample() + msgs = c.generateVortexOrder(config, key, config.WasmMsgTypes.Vortex.NumOrdersPerTx, price, quantity) case WasmMintNft: contract := config.WasmMsgTypes.MintNftType.ContractAddr // TODO: Potentially just hard code the Funds amount here @@ -398,6 +403,21 @@ func (c *LoadTestClient) generateMessage(key cryptotypes.PrivKey, msgType string signer = adminKey gas = 10000000 fee = 1000000 + case Dex: + price := config.PriceDistr.Sample() + quantity := config.QuantityDistr.Sample() + contract := config.ContractDistr.Sample() + orderPlacements := generateDexOrderPlacements(config, key, msgPerTx, price, quantity) + amount, err := sdk.ParseCoinsNormalized(fmt.Sprintf("%d%s", price.Mul(quantity).Ceil().RoundInt64(), "usei")) + if err != nil { + panic(err) + } + msgs = []sdk.Msg{&dextypes.MsgPlaceOrders{ + Creator: sdk.AccAddress(key.PubKey().Address()).String(), + Orders: orderPlacements, + ContractAddr: contract, + Funds: amount, + }} case Staking: delegatorAddr := sdk.AccAddress(key.PubKey().Address()).String() chosenValidator := c.Validators[r.Intn(len(c.Validators))].OperatorAddress @@ -464,6 +484,42 @@ func (c *LoadTestClient) generateMessage(key cryptotypes.PrivKey, msgType string Amount: sdk.NewInt(amountUsei), }), }} + case FailureDexMalformed: + price := config.PriceDistr.InvalidSample() + quantity := config.QuantityDistr.InvalidSample() + contract := config.ContractDistr.Sample() + orderPlacements := generateDexOrderPlacements(config, key, msgPerTx, price, quantity) + amount, err := sdk.ParseCoinsNormalized(fmt.Sprintf("%d%s", price.Mul(quantity).Ceil().RoundInt64(), "usei")) + if err != nil { + panic(err) + } + msgs = []sdk.Msg{&dextypes.MsgPlaceOrders{ + Creator: sdk.AccAddress(key.PubKey().Address()).String(), + Orders: orderPlacements, + ContractAddr: contract, + Funds: amount, + }} + case FailureDexInvalid: + price := config.PriceDistr.Sample() + quantity := config.QuantityDistr.Sample() + contract := config.ContractDistr.Sample() + orderPlacements := generateDexOrderPlacements(config, key, msgPerTx, price, quantity) + var amountUsei int64 + if r.Float64() < 0.5 { + amountUsei = 10000 * price.Mul(quantity).Ceil().RoundInt64() + } else { + amountUsei = 0 + } + amount, err := sdk.ParseCoinsNormalized(fmt.Sprintf("%d%s", amountUsei, "usei")) + if err != nil { + panic(err) + } + msgs = []sdk.Msg{&dextypes.MsgPlaceOrders{ + Creator: sdk.AccAddress(key.PubKey().Address()).String(), + Orders: orderPlacements, + ContractAddr: contract, + Funds: amount, + }} case WasmOccIteratorWrite: // generate some values for indices 1-100 indices := []int{} @@ -522,6 +578,51 @@ func (c *LoadTestClient) generateMessage(key cryptotypes.PrivKey, msgType string return msgs, false, signer, gas, int64(fee) } +func sampleDexOrderType(config Config) (orderType dextypes.OrderType) { + if len(config.MessageTypes) == 1 && config.MessageTypes[0] == "failure_bank_malformed" { + orderType = -1 + } else { + msgType := config.MsgTypeDistr.SampleDexMsgs() + switch msgType { + case Limit: + orderType = dextypes.OrderType_LIMIT + case Market: + orderType = dextypes.OrderType_MARKET + default: + panic(fmt.Sprintf("Unknown message type %s\n", msgType)) + } + } + return orderType +} + +func generateDexOrderPlacements(config Config, key cryptotypes.PrivKey, msgPerTx uint64, price sdk.Dec, quantity sdk.Dec) (orderPlacements []*dextypes.Order) { + orderType := sampleDexOrderType(config) + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + var direction dextypes.PositionDirection + if r.Float64() < 0.5 { + direction = dextypes.PositionDirection_LONG + } else { + direction = dextypes.PositionDirection_SHORT + } + + contract := config.ContractDistr.Sample() + for j := 0; j < int(msgPerTx); j++ { + orderPlacements = append(orderPlacements, &dextypes.Order{ + Account: sdk.AccAddress(key.PubKey().Address()).String(), + ContractAddr: contract, + PositionDirection: direction, + Price: price.Quo(FromMili), + Quantity: quantity.Quo(FromMili), + PriceDenom: "SEI", + AssetDenom: "ATOM", + OrderType: orderType, + Data: VortexData, + }) + } + return orderPlacements +} + func (c *LoadTestClient) generateStakingMsg(delegatorAddr string, chosenValidator string, srcAddr string) sdk.Msg { c.mtx.Lock() defer c.mtx.Unlock() @@ -562,6 +663,71 @@ func (c *LoadTestClient) generateStakingMsg(delegatorAddr string, chosenValidato return msg } +// generateVortexOrder generates Vortex order messages. If short order, creates a deposit message first +func (c *LoadTestClient) generateVortexOrder(config Config, key cryptotypes.PrivKey, numOrders int64, price sdk.Dec, quantity sdk.Dec) []sdk.Msg { + var msgs []sdk.Msg + contract := config.WasmMsgTypes.Vortex.ContractAddr + + r := rand.New(rand.NewSource(time.Now().UnixNano())) + // Randomly select Position Direction + var direction dextypes.PositionDirection + if r.Float64() < 0.5 { + direction = dextypes.PositionDirection_LONG + } else { + direction = dextypes.PositionDirection_SHORT + } + + orderType := sampleDexOrderType(config) + + // If placing short order on vortex, first deposit for buying power + if direction == dextypes.PositionDirection_SHORT { + // TODO: Considering depositing more up front when numOrders > 1 + amountDeposit, err := sdk.ParseCoinsNormalized(fmt.Sprintf("%d%s", price.Mul(quantity).Ceil().RoundInt64(), "usei")) + if err != nil { + panic(err) + } + vortexDeposit := &wasmtypes.MsgExecuteContract{ + Sender: sdk.AccAddress(key.PubKey().Address()).String(), + Contract: contract, + Msg: wasmtypes.RawContractMessage([]byte("{\"deposit\":{}}")), + Funds: amountDeposit, + } + msgs = append(msgs, vortexDeposit) + } + + // Create a MsgPlaceOrders with numOrders Orders + var orderPlacements []*dextypes.Order + for j := 0; j < int(numOrders); j++ { + vortexOrder := &dextypes.Order{ + Account: sdk.AccAddress(key.PubKey().Address()).String(), + ContractAddr: contract, + PositionDirection: direction, + Price: price.Quo(FromMili), + Quantity: quantity.Quo(FromMili), + PriceDenom: "SEI", + AssetDenom: "ATOM", + OrderType: orderType, + Data: VortexData, + } + orderPlacements = append(orderPlacements, vortexOrder) + } + + amount, err := sdk.ParseCoinsNormalized(fmt.Sprintf("%d%s", price.Mul(quantity).Ceil().RoundInt64(), "usei")) + if err != nil { + panic(err) + } + vortexOrderMsg := &dextypes.MsgPlaceOrders{ + Creator: sdk.AccAddress(key.PubKey().Address()).String(), + Orders: orderPlacements, + ContractAddr: contract, + Funds: amount, + } + + msgs = append(msgs, vortexOrderMsg) + + return msgs +} + // nolint func getLastHeight(blockchainEndpoint string) int { out, err := exec.Command("curl", blockchainEndpoint+"/blockchain").Output() diff --git a/occ_tests/utils/utils.go b/occ_tests/utils/utils.go index 877f92db1..e64772664 100644 --- a/occ_tests/utils/utils.go +++ b/occ_tests/utils/utils.go @@ -1,6 +1,7 @@ package utils import ( + "context" "crypto/ecdsa" "encoding/hex" "math/big" @@ -31,6 +32,9 @@ import ( "github.com/sei-protocol/sei-chain/app" utils2 "github.com/sei-protocol/sei-chain/utils" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" "github.com/sei-protocol/sei-chain/x/evm/config" types2 "github.com/sei-protocol/sei-chain/x/evm/types" minttypes "github.com/sei-protocol/sei-chain/x/mint/types" @@ -125,6 +129,7 @@ func NewTestContext(t *testing.T, testAccts []TestAcct, blockTime time.Time, wor }) testApp := wrapper.App ctx := wrapper.Ctx + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(dextypes.MemStoreKey)))) ctx = ctx.WithBlockHeader(tmproto.Header{Height: ctx.BlockHeader().Height, ChainID: ctx.BlockHeader().ChainID, Time: blockTime}) amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(1000000000000000)), sdk.NewCoin("uusdc", sdk.NewInt(1000000000000000))) bankkeeper := testApp.BankKeeper diff --git a/precompiles/wasmd/wasmd_test.go b/precompiles/wasmd/wasmd_test.go index b3eeb9de3..b653ed14d 100644 --- a/precompiles/wasmd/wasmd_test.go +++ b/precompiles/wasmd/wasmd_test.go @@ -68,7 +68,7 @@ func TestInstantiate(t *testing.T) { require.Equal(t, 2, len(outputs)) require.Equal(t, "sei1hrpna9v7vs3stzyd4z3xf00676kf78zpe2u5ksvljswn2vnjp3yslucc3n", outputs[0].(string)) require.Empty(t, outputs[1].([]byte)) - require.Equal(t, uint64(881127), g) + require.NotZero(t, g) amtsbz, err = sdk.NewCoins().MarshalJSON() require.Nil(t, err) @@ -91,7 +91,7 @@ func TestInstantiate(t *testing.T) { require.Equal(t, 2, len(outputs)) require.Equal(t, "sei1hrpna9v7vs3stzyd4z3xf00676kf78zpe2u5ksvljswn2vnjp3yslucc3n", outputs[0].(string)) require.Empty(t, outputs[1].([]byte)) - require.Equal(t, uint64(904183), g) + require.NotZero(t, g) // non-existent code ID args, _ = instantiateMethod.Inputs.Pack( @@ -164,7 +164,7 @@ func TestExecute(t *testing.T) { require.Nil(t, err) require.Equal(t, 1, len(outputs)) require.Equal(t, fmt.Sprintf("received test msg from %s with 1000usei", mockAddr.String()), string(outputs[0].([]byte))) - require.Equal(t, uint64(907386), g) + require.NotZero(t, g) require.Equal(t, int64(1000), testApp.BankKeeper.GetBalance(statedb.Ctx(), contractAddr, "usei").Amount.Int64()) amtsbz, err = sdk.NewCoins().MarshalJSON() @@ -253,7 +253,7 @@ func TestQuery(t *testing.T) { require.Nil(t, err) require.Equal(t, 1, len(outputs)) require.Equal(t, "{\"message\":\"query test\"}", string(outputs[0].([]byte))) - require.Equal(t, uint64(931712), g) + require.NotZero(t, g) // bad contract address args, _ = queryMethod.Inputs.Pack(mockAddr.String(), []byte("{\"info\":{}}")) @@ -316,7 +316,7 @@ func TestExecuteBatchOneMessage(t *testing.T) { require.Nil(t, err) require.Equal(t, 1, len(outputs)) require.Equal(t, fmt.Sprintf("received test msg from %s with 1000usei", mockAddr.String()), string((outputs[0].([][]byte))[0])) - require.Equal(t, uint64(907386), g) + require.NotZero(t, g) require.Equal(t, int64(1000), testApp.BankKeeper.GetBalance(statedb.Ctx(), contractAddr, "usei").Amount.Int64()) amtsbz, err = sdk.NewCoins().MarshalJSON() @@ -467,7 +467,7 @@ func TestExecuteBatchMultipleMessages(t *testing.T) { require.Equal(t, fmt.Sprintf("received test msg from %s with 1000usei", mockAddr.String()), string(parsedOutputs[0])) require.Equal(t, fmt.Sprintf("received test msg from %s with 1000usei", mockAddr.String()), string(parsedOutputs[1])) require.Equal(t, fmt.Sprintf("received test msg from %s with 1000usei", mockAddr.String()), string(parsedOutputs[2])) - require.Equal(t, uint64(726724), g) + require.NotZero(t, g) require.Equal(t, int64(3000), testApp.BankKeeper.GetBalance(statedb.Ctx(), contractAddr, "usei").Amount.Int64()) amtsbz2, err := sdk.NewCoins().MarshalJSON() @@ -494,7 +494,7 @@ func TestExecuteBatchMultipleMessages(t *testing.T) { require.Equal(t, fmt.Sprintf("received test msg from %s with", mockAddr.String()), string(parsedOutputs[0])) require.Equal(t, fmt.Sprintf("received test msg from %s with 1000usei", mockAddr.String()), string(parsedOutputs[1])) require.Equal(t, fmt.Sprintf("received test msg from %s with", mockAddr.String()), string(parsedOutputs[2])) - require.Equal(t, uint64(775245), g) + require.NotZero(t, g) require.Equal(t, int64(1000), testApp.BankKeeper.GetBalance(statedb.Ctx(), contractAddr, "usei").Amount.Int64()) // allowed delegatecall diff --git a/proto/dex/asset_list.proto b/proto/dex/asset_list.proto new file mode 100644 index 000000000..b80d54f71 --- /dev/null +++ b/proto/dex/asset_list.proto @@ -0,0 +1,23 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "cosmos/bank/v1beta1/bank.proto"; +import "gogoproto/gogo.proto"; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +message AssetIBCInfo { + string sourceChannel = 1 [(gogoproto.jsontag) = "source_channel"]; + string dstChannel = 2 [(gogoproto.jsontag) = "dst_channel"]; + string sourceDenom = 3 [(gogoproto.jsontag) = "source_denom"]; + string sourceChainID = 4 [(gogoproto.jsontag) = "source_chain_id"]; +} + +message AssetMetadata { + AssetIBCInfo ibcInfo = 1 [(gogoproto.jsontag) = "ibc_info"]; + string type_asset = 2 [(gogoproto.jsontag) = "type_asset"]; // Ex: cw20, ics20, erc20 + cosmos.bank.v1beta1.Metadata metadata = 3 [ + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "metadata" + ]; +} diff --git a/proto/dex/contract.proto b/proto/dex/contract.proto new file mode 100644 index 000000000..11d87ceb6 --- /dev/null +++ b/proto/dex/contract.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +message ContractInfo { + uint64 codeId = 1; + string contractAddr = 2; + bool needHook = 3; + bool needOrderMatching = 4; + repeated ContractDependencyInfo dependencies = 5; + int64 numIncomingDependencies = 6; +} + +message ContractInfoV2 { + uint64 codeId = 1; + string contractAddr = 2; + bool needHook = 3; + bool needOrderMatching = 4; + repeated ContractDependencyInfo dependencies = 5; + int64 numIncomingDependencies = 6; + string creator = 7; + uint64 rentBalance = 8; + bool suspended = 9; + string suspensionReason = 10; +} + +// suppose A is first registered and depends on X, then B is added and depends on X, +// and then C is added and depends on X, then A is the elder sibling to B and B is +// the younger sibling to A, and B is the elder sibling to C and C is the younger to B +message ContractDependencyInfo { + string dependency = 1; + string immediateElderSibling = 2; + string immediateYoungerSibling = 3; +} + +message LegacyContractInfo { + uint64 codeId = 1; + string contractAddr = 2; + bool needHook = 3; + bool needOrderMatching = 4; + repeated string dependentContractAddrs = 5; +} + +message DownsteamContracts { + repeated string contractAddrs = 1; +} \ No newline at end of file diff --git a/proto/dex/deposit.proto b/proto/dex/deposit.proto new file mode 100644 index 000000000..5f09e2ffa --- /dev/null +++ b/proto/dex/deposit.proto @@ -0,0 +1,21 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +message DepositInfoEntry { + string creator = 1 [ + (gogoproto.jsontag) = "creator" + ]; + string denom = 2 [ + (gogoproto.jsontag) = "denom" + ]; + string amount = 3 [ + (gogoproto.moretags) = "yaml:\"amount\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "amount" + ]; +} diff --git a/proto/dex/enums.proto b/proto/dex/enums.proto new file mode 100644 index 000000000..0eb89c5c0 --- /dev/null +++ b/proto/dex/enums.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +enum PositionDirection { + LONG = 0; + SHORT = 1; +} + +enum PositionEffect { + OPEN = 0; + CLOSE = 1; +} + +enum OrderType { + LIMIT = 0; + MARKET = 1; + FOKMARKET = 3; // fill-or-kill market order + FOKMARKETBYVALUE = 4; // fill-or-kill market by value order + STOPLOSS = 5; + STOPLIMIT = 6; +} + +enum Unit { + STANDARD = 0; + MILLI = 1; + MICRO = 2; + NANO = 3; +} + +enum OrderStatus { + PLACED = 0; + FAILED_TO_PLACE = 1; + CANCELLED = 2; + FULFILLED = 3; +} + +enum CancellationInitiator { + USER = 0; + LIQUIDATED = 1; +} diff --git a/proto/dex/genesis.proto b/proto/dex/genesis.proto new file mode 100644 index 000000000..5e46bc73a --- /dev/null +++ b/proto/dex/genesis.proto @@ -0,0 +1,37 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; +import "dex/params.proto"; +import "dex/long_book.proto"; +import "dex/short_book.proto"; +import "dex/order.proto"; +import "dex/contract.proto"; +import "dex/pair.proto"; +import "dex/price.proto"; +// this line is used by starport scaffolding # genesis/proto/import + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +// GenesisState defines the dex module's genesis state. +message GenesisState { + Params params = 1 [(gogoproto.nullable) = false]; + repeated ContractState contractState = 2 [(gogoproto.nullable) = false]; + uint64 lastEpoch = 3; + // this line is used by starport scaffolding # genesis/proto/state +} + +message ContractState { + ContractInfoV2 contractInfo = 1 [(gogoproto.nullable) = false]; + repeated LongBook longBookList = 2 [(gogoproto.nullable) = false]; + repeated ShortBook shortBookList = 3 [(gogoproto.nullable) = false]; + repeated Order triggeredOrdersList = 4 [(gogoproto.nullable) = false]; + repeated Pair pairList = 5 [(gogoproto.nullable) = false]; + repeated ContractPairPrices priceList = 6 [(gogoproto.nullable) = false]; + uint64 nextOrderId = 7; +} + +message ContractPairPrices { + Pair pricePair = 1 [(gogoproto.nullable) = false]; + repeated Price prices = 2; +} diff --git a/proto/dex/gov.proto b/proto/dex/gov.proto new file mode 100644 index 000000000..4fa4d04e7 --- /dev/null +++ b/proto/dex/gov.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; +import "dex/asset_list.proto"; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +// AddAssetMetadataProposal is a gov Content type for adding a new asset +// to the dex module's asset list. +message AddAssetMetadataProposal { + option (gogoproto.equal) = false; + option (gogoproto.goproto_getters) = false; + option (gogoproto.goproto_stringer) = false; + + string title = 1 [ (gogoproto.moretags) = "yaml:\"title\"" ]; + string description = 2 [ (gogoproto.moretags) = "yaml:\"description\"" ]; + repeated AssetMetadata assetList = 3 [ + (gogoproto.moretags) = "yaml:\"asset_list\"", + (gogoproto.nullable) = false + ]; +} diff --git a/proto/dex/long_book.proto b/proto/dex/long_book.proto new file mode 100644 index 000000000..c9b810f23 --- /dev/null +++ b/proto/dex/long_book.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; +import "dex/order_entry.proto"; +import "gogoproto/gogo.proto"; + +message LongBook { + string price = 1 [ + (gogoproto.moretags) = "yaml:\"price\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "price" + ]; + OrderEntry entry = 2 [ + (gogoproto.jsontag) = "entry" + ]; + +} \ No newline at end of file diff --git a/proto/dex/match_result.proto b/proto/dex/match_result.proto new file mode 100644 index 000000000..c6d76c807 --- /dev/null +++ b/proto/dex/match_result.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; +import "dex/order.proto"; +import "dex/settlement.proto"; +import "gogoproto/gogo.proto"; + +message MatchResult { + int64 height = 1 [(gogoproto.jsontag) = "height"]; + string contractAddr = 2 [(gogoproto.jsontag) = "contract_address"]; + repeated Order orders = 3 [(gogoproto.jsontag) = "orders"]; + repeated SettlementEntry settlements = 4 [(gogoproto.jsontag) = "settlements"]; + repeated Cancellation cancellations = 5 [(gogoproto.jsontag) = "cancellations"]; +} \ No newline at end of file diff --git a/proto/dex/order.proto b/proto/dex/order.proto new file mode 100644 index 000000000..8b366eb6e --- /dev/null +++ b/proto/dex/order.proto @@ -0,0 +1,108 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; +import "dex/enums.proto"; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +message Order { + uint64 id = 1 [ + (gogoproto.jsontag) = "id", + (gogoproto.nullable) = true + ]; + OrderStatus status = 2 [ + (gogoproto.jsontag) = "status", + (gogoproto.nullable) = true + ]; + string account = 3 [ + (gogoproto.jsontag) = "account", + (gogoproto.nullable) = true + ]; + string contractAddr = 4 [ + (gogoproto.jsontag) = "contract_address", + (gogoproto.nullable) = true + ]; + string price = 5 [ + (gogoproto.moretags) = "yaml:\"price\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "price" + ]; + string quantity = 6 [ + (gogoproto.moretags) = "yaml:\"quantity\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "quantity" + ]; + string priceDenom = 7 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 8 [ + (gogoproto.jsontag) = "asset_denom" + ]; + OrderType orderType = 9 [ + (gogoproto.jsontag) = "order_type" + ]; + PositionDirection positionDirection = 10 [ + (gogoproto.jsontag) = "position_direction" + ]; + string data = 11 [ + (gogoproto.jsontag) = "data" + ]; + string statusDescription = 12 [ + (gogoproto.jsontag) = "status_description" + ]; + string nominal = 13 [ + (gogoproto.moretags) = "yaml:\"nominal\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (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 { + uint64 id = 1 [ + (gogoproto.jsontag) = "id" + ]; + CancellationInitiator initiator = 2 [ + (gogoproto.jsontag) = "initiator" + ]; + string creator = 3 [ + (gogoproto.jsontag) = "creator", + (gogoproto.nullable) = true + ]; + string contractAddr = 4 [ + (gogoproto.jsontag) = "contract_address" + ]; + string priceDenom = 5 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 6 [ + (gogoproto.jsontag) = "asset_denom" + ]; + PositionDirection positionDirection = 7 [ + (gogoproto.jsontag) = "position_direction" + ]; + string price = 8 [ + (gogoproto.moretags) = "yaml:\"price\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "price" + ]; +} + +message ActiveOrders { + repeated uint64 ids = 1 [ + (gogoproto.jsontag) = "ids" + ]; +} diff --git a/proto/dex/order_entry.proto b/proto/dex/order_entry.proto new file mode 100644 index 000000000..a35d8075f --- /dev/null +++ b/proto/dex/order_entry.proto @@ -0,0 +1,46 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +message OrderEntry { + + string price = 1 [ + (gogoproto.moretags) = "yaml:\"price\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "price" + ]; + string quantity = 2 [ + (gogoproto.moretags) = "yaml:\"quantity\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "quantity" + ]; + repeated Allocation allocations = 3 [ + (gogoproto.jsontag) = "allocations" + ]; + string priceDenom = 4 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 5 [ + (gogoproto.jsontag) = "asset_denom" + ]; +} + +message Allocation { + uint64 orderId = 1 [ + (gogoproto.jsontag) = "order_id" + ]; + string quantity = 2 [ + (gogoproto.moretags) = "yaml:\"quantity\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "quantity" + ]; + string account = 3 [ + (gogoproto.jsontag) = "account" + ]; +} diff --git a/proto/dex/pair.proto b/proto/dex/pair.proto new file mode 100644 index 000000000..721e459ea --- /dev/null +++ b/proto/dex/pair.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +message Pair { + string priceDenom = 1 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 2 [ + (gogoproto.jsontag) = "asset_denom" + ]; + string priceTicksize = 3 [ + (gogoproto.jsontag) = "price_tick_size", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = true + ]; + string quantityTicksize = 4 [ + (gogoproto.jsontag) = "quantity_tick_size", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = true + ]; +} + +message BatchContractPair { + string contractAddr = 1 [(gogoproto.jsontag) = "contract_addr"]; + repeated Pair pairs = 2 [(gogoproto.jsontag) = "pairs"]; +} diff --git a/proto/dex/params.proto b/proto/dex/params.proto new file mode 100644 index 000000000..de96e4790 --- /dev/null +++ b/proto/dex/params.proto @@ -0,0 +1,70 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +// Params defines the parameters for the module. +message Params { + option (gogoproto.equal) = true; + option (gogoproto.goproto_stringer) = false; + + uint64 price_snapshot_retention = 1 [ + (gogoproto.moretags) = "yaml:\"price_snapshot_retention\"", + (gogoproto.jsontag) = "price_snapshot_retention" + ]; + string sudo_call_gas_price = 2 [ + (gogoproto.jsontag) = "sudo_call_gas_price", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false + ]; + uint64 begin_block_gas_limit = 3 [ + (gogoproto.jsontag) = "begin_block_gas_limit", + (gogoproto.moretags) = "yaml:\"begin_block_gas_limit\"" + ]; + uint64 end_block_gas_limit = 4 [ + (gogoproto.jsontag) = "end_block_gas_limit", + (gogoproto.moretags) = "yaml:\"end_block_gas_limit\"" + ]; + uint64 default_gas_per_order = 5 [ + (gogoproto.jsontag) = "default_gas_per_order", + (gogoproto.moretags) = "yaml:\"default_gas_per_order\"" + ]; + uint64 default_gas_per_cancel = 6 [ + (gogoproto.jsontag) = "default_gas_per_cancel", + (gogoproto.moretags) = "yaml:\"default_gas_per_cancel\"" + ]; + uint64 min_rent_deposit = 7 [ + (gogoproto.jsontag) = "min_rent_deposit", + (gogoproto.moretags) = "yaml:\"min_rent_deposit\"" + ]; + uint64 gas_allowance_per_settlement = 8 [ + (gogoproto.jsontag) = "gas_allowance_per_settlement", + (gogoproto.moretags) = "yaml:\"gas_allowance_per_settlement\"" + ]; + uint64 min_processable_rent = 9 [ + (gogoproto.jsontag) = "min_processable_rent", + (gogoproto.moretags) = "yaml:\"min_processable_rent\"" + ]; + uint64 order_book_entries_per_load = 10 [ + (gogoproto.jsontag) = "order_book_entries_per_load", + (gogoproto.moretags) = "yaml:\"order_book_entries_per_load\"" + ]; + uint64 contract_unsuspend_cost = 11 [ + (gogoproto.jsontag) = "contract_unsuspend_cost", + (gogoproto.moretags) = "yaml:\"contract_unsuspend_cost\"" + ]; + uint64 max_order_per_price = 12 [ + (gogoproto.jsontag) = "max_order_per_price", + (gogoproto.moretags) = "yaml:\"max_order_per_price\"" + ]; + uint64 max_pairs_per_contract = 13 [ + (gogoproto.jsontag) = "max_pairs_per_contract", + (gogoproto.moretags) = "yaml:\"max_pairs_per_contract\"" + ]; + uint64 default_gas_per_order_data_byte = 14 [ + (gogoproto.jsontag) = "default_gas_per_order_data_byte", + (gogoproto.moretags) = "yaml:\"default_gas_per_order_data_byte\"" + ]; +} diff --git a/proto/dex/price.proto b/proto/dex/price.proto new file mode 100644 index 000000000..65b544717 --- /dev/null +++ b/proto/dex/price.proto @@ -0,0 +1,52 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; +import "dex/pair.proto"; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +message Price { + + uint64 snapshotTimestampInSeconds = 1 [ + (gogoproto.jsontag) = "snapshot_timestamp_in_seconds" + ]; + string price = 2 [ + (gogoproto.moretags) = "yaml:\"price\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "price" + ]; + Pair pair = 3 [ + (gogoproto.jsontag) = "pair" + ]; +} + +message PriceCandlestick { + uint64 beginTimestamp = 1 [ + (gogoproto.jsontag) = "begin_timestamp" + ]; + uint64 endTimestamp = 2 [ + (gogoproto.jsontag) = "end_timestamp" + ]; + string open = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "open" + ]; + string high = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "high" + ]; + string low = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "low" + ]; + string close = 6 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "close" + ]; + string volume = 7 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "volume" + ]; +} diff --git a/proto/dex/query.proto b/proto/dex/query.proto new file mode 100644 index 000000000..4aeccce56 --- /dev/null +++ b/proto/dex/query.proto @@ -0,0 +1,401 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "dex/params.proto"; +import "dex/long_book.proto"; +import "dex/short_book.proto"; +import "dex/price.proto"; +import "dex/contract.proto"; +import "dex/twap.proto"; +import "dex/asset_list.proto"; +import "dex/pair.proto"; +import "dex/order.proto"; +import "dex/match_result.proto"; +import "dex/enums.proto"; +// this line is used by starport scaffolding # 1 + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +// Query defines the gRPC querier service. +service Query { + // Parameters queries the parameters of the module. + rpc Params(QueryParamsRequest) returns (QueryParamsResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/params"; + } + // Queries a LongBook by id. + rpc LongBook(QueryGetLongBookRequest) returns (QueryGetLongBookResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/long_book/{contractAddr}/{priceDenom}/{assetDenom}/{price}"; + } + + // Queries a list of LongBook items. + rpc LongBookAll(QueryAllLongBookRequest) returns (QueryAllLongBookResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/long_book/{contractAddr}/{priceDenom}/{assetDenom}"; + } + +// Queries a ShortBook by id. + rpc ShortBook(QueryGetShortBookRequest) returns (QueryGetShortBookResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/short_book/{contractAddr}/{priceDenom}/{assetDenom}/{price}"; + } + + // Queries a list of ShortBook items. + rpc ShortBookAll(QueryAllShortBookRequest) returns (QueryAllShortBookResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/short_book/{contractAddr}/{priceDenom}/{assetDenom}"; + } + + rpc GetPrice(QueryGetPriceRequest) returns (QueryGetPriceResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/get_price/{contractAddr}/{priceDenom}/{assetDenom}/{timestamp}"; + } + + rpc GetLatestPrice(QueryGetLatestPriceRequest) returns (QueryGetLatestPriceResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/get_latest_price/{contractAddr}/{priceDenom}/{assetDenom}"; + } + + rpc GetPrices(QueryGetPricesRequest) returns (QueryGetPricesResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/get_prices/{contractAddr}/{priceDenom}/{assetDenom}"; + } + + rpc GetTwaps(QueryGetTwapsRequest) returns (QueryGetTwapsResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/get_twaps/{contractAddr}/{lookbackSeconds}"; + } + + // Returns the metadata for a specified denom / display type + rpc AssetMetadata(QueryAssetMetadataRequest) returns (QueryAssetMetadataResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/asset_list/{denom}"; + } + + // Returns metadata for all the assets + rpc AssetList(QueryAssetListRequest) returns (QueryAssetListResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/asset_list"; + } + + // Returns all registered pairs for specified contract address + rpc GetRegisteredPairs(QueryRegisteredPairsRequest) returns (QueryRegisteredPairsResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/registered_pairs"; + } + + // Returns registered contract information + rpc GetRegisteredContract(QueryRegisteredContractRequest) returns (QueryRegisteredContractResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/registered_contract/{contractAddr}"; + } + + rpc GetOrders(QueryGetOrdersRequest) returns (QueryGetOrdersResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/get_orders/{contractAddr}/{account}"; + } + + rpc GetOrder(QueryGetOrderByIDRequest) returns (QueryGetOrderByIDResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/get_order_by_id/{contractAddr}/{priceDenom}/{assetDenom}/{id}"; + } + + rpc GetHistoricalPrices(QueryGetHistoricalPricesRequest) returns (QueryGetHistoricalPricesResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/get_historical_prices/{contractAddr}/{priceDenom}/{assetDenom}/{periodLengthInSeconds}/{numOfPeriods}"; + } + + rpc GetMarketSummary(QueryGetMarketSummaryRequest) returns (QueryGetMarketSummaryResponse) { + option (google.api.http).get = "/sei-protocol/seichain/dex/get_market_summary/{contractAddr}/{priceDenom}/{assetDenom}/{lookbackInSeconds}"; + } + + rpc GetOrderSimulation(QueryOrderSimulationRequest) returns (QueryOrderSimulationResponse) {} + + rpc GetMatchResult(QueryGetMatchResultRequest) returns (QueryGetMatchResultResponse) {} + + rpc GetOrderCount(QueryGetOrderCountRequest) returns (QueryGetOrderCountResponse) {} + +// this line is used by starport scaffolding # 2 +} + +// QueryParamsRequest is request type for the Query/Params RPC method. +message QueryParamsRequest {} + +// QueryParamsResponse is response type for the Query/Params RPC method. +message QueryParamsResponse { + // params holds all the parameters of this module. + Params params = 1 [(gogoproto.nullable) = false]; +} + +message QueryGetLongBookRequest { + string price = 1; + string contractAddr = 2; + string priceDenom = 3; + string assetDenom = 4; +} + +message QueryGetLongBookResponse { + LongBook LongBook = 1 [(gogoproto.nullable) = false]; +} + +message QueryAllLongBookRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; + string contractAddr = 2; + string priceDenom = 3; + string assetDenom = 4; +} + +message QueryAllLongBookResponse { + repeated LongBook LongBook = 1 [(gogoproto.nullable) = false]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +message QueryGetShortBookRequest { + string price = 1; + string contractAddr = 2; + string priceDenom = 3; + string assetDenom = 4; +} + +message QueryGetShortBookResponse { + ShortBook ShortBook = 1 [(gogoproto.nullable) = false]; +} + +message QueryAllShortBookRequest { + cosmos.base.query.v1beta1.PageRequest pagination = 1; + string contractAddr = 2; + string priceDenom = 3; + string assetDenom = 4; +} + +message QueryAllShortBookResponse { + repeated ShortBook ShortBook = 1 [(gogoproto.nullable) = false]; + cosmos.base.query.v1beta1.PageResponse pagination = 2; +} + +message QueryGetPricesRequest { + string priceDenom = 1; + string assetDenom = 2; + string contractAddr = 3; +} + +message QueryGetPricesResponse { + repeated Price prices = 1; +} + +message QueryGetPriceRequest { + string priceDenom = 1; + string assetDenom = 2; + string contractAddr = 3; + uint64 timestamp = 4; +} + +message QueryGetPriceResponse { + Price price = 1; + bool found = 2; +} + +message QueryGetLatestPriceRequest { + string priceDenom = 1 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 2 [ + (gogoproto.jsontag) = "asset_denom" + ]; + string contractAddr = 3 [ + (gogoproto.jsontag) = "contract_address" + ]; +} + +message QueryGetLatestPriceResponse { + Price price = 1; +} + +message QueryGetTwapsRequest { + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; + uint64 lookbackSeconds = 2 [ + (gogoproto.jsontag) = "lookback_seconds" + ]; + } + +message QueryGetTwapsResponse { + repeated Twap twaps = 1 [ + (gogoproto.jsontag) = "twaps" + ]; +} + +message QueryAssetListRequest {} + +message QueryAssetListResponse { + repeated AssetMetadata assetList = 1 [(gogoproto.nullable) = false]; +} + +message QueryAssetMetadataRequest { + string denom = 1; +} + +message QueryAssetMetadataResponse { + AssetMetadata metadata = 1; +} + +message QueryRegisteredPairsRequest { + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; +} + +message QueryRegisteredPairsResponse { + repeated Pair pairs = 1 [(gogoproto.nullable) = false]; +} + +message QueryRegisteredContractRequest { + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; +} + +message QueryRegisteredContractResponse { + ContractInfoV2 contract_info = 1; +} + +message QueryGetOrdersRequest{ + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; + string account = 2 [ + (gogoproto.jsontag) = "account" + ]; +} + +message QueryGetOrdersResponse { + repeated Order orders = 1 [ + (gogoproto.jsontag) = "orders" + ]; +} + +message QueryGetOrderByIDRequest{ + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; + string priceDenom = 2 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 3 [ + (gogoproto.jsontag) = "asset_denom" + ]; + uint64 id = 4 [ + (gogoproto.jsontag) = "id" + ]; +} + +message QueryGetOrderByIDResponse { + Order order = 1 [ + (gogoproto.jsontag) = "order" + ]; +} + +message QueryGetHistoricalPricesRequest { + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; + string priceDenom = 2 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 3 [ + (gogoproto.jsontag) = "asset_denom" + ]; + uint64 periodLengthInSeconds = 4 [ + (gogoproto.jsontag) = "period_length_in_seconds" + ]; + uint64 numOfPeriods = 5 [ + (gogoproto.jsontag) = "number_of_periods" + ]; +} + +message QueryGetHistoricalPricesResponse { + repeated PriceCandlestick prices = 1[ + (gogoproto.jsontag) = "prices" + ]; +} + +message QueryGetMarketSummaryRequest { + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; + string priceDenom = 2 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 3 [ + (gogoproto.jsontag) = "asset_denom" + ]; + uint64 lookbackInSeconds = 4 [ + (gogoproto.jsontag) = "lookback_in_seconds" + ]; +} + +message QueryGetMarketSummaryResponse{ + string totalVolume = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "total_volume" + ]; + string totalVolumeNotional = 2 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "total_volume_notional" + ]; + string highPrice = 3 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "high_price" + ]; + string lowPrice = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "low_price" + ]; + string lastPrice = 5 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "last_price" + ]; +} + +message QueryOrderSimulationRequest { + Order order = 1 [ + (gogoproto.jsontag) = "order" + ]; + string contractAddr = 2 [ + (gogoproto.jsontag) = "contract_address" + ]; +} + +message QueryOrderSimulationResponse { + string ExecutedQuantity = 1 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "executed_quantity" + ]; +} + +message QueryGetMatchResultRequest { + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; +} + +message QueryGetMatchResultResponse { + MatchResult result = 1 [ + (gogoproto.jsontag) = "result" + ]; +} + +message QueryGetOrderCountRequest { + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; + string priceDenom = 2 [ + (gogoproto.jsontag) = "price_denom" + ]; + string assetDenom = 3 [ + (gogoproto.jsontag) = "asset_denom" + ]; + string price = 4 [ + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.jsontag) = "price" + ]; + PositionDirection positionDirection = 5 [ + (gogoproto.jsontag) = "position_direction" + ]; +} + +message QueryGetOrderCountResponse { + uint64 count = 1 [ + (gogoproto.jsontag) = "count" + ]; +} +// this line is used by starport scaffolding # 3 diff --git a/proto/dex/settlement.proto b/proto/dex/settlement.proto new file mode 100644 index 000000000..8e5487ebd --- /dev/null +++ b/proto/dex/settlement.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; +import "gogoproto/gogo.proto"; + +message SettlementEntry { + string account = 1 [(gogoproto.jsontag) = "account"]; + string priceDenom = 2 [(gogoproto.jsontag) = "price_denom"]; + string assetDenom = 3 [(gogoproto.jsontag) = "asset_denom"]; + string quantity = 4 [ + (gogoproto.moretags) = "yaml:\"quantity\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "quantity" + ]; + string executionCostOrProceed = 5 [ + (gogoproto.moretags) = "yaml:\"execution_cost_or_proceed\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "execution_cost_or_proceed" + ]; + string expectedCostOrProceed = 6 [ + (gogoproto.moretags) = "yaml:\"expected_cost_or_proceed\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "expected_cost_or_proceed" + ]; + string positionDirection = 7 [(gogoproto.jsontag) = "position_direction"]; + string orderType = 8 [(gogoproto.jsontag) = "order_type"]; + uint64 orderId = 9 [(gogoproto.jsontag) = "order_id"]; + uint64 timestamp = 10 [(gogoproto.jsontag) = "timestamp"]; + uint64 height = 11 [(gogoproto.jsontag) = "height"]; + uint64 settlementId = 12 [(gogoproto.jsontag) = "settlement_id"]; +} + +message Settlements { + int64 epoch = 1 [(gogoproto.jsontag) = "epoch"]; + repeated SettlementEntry entries = 2 [(gogoproto.jsontag) = "entries"]; +} \ No newline at end of file diff --git a/proto/dex/short_book.proto b/proto/dex/short_book.proto new file mode 100644 index 000000000..b355c3cab --- /dev/null +++ b/proto/dex/short_book.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; +import "dex/order_entry.proto"; +import "gogoproto/gogo.proto"; + +message ShortBook { + string price = 1 [ + (gogoproto.moretags) = "yaml:\"price\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "price" + ]; + OrderEntry entry = 2 [ + (gogoproto.jsontag) = "entry" + ]; + +} \ No newline at end of file diff --git a/proto/dex/tick_size.proto b/proto/dex/tick_size.proto new file mode 100644 index 000000000..80eece546 --- /dev/null +++ b/proto/dex/tick_size.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; +import "dex/pair.proto"; +import "gogoproto/gogo.proto"; + +message TickSize { + Pair pair = 1 [ + (gogoproto.jsontag) = "pair" + ]; + string ticksize = 2 [ + (gogoproto.moretags) = "yaml:\"tick_size\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "tick_size" + ]; + string contractAddr = 3 [ + (gogoproto.moretags) = "yaml:\"tick_size\"", + (gogoproto.jsontag) = "contract_addr" + ]; +} \ No newline at end of file diff --git a/proto/dex/twap.proto b/proto/dex/twap.proto new file mode 100644 index 000000000..cca0836fb --- /dev/null +++ b/proto/dex/twap.proto @@ -0,0 +1,24 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "gogoproto/gogo.proto"; +import "dex/pair.proto"; + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + + +message Twap { + + Pair pair = 1 [ + (gogoproto.jsontag) = "pair" + ]; + string twap = 2 [ + (gogoproto.moretags) = "yaml:\"twap\"", + (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "twap" + ]; + uint64 lookbackSeconds = 3 [ + (gogoproto.jsontag) = "lookback_seconds" + ]; +} diff --git a/proto/dex/tx.proto b/proto/dex/tx.proto new file mode 100644 index 000000000..b21f5dde7 --- /dev/null +++ b/proto/dex/tx.proto @@ -0,0 +1,147 @@ +syntax = "proto3"; +package seiprotocol.seichain.dex; + +import "cosmos/base/v1beta1/coin.proto"; +import "gogoproto/gogo.proto"; +import "dex/contract.proto"; +import "dex/order.proto"; +import "dex/pair.proto"; +import "dex/tick_size.proto"; + +// this line is used by starport scaffolding # proto/tx/import + +option go_package = "github.com/sei-protocol/sei-chain/x/dex/types"; + +// Msg defines the Msg service. +service Msg { + rpc PlaceOrders(MsgPlaceOrders) returns (MsgPlaceOrdersResponse); + rpc CancelOrders(MsgCancelOrders) returns (MsgCancelOrdersResponse); + rpc RegisterContract(MsgRegisterContract) returns(MsgRegisterContractResponse); + rpc ContractDepositRent(MsgContractDepositRent) returns(MsgContractDepositRentResponse); + rpc UnregisterContract(MsgUnregisterContract) returns(MsgUnregisterContractResponse); + rpc RegisterPairs(MsgRegisterPairs) returns(MsgRegisterPairsResponse); + rpc UpdatePriceTickSize(MsgUpdatePriceTickSize) returns(MsgUpdateTickSizeResponse); + rpc UpdateQuantityTickSize(MsgUpdateQuantityTickSize) returns(MsgUpdateTickSizeResponse); + rpc UnsuspendContract(MsgUnsuspendContract) returns(MsgUnsuspendContractResponse); + // privileged endpoints below + +// this line is used by starport scaffolding # proto/tx/rpc +} + +message MsgPlaceOrders { + string creator = 1 [ + (gogoproto.jsontag) = "creator" + ]; + repeated Order orders = 2 [ + (gogoproto.jsontag) = "orders" + ]; + string contractAddr = 3 [ + (gogoproto.jsontag) = "contract_address" + ]; + repeated cosmos.base.v1beta1.Coin funds = 4 [ + (gogoproto.nullable) = false, + (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", + (gogoproto.jsontag) = "funds" + ]; +} + +message MsgPlaceOrdersResponse { + repeated uint64 orderIds = 1 [ + (gogoproto.moretags) = "yaml:\"order_ids\"", + (gogoproto.jsontag) = "order_ids" + ]; +} + +message MsgCancelOrders { + string creator = 1 [ + (gogoproto.jsontag) = "creator" + ]; + repeated Cancellation cancellations = 2 [ + (gogoproto.jsontag) = "cancellations" + ]; + string contractAddr = 3 [ + (gogoproto.jsontag) = "contract_address" + ]; +} + +message MsgCancelOrdersResponse {} + +message MsgRegisterContract { + string creator = 1; + ContractInfoV2 contract = 2; +} + +message MsgRegisterContractResponse {} + +message MsgContractDepositRent { + string contractAddr = 1 [ + (gogoproto.jsontag) = "contract_address" + ]; + uint64 amount = 2 [ + (gogoproto.jsontag) = "amount" + ]; + string sender = 3 [ + (gogoproto.jsontag) = "sender" + ]; +} + +message MsgContractDepositRentResponse {} + +message MsgUnregisterContract { + string creator = 1 [ + (gogoproto.jsontag) = "creator" + ]; + string contractAddr = 2 [ + (gogoproto.jsontag) = "contract_address" + ]; +} + +message MsgUnregisterContractResponse {} + +message MsgRegisterPairs { + string creator = 1; + repeated BatchContractPair batchcontractpair = 3 [ + (gogoproto.moretags) = "yaml:\"batch_contract_pair\"", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "batch_contract_pair" + ]; +} + +message MsgRegisterPairsResponse {} + +message MsgUpdatePriceTickSize { + string creator = 1 [ + (gogoproto.jsontag) = "creator" + ]; + repeated TickSize tickSizeList = 2 [ + (gogoproto.moretags) = "yaml:\"tick_size_list\"", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "tick_size_list" + ]; +} + +message MsgUpdateQuantityTickSize { + string creator = 1 [ + (gogoproto.jsontag) = "creator" + ]; + repeated TickSize tickSizeList = 2 [ + (gogoproto.moretags) = "yaml:\"tick_size_list\"", + (gogoproto.nullable) = false, + (gogoproto.jsontag) = "tick_size_list" + ]; +} + +message MsgUpdateTickSizeResponse {} + +message MsgUnsuspendContract { + string creator = 1 [ + (gogoproto.jsontag) = "creator" + ]; + string contractAddr = 2 [ + (gogoproto.jsontag) = "contract_address" + ]; +} + +message MsgUnsuspendContractResponse {} + +// this line is used by starport scaffolding # proto/tx/message \ No newline at end of file diff --git a/proto/mint/v1beta1/gov.proto b/proto/mint/v1beta1/gov.proto index 1f9c2133e..084b95196 100644 --- a/proto/mint/v1beta1/gov.proto +++ b/proto/mint/v1beta1/gov.proto @@ -6,6 +6,8 @@ import "mint/v1beta1/mint.proto"; option go_package = "github.com/sei-protocol/sei-chain/x/mint/types"; +// AddAssetMetadataProposal is a gov Content type for adding a new asset +// to the dex module's asset list. message UpdateMinterProposal { option (gogoproto.equal) = false; option (gogoproto.goproto_getters) = false; diff --git a/scripts/dump_app_state_for_height.sh b/scripts/dump_app_state_for_height.sh index 5d7d2b647..3107b2947 100755 --- a/scripts/dump_app_state_for_height.sh +++ b/scripts/dump_app_state_for_height.sh @@ -28,7 +28,7 @@ fi cd $HOME sudo rm -r state_$HEIGHT mkdir state_$HEIGHT -for key in wasm accesscontrol oracle epoch mint acc bank crisis feegrant staking distribution slashing gov params ibc upgrade evidence transfer tokenfactory +for key in dex wasm accesscontrol oracle epoch mint acc bank crisis feegrant staking distribution slashing gov params ibc upgrade evidence transfer tokenfactory do $HOME/go/bin/iaviewer data $HOME/.sei/data/application.db "s/k:"$key"/" $HEIGHT > $HOME/state_$HEIGHT/$key.data $HOME/go/bin/iaviewer shape $HOME/.sei/data/application.db "s/k:"$key"/" $HEIGHT > $HOME/state_$HEIGHT/$key.shape diff --git a/scripts/initialize_local_chain.sh b/scripts/initialize_local_chain.sh index 68773c0a9..ff17168f1 100755 --- a/scripts/initialize_local_chain.sh +++ b/scripts/initialize_local_chain.sh @@ -60,7 +60,7 @@ cat ~/.sei/config/genesis.json | jq '.app_state["oracle"]["params"]["whitelist"] cat ~/.sei/config/genesis.json | jq '.app_state["distribution"]["params"]["community_tax"]="0.000000000000000000"' > ~/.sei/config/tmp_genesis.json && mv ~/.sei/config/tmp_genesis.json ~/.sei/config/genesis.json cat ~/.sei/config/genesis.json | jq '.consensus_params["block"]["max_gas"]="35000000"' > ~/.sei/config/tmp_genesis.json && mv ~/.sei/config/tmp_genesis.json ~/.sei/config/genesis.json cat ~/.sei/config/genesis.json | jq '.app_state["staking"]["params"]["max_voting_power_ratio"]="1.000000000000000000"' > ~/.sei/config/tmp_genesis.json && mv ~/.sei/config/tmp_genesis.json ~/.sei/config/genesis.json -cat ~/.sei/config/genesis.json | jq '.app_state["bank"]["denom_metadata"]=[{"denom_units":[{"denom":"UATOM","exponent":6,"aliases":["UATOM"]}],"base":"uatom","display":"uatom","name":"UATOM","symbol":"UATOM"}]' > ~/.sei/config/tmp_genesis.json && mv ~/.sei/config/tmp_genesis.json ~/.sei/config/genesis.json +cat ~/.sei/config/genesis.json | jq '.app_state["bank"]["denom_metadata"]=[{"denom_units":[{"denom":"usei","exponent":0,"aliases":["USEI"]}],"base":"usei","display":"usei","name":"USEI","symbol":"USEI"}]' > ~/.sei/config/tmp_genesis.json && mv ~/.sei/config/tmp_genesis.json ~/.sei/config/genesis.json # Use the Python command to get the dates START_DATE=$($PYTHON_CMD -c "from datetime import datetime; print(datetime.now().strftime('%Y-%m-%d'))") diff --git a/scripts/upload_clearing_house_contract.sh b/scripts/upload_clearing_house_contract.sh new file mode 100755 index 000000000..cfbe49e9b --- /dev/null +++ b/scripts/upload_clearing_house_contract.sh @@ -0,0 +1,18 @@ +# ./scripts/initialize_local.sh to spawn chain locally, endpoint is default to localhost:9090 +# build the contract to wasm with `cargo build; docker run --rm -v "$(pwd)":/code --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry cosmwasm/rust-optimizer:0.12.5` + +# upload the code +printf '00000000\n' | ./build/seid tx wasm store ../matrix-contract/clearing-house-contract/artifacts/clearing_house.wasm -y --from=alice --chain-id=sei --gas=3000000 --fees=100000usei --broadcast-mode=block +# replace addr here with an addr you have privateKey +printf '00000000\n' | ./build/seid tx wasm instantiate 1 '{"whitelist": ["sei1zywupnfk3t8lvtuzh540vls8mf53r5zuq98wkt"],"use_whitelist":false,"admin":"sei1zywupnfk3t8lvtuzh540vls8mf53r5zuq98wkt","limit_order_fee":{"decimal":"0.0001","negative":false},"market_order_fee":{"decimal":"0.0001","negative":false},"liquidation_order_fee":{"decimal":"0.0001","negative":false},"margin_ratio":{"decimal":"0.0625","negative":false},"max_leverage":{"decimal":"4","negative":false}}' -y --no-admin --chain-id=sei --gas=1500000 --fees=15000usei --broadcast-mode=block --label=dex --from=alice +# contract_address highly possible is the same, if not replace +printf '00000000\n' | ./build/seid tx dex register-contract sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m 1 -y --from=alice --chain-id=sei --fees=100000usei --gas=500000 --broadcast-mode=block +# register a pair +printf '00000000\n' | ./build/seid tx dex register-pairs ./x/dex/example/register-pair-tx.json -y --from=alice --chain-id=sei --fees=10000000usei --gas=500000 --broadcast-mode=block +sleep 5 +printf '00000000\n' | ./build/seid tx dex update-tick-size ./x/dex/example/update-tick-size-tx.json -y --from=alice --chain-id=sei --fees=10000000usei --gas=500000 --broadcast-mode=block +printf '00000000\n' | ./build/seid tx gov deposit 2 10000000usei -y --from=alice --chain-id=sei --fees=10000000usei --gas=500000 --broadcast-mode=block +printf '00000000\n' | ./build/seid tx gov vote 2 yes -y --from=alice --chain-id=sei --fees=10000000usei --gas=500000 --broadcast-mode=block +# order: (position_direction, price, quantity, price_denom, asset_denom, position_effect(open/close), order_type(limit, market,..), leverage) +# need to wait for vote period close to take effect, seem no early stop implemented for vote +# ./build/seid tx dex place-orders sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m Long,1.01,5,usdc,sei,Open,Limit,1 --amount=10000usei -y --from=alice --chain-id=sei --fees=10000usei --gas=50000000 --broadcast-mode=block \ No newline at end of file diff --git a/testutil/fuzzing/dex.go b/testutil/fuzzing/dex.go new file mode 100644 index 000000000..78070362a --- /dev/null +++ b/testutil/fuzzing/dex.go @@ -0,0 +1,228 @@ +package fuzzing + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +const BaselinePrice = 1234.56 + +var ValidAccountCorpus = []string{ + "sei1h9yjz89tl0dl6zu65dpxcqnxfhq60wxx8s5kag", + "sei1c2q6xm0x684rshrnlg898zm3vpwz92pcfhgmws", + "sei1ewxvf5a9wq9zk5nurtl6m9yfxpnhyp7s7uk5sl", + "sei1lllgxa294pshcsrsrteh7sj6ey0zqgty30sl8a", + "sei1vhn2p3xavts9swus27zz3n56tz98g3f6unavs2", + "sei1jpkqjfydghgrc23chmnj52xln0muz09j5huhkt", + "sei1k98zjg7scsmk6d4ye8hhrv3an6ppykvt660736", + "sei1wxpqjzdmtjm6gwg6555n0a0aqglrvnp3pqh9hs", + "sei1yuyyr3xg7jhk7pjkrp4j6h88t7gv35e29pfvmf", + "sei1vjgdad5v2euf98nj3pwg5d8agflr384k0eks43", +} + +var AccountCorpus = append([]string{ + "invalid", +}, ValidAccountCorpus...) + +var ContractCorpus = []string{ + "invalid", + "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m", + "sei1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrqms7u8a", +} + +var ( + MicroTick = sdk.MustNewDecFromStr("0.000001") + MilliTick = sdk.MustNewDecFromStr("0.001") + WholeTick = sdk.OneDec() + PairCorpus = []types.Pair{ + {}, + {PriceDenom: "SEI"}, + {AssetDenom: "ATOM"}, + { + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + { + PriceDenom: "SEI", + AssetDenom: "ATOM", + PriceTicksize: &MicroTick, + QuantityTicksize: &MicroTick, + }, + { + PriceDenom: "SEI", + AssetDenom: "ATOM", + PriceTicksize: &MilliTick, + QuantityTicksize: &MilliTick, + }, + { + PriceDenom: "SEI", + AssetDenom: "ATOM", + PriceTicksize: &WholeTick, + QuantityTicksize: &WholeTick, + }, + { + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + { + PriceDenom: "USDC", + AssetDenom: "ATOM", + PriceTicksize: &MicroTick, + QuantityTicksize: &MicroTick, + }, + { + PriceDenom: "USDC", + AssetDenom: "ATOM", + PriceTicksize: &MilliTick, + QuantityTicksize: &MilliTick, + }, + { + PriceDenom: "USDC", + AssetDenom: "ATOM", + PriceTicksize: &WholeTick, + QuantityTicksize: &WholeTick, + }, + } +) + +func GetAccount(i int) string { + ui := uint64(i) % uint64(len(AccountCorpus)) + return AccountCorpus[int(ui)] +} + +func GetValidAccount(i int) string { + ui := uint64(i) % uint64(len(ValidAccountCorpus)) + return ValidAccountCorpus[int(ui)] +} + +func GetContract(i int) string { + ui := uint64(i) % uint64(len(ContractCorpus)) + return ContractCorpus[int(ui)] +} + +func GetPair(i int) types.Pair { + ui := uint64(i) % uint64(len(PairCorpus)) + return PairCorpus[int(ui)] +} + +func GetPlacedOrders(direction types.PositionDirection, orderType types.OrderType, pair types.Pair, prices []byte, quantities []byte) []*types.Order { + // take the shorter slice's length + if len(prices) < len(quantities) { + quantities = quantities[:len(prices)] + } else { + prices = prices[:len(quantities)] + } + res := []*types.Order{} + for i, price := range prices { + var priceDec sdk.Dec + if direction == types.PositionDirection_LONG { + priceDec = sdk.MustNewDecFromStr(fmt.Sprintf("%f", BaselinePrice+float64(price))) + } else { + priceDec = sdk.MustNewDecFromStr(fmt.Sprintf("%f", BaselinePrice-float64(price))) + } + quantity := sdk.NewDec(int64(quantities[i])) + res = append(res, &types.Order{ + Id: uint64(i), + Status: types.OrderStatus_PLACED, + Price: priceDec, + Quantity: quantity, + PositionDirection: direction, + OrderType: orderType, + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + }) + } + return res +} + +func GetOrderBookEntries(buy bool, priceDenom string, assetDenom string, entryWeights []byte, allAccountIndices []byte, allWeights []byte) []types.OrderBookEntry { + res := []types.OrderBookEntry{} + totalPriceWeights := uint64(0) + for _, entryWeight := range entryWeights { + totalPriceWeights += uint64(entryWeight) + } + if totalPriceWeights == uint64(0) { + return res + } + sliceStartAccnt, sliceStartWeights := 0, 0 + cumWeights := uint64(0) + for i, entryWeight := range entryWeights { + var price sdk.Dec + if buy { + price = sdk.MustNewDecFromStr(fmt.Sprintf("%f", BaselinePrice-float64(i))) + } else { + price = sdk.MustNewDecFromStr(fmt.Sprintf("%f", BaselinePrice+float64(i))) + } + cumWeights += uint64(entryWeight) + nextSliceStartAccnt := int(cumWeights * uint64(len(allAccountIndices)) / totalPriceWeights) + nextSliceStartWeights := int(cumWeights * uint64(len(allWeights)) / totalPriceWeights) + entry := types.OrderEntry{ + Price: price, + Quantity: sdk.NewDec(int64(uint64((entryWeight)))), + PriceDenom: priceDenom, + AssetDenom: assetDenom, + Allocations: GetAllocations( + int64(uint64((entryWeight))), + allAccountIndices[sliceStartAccnt:nextSliceStartAccnt], + allWeights[sliceStartWeights:nextSliceStartWeights], + ), + } + if buy { + res = append(res, &types.LongBook{ + Price: price, + Entry: &entry, + }) + } else { + res = append(res, &types.ShortBook{ + Price: price, + Entry: &entry, + }) + } + sliceStartAccnt, sliceStartWeights = nextSliceStartAccnt, nextSliceStartWeights + } + return res +} + +func GetAllocations(totalQuantity int64, accountIndices []byte, weights []byte) []*types.Allocation { + // take the shorter slice's length + if len(accountIndices) < len(weights) { + weights = weights[:len(accountIndices)] + } else { + accountIndices = accountIndices[:len(weights)] + } + // dedupe and aggregate + aggregatedAccountsToWeights := map[string]uint64{} + totalWeight := uint64(0) + for i, accountIdx := range accountIndices { + account := GetValidAccount(int(accountIdx)) + weight := uint64(weights[i]) + if old, ok := aggregatedAccountsToWeights[account]; !ok { + aggregatedAccountsToWeights[account] = weight + } else { + aggregatedAccountsToWeights[account] = old + weight + } + totalWeight += weight + } + + quantityDec := sdk.NewDec(totalQuantity) + totalWeightDec := sdk.NewDec(int64(totalWeight)) + res := []*types.Allocation{} + orderID := 0 + for account, weight := range aggregatedAccountsToWeights { + var quantity sdk.Dec + if totalWeightDec.IsZero() { + quantity = sdk.ZeroDec() + } else { + quantity = quantityDec.Mul(sdk.NewDec(int64(weight))).Quo(totalWeightDec) + } + res = append(res, &types.Allocation{ + OrderId: uint64(orderID), + Account: account, + Quantity: quantity, + }) + orderID++ + } + return res +} diff --git a/testutil/keeper/dex.go b/testutil/keeper/dex.go new file mode 100644 index 000000000..5681676b7 --- /dev/null +++ b/testutil/keeper/dex.go @@ -0,0 +1,196 @@ +package keeper + +import ( + "context" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" + typesparams "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/sei-protocol/sei-chain/app" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + epochkeeper "github.com/sei-protocol/sei-chain/x/epoch/keeper" + epochtypes "github.com/sei-protocol/sei-chain/x/epoch/types" + minttypes "github.com/sei-protocol/sei-chain/x/mint/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmdb "github.com/tendermint/tm-db" +) + +const ( + TestAccount = "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx" + TestContract = "sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc" + TestAccount2 = "sei1vk2f6aps83xahv2sql4equx8fa95jgcnsdxkvr" + TestContract2 = "sei17p9rzwnnfxcjp32un9ug7yhhzgtkhvl9jfksztgw5uh69wac2pgsrtqewe" + TestPriceDenom = "usdc" + TestAssetDenom = "atom" +) + +var ( + TestTicksize = sdk.OneDec() + TestPair = types.Pair{ + PriceDenom: TestPriceDenom, + AssetDenom: TestAssetDenom, + PriceTicksize: &TestTicksize, + QuantityTicksize: &TestTicksize, + } +) + +func TestApp() *app.App { + return app.Setup(false, false) +} + +func DexKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { + storeKey := sdk.NewKVStoreKey(types.StoreKey) + keyAcc := sdk.NewKVStoreKey(authtypes.StoreKey) + keyBank := sdk.NewKVStoreKey(banktypes.StoreKey) + keyParams := sdk.NewKVStoreKey(typesparams.StoreKey) + tKeyParams := sdk.NewTransientStoreKey(typesparams.TStoreKey) + keyEpochs := sdk.NewKVStoreKey(epochtypes.StoreKey) + dexMemStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + memStoreKey := storetypes.NewMemoryStoreKey(epochtypes.MemStoreKey) + + blackListAddrs := map[string]bool{} + + maccPerms := map[string][]string{ + types.ModuleName: nil, + minttypes.ModuleName: {authtypes.Minter}, + } + + db := tmdb.NewMemDB() + stateStore := store.NewCommitMultiStore(db) + stateStore.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(keyBank, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) + stateStore.MountStoreWithDB(dexMemStoreKey, sdk.StoreTypeMemory, nil) + stateStore.MountStoreWithDB(keyEpochs, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(tKeyParams, sdk.StoreTypeTransient, db) + stateStore.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) + require.NoError(t, stateStore.LoadLatestVersion()) + + cdc := codec.NewProtoCodec(app.MakeEncodingConfig().InterfaceRegistry) + + paramsSubspace := typesparams.NewSubspace(cdc, + types.Amino, + storeKey, + memStoreKey, + "DexParams", + ) + paramsKeeper := paramskeeper.NewKeeper(cdc, codec.NewLegacyAmino(), keyParams, tKeyParams) + accountKeeper := authkeeper.NewAccountKeeper(cdc, keyAcc, paramsKeeper.Subspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms) + bankKeeper := bankkeeper.NewBaseKeeper(cdc, keyBank, accountKeeper, paramsKeeper.Subspace(banktypes.ModuleName), blackListAddrs) + epochKeeper := epochkeeper.NewKeeper(cdc, keyEpochs, memStoreKey, paramsKeeper.Subspace(epochtypes.ModuleName)) + k := keeper.NewKeeper( + cdc, + storeKey, + dexMemStoreKey, + paramsSubspace, + *epochKeeper, + bankKeeper, + accountKeeper, + ) + + ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) + k.CreateModuleAccount(ctx) + + // Initialize params + k.SetParams(ctx, types.DefaultParams()) + bankParams := banktypes.DefaultParams() + bankParams.SendEnabled = []*banktypes.SendEnabled{ + { + Denom: TestPriceDenom, + Enabled: true, + }, + } + bankKeeper.SetParams(ctx, bankParams) + + return k, ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(dexMemStoreKey))) +} + +func CreateAssetMetadata(keeper *keeper.Keeper, ctx sdk.Context) types.AssetMetadata { + ibcInfo := types.AssetIBCInfo{ + SourceChannel: "channel-1", + DstChannel: "channel-2", + SourceDenom: "uusdc", + SourceChainID: "axelar", + } + + denomUnit := banktypes.DenomUnit{ + Denom: "ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858", + Exponent: 0, + Aliases: []string{"axlusdc", "usdc"}, + } + + var denomUnits []*banktypes.DenomUnit + denomUnits = append(denomUnits, &denomUnit) + + metadata := banktypes.Metadata{ + Description: "Circle's stablecoin on Axelar", + DenomUnits: denomUnits, + Base: "ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858", + Name: "USD Coin", + Display: "axlusdc", + Symbol: "USDC", + } + + item := types.AssetMetadata{ + IbcInfo: &ibcInfo, + TypeAsset: "erc20", + Metadata: metadata, + } + + keeper.SetAssetMetadata(ctx, item) + + return item +} + +func SeedPriceSnapshot(ctx sdk.Context, k *keeper.Keeper, price string, timestamp uint64) { + priceSnapshot := types.Price{ + SnapshotTimestampInSeconds: timestamp, + Price: sdk.MustNewDecFromStr(price), + Pair: &TestPair, + } + k.SetPriceState(ctx, priceSnapshot, TestContract) +} + +func CreateNLongBook(keeper *keeper.Keeper, ctx sdk.Context, n int) []types.LongBook { + items := make([]types.LongBook, n) + for i := range items { + items[i].Entry = &types.OrderEntry{ + Price: sdk.NewDec(int64(i)), + Quantity: sdk.NewDec(int64(i)), + PriceDenom: TestPriceDenom, + AssetDenom: TestAssetDenom, + } + items[i].Price = sdk.NewDec(int64(i)) + keeper.SetLongBook(ctx, TestContract, items[i]) + } + return items +} + +func CreateNShortBook(keeper *keeper.Keeper, ctx sdk.Context, n int) []types.ShortBook { + items := make([]types.ShortBook, n) + for i := range items { + items[i].Entry = &types.OrderEntry{ + Price: sdk.NewDec(int64(i)), + Quantity: sdk.NewDec(int64(i)), + PriceDenom: TestPriceDenom, + AssetDenom: TestAssetDenom, + } + items[i].Price = sdk.NewDec(int64(i)) + keeper.SetShortBook(ctx, TestContract, items[i]) + } + return items +} diff --git a/testutil/keeper/epoch.go b/testutil/keeper/epoch.go index 57f91de84..0f5584600 100644 --- a/testutil/keeper/epoch.go +++ b/testutil/keeper/epoch.go @@ -9,7 +9,6 @@ import ( storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" typesparams "github.com/cosmos/cosmos-sdk/x/params/types" - "github.com/sei-protocol/sei-chain/app" "github.com/sei-protocol/sei-chain/x/epoch/keeper" "github.com/sei-protocol/sei-chain/x/epoch/types" "github.com/stretchr/testify/require" @@ -18,10 +17,6 @@ import ( tmdb "github.com/tendermint/tm-db" ) -func TestApp() *app.App { - return app.Setup(false, false) -} - func EpochKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { storeKey := sdk.NewKVStoreKey(types.StoreKey) memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) diff --git a/testutil/keeper/evm.go b/testutil/keeper/evm.go index d5449ad59..bd2df8b44 100644 --- a/testutil/keeper/evm.go +++ b/testutil/keeper/evm.go @@ -100,3 +100,7 @@ func PrivateKeyToAddresses(privKey cryptotypes.PrivKey) (sdk.AccAddress, common. return sdk.AccAddress(privKey.PubKey().Address()), crypto.PubkeyToAddress(*pubKey) } + +func UseiCoins(amount int64) sdk.Coins { + return sdk.NewCoins(sdk.NewCoin(sdk.MustGetBaseDenom(), sdk.NewInt(amount))) +} diff --git a/testutil/processblock/msgs/dex.go b/testutil/processblock/msgs/dex.go new file mode 100644 index 000000000..6a9e79991 --- /dev/null +++ b/testutil/processblock/msgs/dex.go @@ -0,0 +1,101 @@ +package msgs + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/utils" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" +) + +type Market struct { + contract string + priceDenom string + assetDenom string +} + +func NewMarket(contract string, priceDenom string, assetDenom string) *Market { + return &Market{ + contract: contract, + priceDenom: priceDenom, + assetDenom: assetDenom, + } +} + +func (m *Market) Register(admin sdk.AccAddress, deps []string, deposit uint64) []sdk.Msg { + pointOne := sdk.NewDecWithPrec(1, 1) + return []sdk.Msg{dextypes.NewMsgRegisterContract(admin.String(), 0, m.contract, true, utils.Map(deps, func(dep string) *dextypes.ContractDependencyInfo { + return &dextypes.ContractDependencyInfo{Dependency: dep} + }), deposit), dextypes.NewMsgRegisterPairs(admin.String(), []dextypes.BatchContractPair{{ + ContractAddr: m.contract, + Pairs: []*dextypes.Pair{{ + PriceDenom: m.priceDenom, + AssetDenom: m.assetDenom, + PriceTicksize: &pointOne, + QuantityTicksize: &pointOne, + }}, + }})} +} + +func (m *Market) LongLimitOrder(account sdk.AccAddress, price string, quantity string) *dextypes.MsgPlaceOrders { + o := m.commonOrder(account, price, quantity) + o.PositionDirection = dextypes.PositionDirection_LONG + o.OrderType = dextypes.OrderType_LIMIT + return dextypes.NewMsgPlaceOrders(account.String(), []*dextypes.Order{o}, m.contract, fundForOrder(o)) +} + +func (m *Market) ShortLimitOrder(account sdk.AccAddress, price string, quantity string) *dextypes.MsgPlaceOrders { + o := m.commonOrder(account, price, quantity) + o.PositionDirection = dextypes.PositionDirection_SHORT + o.OrderType = dextypes.OrderType_LIMIT + return dextypes.NewMsgPlaceOrders(account.String(), []*dextypes.Order{o}, m.contract, fundForOrder(o)) +} + +func (m *Market) LongMarketOrder(account sdk.AccAddress, price string, quantity string) *dextypes.MsgPlaceOrders { + o := m.commonOrder(account, price, quantity) + o.PositionDirection = dextypes.PositionDirection_LONG + o.OrderType = dextypes.OrderType_MARKET + return dextypes.NewMsgPlaceOrders(account.String(), []*dextypes.Order{o}, m.contract, fundForOrder(o)) +} + +func (m *Market) ShortMarketOrder(account sdk.AccAddress, price string, quantity string) *dextypes.MsgPlaceOrders { + o := m.commonOrder(account, price, quantity) + o.PositionDirection = dextypes.PositionDirection_SHORT + o.OrderType = dextypes.OrderType_MARKET + return dextypes.NewMsgPlaceOrders(account.String(), []*dextypes.Order{o}, m.contract, fundForOrder(o)) +} + +func (m *Market) CancelLongOrder(account sdk.AccAddress, price string, id uint64) *dextypes.MsgCancelOrders { + c := m.commonCancel(account, price, id) + c.PositionDirection = dextypes.PositionDirection_LONG + return dextypes.NewMsgCancelOrders(account.String(), []*dextypes.Cancellation{c}, m.contract) +} + +func (m *Market) CancelShortOrder(account sdk.AccAddress, price string, id uint64) *dextypes.MsgCancelOrders { + c := m.commonCancel(account, price, id) + c.PositionDirection = dextypes.PositionDirection_SHORT + return dextypes.NewMsgCancelOrders(account.String(), []*dextypes.Cancellation{c}, m.contract) +} + +func (m *Market) commonOrder(account sdk.AccAddress, price string, quantity string) *dextypes.Order { + return &dextypes.Order{ + Account: account.String(), + Price: sdk.MustNewDecFromStr(price), + Quantity: sdk.MustNewDecFromStr(quantity), + PriceDenom: m.priceDenom, + AssetDenom: m.assetDenom, + } +} + +func (m *Market) commonCancel(account sdk.AccAddress, price string, id uint64) *dextypes.Cancellation { + return &dextypes.Cancellation{ + Creator: account.String(), + Price: sdk.MustNewDecFromStr(price), + Id: id, + PriceDenom: m.priceDenom, + AssetDenom: m.assetDenom, + ContractAddr: m.contract, + } +} + +func fundForOrder(o *dextypes.Order) sdk.Coins { + return sdk.NewCoins(sdk.NewCoin("usei", o.Price.Mul(o.Quantity).RoundInt())) +} diff --git a/testutil/processblock/presets.go b/testutil/processblock/presets.go index 27cb58cb8..785046f28 100644 --- a/testutil/processblock/presets.go +++ b/testutil/processblock/presets.go @@ -9,6 +9,9 @@ import ( authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/sei-protocol/sei-chain/testutil/processblock/msgs" + "github.com/sei-protocol/sei-chain/utils" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" minttypes "github.com/sei-protocol/sei-chain/x/mint/types" ) @@ -17,6 +20,8 @@ type Preset struct { SignableAccounts []sdk.AccAddress AllAccounts []sdk.AccAddress AllValidators []sdk.ValAddress + AllContracts []sdk.AccAddress + AllDexMarkets []*msgs.Market } // 3 unsignable accounts @@ -27,6 +32,7 @@ func CommonPreset(app *App) *Preset { fmt.Printf("Distribution module: %s\n", app.AccountKeeper.GetModuleAddress(distrtypes.ModuleName).String()) fmt.Printf("Staking bonded pool: %s\n", app.AccountKeeper.GetModuleAddress(stakingtypes.BondedPoolName).String()) fmt.Printf("Staking unbonded pool: %s\n", app.AccountKeeper.GetModuleAddress(stakingtypes.NotBondedPoolName).String()) + fmt.Printf("Dex module: %s\n", app.AccountKeeper.GetModuleAddress(dextypes.ModuleName).String()) fmt.Printf("Wasm module: %s\n", app.AccountKeeper.GetModuleAddress(wasm.ModuleName).String()) p := &Preset{ Admin: app.NewSignableAccount("admin"), @@ -49,7 +55,37 @@ func CommonPreset(app *App) *Preset { return p } +func DexPreset(app *App, numAccounts int, numMarkets int) *Preset { + p := CommonPreset(app) + for i := 0; i < numAccounts; i++ { + acc := app.NewSignableAccount(fmt.Sprintf("DexPreset%d", i)) + app.FundAccount(acc, 10000000) + p.AllAccounts = append(p.AllAccounts, acc) + p.SignableAccounts = append(p.SignableAccounts, acc) + fmt.Printf("DexPreset account: %s\n", acc.String()) + } + for i := 0; i < numMarkets; i++ { + contract := app.NewContract(p.Admin, "./mars.wasm") + market := msgs.NewMarket(contract.String(), "SEI", fmt.Sprintf("ATOM%d", i)) + p.AllContracts = append(p.AllContracts, contract) + p.AllDexMarkets = append(p.AllDexMarkets, market) + fmt.Printf("DexPreset contract: %s\n", contract.String()) + } + return p +} + // always with enough fee func (p *Preset) AdminSign(app *App, msgs ...sdk.Msg) signing.Tx { return app.Sign(p.Admin, 10000000, msgs...) } + +func (p *Preset) DoRegisterMarkets(app *App) { + block := utils.Map(p.AllDexMarkets, func(m *msgs.Market) signing.Tx { + return p.AdminSign(app, m.Register(p.Admin, []string{}, 20000000)...) + }) + for i, code := range app.RunBlock(block) { + if code != 0 { + panic(fmt.Sprintf("error code %d when registering the %d-th market", code, i)) + } + } +} diff --git a/testutil/processblock/verify/bank.go b/testutil/processblock/verify/bank.go index 2bd76fe9f..580ee5b85 100644 --- a/testutil/processblock/verify/bank.go +++ b/testutil/processblock/verify/bank.go @@ -7,6 +7,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/signing" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/sei-protocol/sei-chain/testutil/processblock" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" "github.com/stretchr/testify/require" ) @@ -31,6 +32,12 @@ func Balance(t *testing.T, app *processblock.App, f BlockRunnable, txs []signing for _, output := range m.Outputs { updateMultipleExpectedBalanceChange(expectedChanges, output.Address, output.Coins, true) } + case *dextypes.MsgPlaceOrders: + updateMultipleExpectedBalanceChange(expectedChanges, m.Creator, m.Funds, false) + updateMultipleExpectedBalanceChange(expectedChanges, m.ContractAddr, m.Funds, true) + case *dextypes.MsgRegisterContract: + funds := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(int64(m.Contract.RentBalance)))) + updateMultipleExpectedBalanceChange(expectedChanges, m.Creator, funds, false) default: // TODO: add coverage for other balance-affecting messages to enable testing for those message types continue diff --git a/testutil/processblock/verify/dex.go b/testutil/processblock/verify/dex.go new file mode 100644 index 000000000..cfc5a2779 --- /dev/null +++ b/testutil/processblock/verify/dex.go @@ -0,0 +1,269 @@ +package verify + +import ( + "sort" + "strings" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/signing" + "github.com/sei-protocol/sei-chain/testutil/processblock" + "github.com/sei-protocol/sei-chain/utils" + dexkeeper "github.com/sei-protocol/sei-chain/x/dex/keeper" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func DexOrders(t *testing.T, app *processblock.App, f BlockRunnable, txs []signing.Tx) BlockRunnable { + return func() []uint32 { + orderPlacementsByMarket := map[string][]*dextypes.Order{} + orderCancellationsByMarket := map[string][]*dextypes.Cancellation{} + markets := map[string]struct{}{} + for _, tx := range txs { + for _, msg := range tx.GetMsgs() { + switch m := msg.(type) { + case *dextypes.MsgPlaceOrders: + for _, o := range m.Orders { + id := strings.Join([]string{m.ContractAddr, o.PriceDenom, o.AssetDenom}, ",") + markets[id] = struct{}{} + if orders, ok := orderPlacementsByMarket[id]; ok { + o.Id = app.DexKeeper.GetNextOrderID(app.Ctx(), m.ContractAddr) + uint64(len(orders)) + orderPlacementsByMarket[id] = append(orders, o) + } else { + o.Id = app.DexKeeper.GetNextOrderID(app.Ctx(), m.ContractAddr) + orderPlacementsByMarket[id] = []*dextypes.Order{o} + } + } + case *dextypes.MsgCancelOrders: + for _, o := range m.Cancellations { + id := strings.Join([]string{m.ContractAddr, o.PriceDenom, o.AssetDenom}, ",") + markets[id] = struct{}{} + if cancels, ok := orderCancellationsByMarket[id]; ok { + orderCancellationsByMarket[id] = append(cancels, o) + } else { + orderCancellationsByMarket[id] = []*dextypes.Cancellation{o} + } + } + default: + continue + } + } + } + expectedLongBookByMarket := map[string]map[string]*dextypes.OrderEntry{} + expectedShortBookByMarket := map[string]map[string]*dextypes.OrderEntry{} + for market := range markets { + orderPlacements := []*dextypes.Order{} + if o, ok := orderPlacementsByMarket[market]; ok { + orderPlacements = o + } + orderCancellations := []*dextypes.Cancellation{} + if c, ok := orderCancellationsByMarket[market]; ok { + orderCancellations = c + } + parts := strings.Split(market, ",") + longBook, shortBook := expectedOrdersForMarket(app.Ctx(), &app.DexKeeper, orderPlacements, orderCancellations, parts[0], parts[1], parts[2]) + expectedLongBookByMarket[market] = longBook + expectedShortBookByMarket[market] = shortBook + } + + results := f() + + for market, longBook := range expectedLongBookByMarket { + parts := strings.Split(market, ",") + contract := parts[0] + priceDenom := parts[1] + assetDenom := parts[2] + require.Equal(t, len(longBook), len(app.DexKeeper.GetAllLongBookForPair(app.Ctx(), contract, priceDenom, assetDenom))) + for price, entry := range longBook { + actual, found := app.DexKeeper.GetLongOrderBookEntryByPrice(app.Ctx(), contract, sdk.MustNewDecFromStr(price), priceDenom, assetDenom) + require.True(t, found) + require.Equal(t, *entry, *(actual.GetOrderEntry())) + } + } + + for market, shortBook := range expectedShortBookByMarket { + parts := strings.Split(market, ",") + contract := parts[0] + priceDenom := parts[1] + assetDenom := parts[2] + require.Equal(t, len(shortBook), len(app.DexKeeper.GetAllShortBookForPair(app.Ctx(), contract, priceDenom, assetDenom))) + for price, entry := range shortBook { + actual, found := app.DexKeeper.GetShortOrderBookEntryByPrice(app.Ctx(), contract, sdk.MustNewDecFromStr(price), priceDenom, assetDenom) + require.True(t, found) + require.Equal(t, *entry, *(actual.GetOrderEntry())) + } + } + + return results + } +} + +// A slow but correct implementation of dex exchange logics that build the expected order book state based on the +// current state and the list of new orders/cancellations, based on dex exchange rules. +func expectedOrdersForMarket( + ctx sdk.Context, + keeper *dexkeeper.Keeper, + orderPlacements []*dextypes.Order, + orderCancellations []*dextypes.Cancellation, + contract string, + priceDenom string, + assetDenom string, +) (longEntries map[string]*dextypes.OrderEntry, shortEntries map[string]*dextypes.OrderEntry) { + longBook := toOrderBookMap(keeper.GetAllLongBookForPair(ctx, contract, priceDenom, assetDenom)) + shortBook := toOrderBookMap(keeper.GetAllShortBookForPair(ctx, contract, priceDenom, assetDenom)) + books := map[dextypes.PositionDirection]map[string]*dextypes.OrderEntry{ + dextypes.PositionDirection_LONG: longBook, + dextypes.PositionDirection_SHORT: shortBook, + } + // first, cancellation + cancelOrders(books, orderCancellations) + // then add new limit orders to book + addOrders(books, orderPlacements) + // then match market orders + matchOrders(getMarketOrderBookMap(orderPlacements, dextypes.PositionDirection_LONG), shortBook) + matchOrders(longBook, getMarketOrderBookMap(orderPlacements, dextypes.PositionDirection_SHORT)) + // finally match limit orders + matchOrders(longBook, shortBook) + return longBook, shortBook +} + +func cancelOrders( + books map[dextypes.PositionDirection]map[string]*dextypes.OrderEntry, + orderCancellations []*dextypes.Cancellation, +) { + for _, cancel := range orderCancellations { + book := books[cancel.PositionDirection] + if entry, ok := book[cancel.Price.String()]; ok { + entry.Allocations = removeMatched(entry.Allocations, func(a *dextypes.Allocation) bool { return a.OrderId == cancel.Id }) + updateEntryQuantity(entry) + if entry.Quantity.IsZero() { + delete(book, cancel.Price.String()) + } + } + } +} + +func addOrders( + books map[dextypes.PositionDirection]map[string]*dextypes.OrderEntry, + orderPlacements []*dextypes.Order, +) { + for _, o := range orderPlacements { + if o.OrderType != dextypes.OrderType_LIMIT { + continue + } + book := books[o.PositionDirection] + newAllocation := &dextypes.Allocation{ + Account: o.Account, + Quantity: o.Quantity, + OrderId: o.Id, + } + if entry, ok := book[o.Price.String()]; ok { + entry.Allocations = append(entry.Allocations, newAllocation) + updateEntryQuantity(entry) + } else { + book[o.Price.String()] = &dextypes.OrderEntry{ + Price: o.Price, + Quantity: o.Quantity, + PriceDenom: o.PriceDenom, + AssetDenom: o.AssetDenom, + Allocations: []*dextypes.Allocation{newAllocation}, + } + } + } +} + +func matchOrders( + longBook map[string]*dextypes.OrderEntry, + shortBook map[string]*dextypes.OrderEntry, +) { + buyPrices := sortedPrices(longBook, true) + sellPrices := sortedPrices(shortBook, false) + for i, j := 0, 0; i < len(buyPrices) && j < len(sellPrices) && buyPrices[i].GTE(sellPrices[j]); { + buyEntry := longBook[buyPrices[i].String()] + sellEntry := shortBook[sellPrices[j].String()] + if buyEntry.Quantity.GT(sellEntry.Quantity) { + takeLiquidity(longBook, buyPrices[i], sellEntry.Quantity) + takeLiquidity(shortBook, sellPrices[i], sellEntry.Quantity) + j++ + } else { + takeLiquidity(longBook, buyPrices[i], buyEntry.Quantity) + takeLiquidity(shortBook, sellPrices[i], buyEntry.Quantity) + i++ + } + } +} + +func toOrderBookMap(book []dextypes.OrderBookEntry) map[string]*dextypes.OrderEntry { + bookMap := map[string]*dextypes.OrderEntry{} + for _, e := range book { + bookMap[e.GetPrice().String()] = e.GetOrderEntry() + } + return bookMap +} + +func getMarketOrderBookMap(orderPlacements []*dextypes.Order, direction dextypes.PositionDirection) map[string]*dextypes.OrderEntry { + bookMap := map[string]*dextypes.OrderEntry{} + for _, o := range orderPlacements { + if o.OrderType != dextypes.OrderType_MARKET || o.PositionDirection != direction { + continue + } + bookMap[o.Price.String()] = orderToOrderEntry(o) + } + return bookMap +} + +func updateEntryQuantity(entry *dextypes.OrderEntry) { + entry.Quantity = utils.Reduce( + entry.Allocations, + func(a *dextypes.Allocation, q sdk.Dec) sdk.Dec { return q.Add(a.Quantity) }, + sdk.ZeroDec(), + ) +} + +func takeLiquidity(book map[string]*dextypes.OrderEntry, price sdk.Dec, quantity sdk.Dec) { + entry := book[price.String()] + if entry.Quantity.Equal(quantity) { + delete(book, price.String()) + return + } + if quantity.GT(entry.Quantity) { + panic("insufficient liquidity") + } + allocated := sdk.ZeroDec() + newAllocations := []*dextypes.Allocation{} + for _, a := range entry.Allocations { + switch { + case allocated.Equal(quantity): + newAllocations = append(newAllocations, a) + case allocated.Add(a.Quantity).GT(quantity): + a.Quantity = a.Quantity.Sub(quantity.Sub(allocated)) + newAllocations = append(newAllocations, a) + allocated = quantity + default: + allocated = allocated.Add(a.Quantity) + } + } + entry.Allocations = newAllocations + entry.Quantity = entry.Quantity.Sub(quantity) +} + +func sortedPrices(book map[string]*dextypes.OrderEntry, descending bool) []sdk.Dec { + prices := []sdk.Dec{} + for p := range book { + prices = append(prices, sdk.MustNewDecFromStr(p)) + } + if descending { + sort.Slice(prices, func(i, j int) bool { return prices[i].GT(prices[j]) }) + } else { + sort.Slice(prices, func(i, j int) bool { return prices[i].LT(prices[j]) }) + } + return prices +} + +func orderToOrderEntry(order *dextypes.Order) *dextypes.OrderEntry { + return &dextypes.OrderEntry{ + Price: order.Price, + Quantity: order.Quantity, + Allocations: []*dextypes.Allocation{{Quantity: order.Quantity}}, + } +} diff --git a/wasmbinding/bindings/msg.go b/wasmbinding/bindings/msg.go index cb9fdff46..7e633640d 100644 --- a/wasmbinding/bindings/msg.go +++ b/wasmbinding/bindings/msg.go @@ -3,6 +3,7 @@ package bindings import ( sdk "github.com/cosmos/cosmos-sdk/types" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + "github.com/sei-protocol/sei-chain/x/dex/types" ) // / CreateDenom creates a new factory denom, of denomination: @@ -34,6 +35,18 @@ type BurnTokens struct { Amount sdk.Coin `json:"amount"` } +// Dex Module msgs +type PlaceOrders struct { + Orders []*types.Order `json:"orders"` + Funds sdk.Coins `json:"funds"` + ContractAddr string `json:"contract_address"` +} + +type CancelOrders struct { + Cancellations []*types.Cancellation `json:"cancellations"` + ContractAddr string `json:"contract_address"` +} + type CallEVM struct { Value *sdk.Int `json:"value"` To string `json:"to"` diff --git a/wasmbinding/encoder.go b/wasmbinding/encoder.go index 087e00279..1e691b8d6 100644 --- a/wasmbinding/encoder.go +++ b/wasmbinding/encoder.go @@ -7,11 +7,14 @@ import ( wasmvmtypes "github.com/CosmWasm/wasmvm/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + dexwasm "github.com/sei-protocol/sei-chain/x/dex/client/wasm" evmwasm "github.com/sei-protocol/sei-chain/x/evm/client/wasm" tokenfactorywasm "github.com/sei-protocol/sei-chain/x/tokenfactory/client/wasm" ) type SeiWasmMessage struct { + PlaceOrders json.RawMessage `json:"place_orders,omitempty"` + CancelOrders json.RawMessage `json:"cancel_orders,omitempty"` CreateDenom json.RawMessage `json:"create_denom,omitempty"` MintTokens json.RawMessage `json:"mint_tokens,omitempty"` BurnTokens json.RawMessage `json:"burn_tokens,omitempty"` @@ -27,6 +30,10 @@ func CustomEncoder(sender sdk.AccAddress, msg json.RawMessage, info wasmvmtypes. return []sdk.Msg{}, sdkerrors.Wrap(err, "Error parsing Sei Wasm Message") } switch { + case parsedMessage.PlaceOrders != nil: + return dexwasm.EncodeDexPlaceOrders(parsedMessage.PlaceOrders, sender) + case parsedMessage.CancelOrders != nil: + return dexwasm.EncodeDexCancelOrders(parsedMessage.CancelOrders, sender) case parsedMessage.CreateDenom != nil: return tokenfactorywasm.EncodeTokenFactoryCreateDenom(parsedMessage.CreateDenom, sender) case parsedMessage.MintTokens != nil: diff --git a/wasmbinding/queries.go b/wasmbinding/queries.go index de60fed50..122bb712b 100644 --- a/wasmbinding/queries.go +++ b/wasmbinding/queries.go @@ -7,6 +7,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sei-protocol/sei-chain/utils/metrics" + dexwasm "github.com/sei-protocol/sei-chain/x/dex/client/wasm" + dexbindings "github.com/sei-protocol/sei-chain/x/dex/client/wasm/bindings" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" epochwasm "github.com/sei-protocol/sei-chain/x/epoch/client/wasm" epochbindings "github.com/sei-protocol/sei-chain/x/epoch/client/wasm/bindings" epochtypes "github.com/sei-protocol/sei-chain/x/epoch/types" @@ -22,15 +25,17 @@ import ( type QueryPlugin struct { oracleHandler oraclewasm.OracleWasmQueryHandler + dexHandler dexwasm.DexWasmQueryHandler epochHandler epochwasm.EpochWasmQueryHandler tokenfactoryHandler tokenfactorywasm.TokenFactoryWasmQueryHandler evmHandler evmwasm.EVMQueryHandler } // NewQueryPlugin returns a reference to a new QueryPlugin. -func NewQueryPlugin(oh *oraclewasm.OracleWasmQueryHandler, eh *epochwasm.EpochWasmQueryHandler, th *tokenfactorywasm.TokenFactoryWasmQueryHandler, evmh *evmwasm.EVMQueryHandler) *QueryPlugin { +func NewQueryPlugin(oh *oraclewasm.OracleWasmQueryHandler, dh *dexwasm.DexWasmQueryHandler, eh *epochwasm.EpochWasmQueryHandler, th *tokenfactorywasm.TokenFactoryWasmQueryHandler, evmh *evmwasm.EVMQueryHandler) *QueryPlugin { return &QueryPlugin{ oracleHandler: *oh, + dexHandler: *dh, epochHandler: *eh, tokenfactoryHandler: *th, evmHandler: *evmh, @@ -70,6 +75,72 @@ func (qp QueryPlugin) HandleOracleQuery(ctx sdk.Context, queryData json.RawMessa } } +func (qp QueryPlugin) HandleDexQuery(ctx sdk.Context, queryData json.RawMessage) ([]byte, error) { + var parsedQuery dexbindings.SeiDexQuery + if err := json.Unmarshal(queryData, &parsedQuery); err != nil { + return nil, dextypes.ErrParsingSeiDexQuery + } + switch { + case parsedQuery.DexTwaps != nil: + res, err := qp.dexHandler.GetDexTwap(ctx, parsedQuery.DexTwaps) + if err != nil { + return nil, err + } + bz, err := json.Marshal(res) + if err != nil { + return nil, dextypes.ErrEncodingDexTwaps + } + + return bz, nil + case parsedQuery.GetOrders != nil: + res, err := qp.dexHandler.GetOrders(ctx, parsedQuery.GetOrders) + if err != nil { + return nil, err + } + bz, err := json.Marshal(res) + if err != nil { + return nil, dextypes.ErrEncodingOrders + } + + return bz, nil + case parsedQuery.GetOrderByID != nil: + res, err := qp.dexHandler.GetOrderByID(ctx, parsedQuery.GetOrderByID) + if err != nil { + return nil, err + } + bz, err := json.Marshal(res) + if err != nil { + return nil, dextypes.ErrEncodingOrder + } + + return bz, nil + case parsedQuery.GetOrderSimulation != nil: + res, err := qp.dexHandler.GetOrderSimulation(ctx, parsedQuery.GetOrderSimulation) + if err != nil { + return nil, err + } + bz, err := json.Marshal(res) + if err != nil { + return nil, dextypes.ErrEncodingOrderSimulation + } + + return bz, nil + case parsedQuery.GetLatestPrice != nil: + res, err := qp.dexHandler.GetLatestPrice(ctx, parsedQuery.GetLatestPrice) + if err != nil { + return nil, err + } + bz, err := json.Marshal(res) + if err != nil { + return nil, dextypes.ErrEncodingLatestPrice + } + + return bz, nil + default: + return nil, dextypes.ErrUnknownSeiDexQuery + } +} + func (qp QueryPlugin) HandleEpochQuery(ctx sdk.Context, queryData json.RawMessage) ([]byte, error) { var parsedQuery epochbindings.SeiEpochQuery if err := json.Unmarshal(queryData, &parsedQuery); err != nil { diff --git a/wasmbinding/query_plugin.go b/wasmbinding/query_plugin.go index aa24663be..db21e9404 100644 --- a/wasmbinding/query_plugin.go +++ b/wasmbinding/query_plugin.go @@ -10,6 +10,7 @@ import ( const ( OracleRoute = "oracle" + DexRoute = "dex" EpochRoute = "epoch" TokenFactoryRoute = "tokenfactory" EVMRoute = "evm" @@ -31,6 +32,8 @@ func CustomQuerier(qp *QueryPlugin) func(ctx sdk.Context, request json.RawMessag switch contractQuery.Route { case OracleRoute: return qp.HandleOracleQuery(ctx, contractQuery.QueryData) + case DexRoute: + return qp.HandleDexQuery(ctx, contractQuery.QueryData) case EpochRoute: return qp.HandleEpochQuery(ctx, contractQuery.QueryData) case TokenFactoryRoute: diff --git a/wasmbinding/test/encoder_test.go b/wasmbinding/test/encoder_test.go index 0e55393cb..439c3a707 100644 --- a/wasmbinding/test/encoder_test.go +++ b/wasmbinding/test/encoder_test.go @@ -6,6 +6,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sei-protocol/sei-chain/wasmbinding/bindings" + dexwasm "github.com/sei-protocol/sei-chain/x/dex/client/wasm" + "github.com/sei-protocol/sei-chain/x/dex/types" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" tokenfactorywasm "github.com/sei-protocol/sei-chain/x/tokenfactory/client/wasm" tokenfactorytypes "github.com/sei-protocol/sei-chain/x/tokenfactory/types" "github.com/stretchr/testify/require" @@ -16,6 +19,71 @@ const ( TEST_CREATOR = "sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw" ) +func TestEncodePlaceOrder(t *testing.T) { + contractAddr, err := sdk.AccAddressFromBech32("sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw") + require.NoError(t, err) + order := dextypes.Order{ + PositionDirection: dextypes.PositionDirection_LONG, + OrderType: dextypes.OrderType_LIMIT, + PriceDenom: "USDC", + AssetDenom: "SEI", + Price: sdk.MustNewDecFromStr("10"), + 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{ + Orders: []*dextypes.Order{&order}, + Funds: []sdk.Coin{fund}, + ContractAddr: TEST_TARGET_CONTRACT, + } + serializedMsg, _ := json.Marshal(msg) + + decodedMsgs, err := dexwasm.EncodeDexPlaceOrders(serializedMsg, contractAddr) + require.NoError(t, err) + require.Equal(t, 1, len(decodedMsgs)) + typedDecodedMsg, ok := decodedMsgs[0].(*dextypes.MsgPlaceOrders) + require.True(t, ok) + expectedMsg := dextypes.MsgPlaceOrders{ + Creator: TEST_CREATOR, + Orders: []*dextypes.Order{&order}, + ContractAddr: TEST_TARGET_CONTRACT, + Funds: []sdk.Coin{fund}, + } + require.Equal(t, expectedMsg, *typedDecodedMsg) +} + +func TestDecodeOrderCancellation(t *testing.T) { + contractAddr, err := sdk.AccAddressFromBech32("sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw") + require.NoError(t, err) + msg := bindings.CancelOrders{ + Cancellations: []*types.Cancellation{ + {Id: 1}, + }, + ContractAddr: TEST_TARGET_CONTRACT, + } + serializedMsg, _ := json.Marshal(msg) + + decodedMsgs, err := dexwasm.EncodeDexCancelOrders(serializedMsg, contractAddr) + require.NoError(t, err) + require.Equal(t, 1, len(decodedMsgs)) + typedDecodedMsg, ok := decodedMsgs[0].(*dextypes.MsgCancelOrders) + require.True(t, ok) + expectedMsg := dextypes.MsgCancelOrders{ + Creator: TEST_CREATOR, + Cancellations: []*types.Cancellation{ + {Id: 1, Price: sdk.ZeroDec()}, + }, + ContractAddr: TEST_TARGET_CONTRACT, + } + require.Equal(t, expectedMsg.Creator, typedDecodedMsg.Creator) + require.Equal(t, *expectedMsg.Cancellations[0], *typedDecodedMsg.Cancellations[0]) + require.Equal(t, expectedMsg.ContractAddr, typedDecodedMsg.ContractAddr) +} + func TestEncodeCreateDenom(t *testing.T) { contractAddr, err := sdk.AccAddressFromBech32("sei1y3pxq5dp900czh0mkudhjdqjq5m8cpmmps8yjw") require.NoError(t, err) diff --git a/wasmbinding/test/query_test.go b/wasmbinding/test/query_test.go index d02a72f1c..c4dd219bb 100644 --- a/wasmbinding/test/query_test.go +++ b/wasmbinding/test/query_test.go @@ -1,6 +1,7 @@ package wasmbinding import ( + "context" "encoding/json" "fmt" "testing" @@ -11,7 +12,13 @@ import ( "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sei-protocol/sei-chain/app" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" "github.com/sei-protocol/sei-chain/wasmbinding" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + dexwasm "github.com/sei-protocol/sei-chain/x/dex/client/wasm" + dexbinding "github.com/sei-protocol/sei-chain/x/dex/client/wasm/bindings" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" epochwasm "github.com/sei-protocol/sei-chain/x/epoch/client/wasm" epochbinding "github.com/sei-protocol/sei-chain/x/epoch/client/wasm/bindings" epochtypes "github.com/sei-protocol/sei-chain/x/epoch/types" @@ -33,10 +40,11 @@ func SetupWasmbindingTest(t *testing.T) (*app.TestWrapper, func(ctx sdk.Context, testWrapper := app.NewTestWrapper(t, tm, valPub, false) oh := oraclewasm.NewOracleWasmQueryHandler(&testWrapper.App.OracleKeeper) + dh := dexwasm.NewDexWasmQueryHandler(&testWrapper.App.DexKeeper) eh := epochwasm.NewEpochWasmQueryHandler(&testWrapper.App.EpochKeeper) th := tokenfactorywasm.NewTokenFactoryWasmQueryHandler(&testWrapper.App.TokenFactoryKeeper) evmh := evmwasm.NewEVMQueryHandler(&testWrapper.App.EvmKeeper) - qp := wasmbinding.NewQueryPlugin(oh, eh, th, evmh) + qp := wasmbinding.NewQueryPlugin(oh, dh, eh, th, evmh) return testWrapper, wasmbinding.CustomQuerier(qp) } @@ -54,6 +62,17 @@ func TestWasmUnknownQuery(t *testing.T) { require.Error(t, err) require.Equal(t, err, oracletypes.ErrUnknownSeiOracleQuery) + dex_req := dexbinding.SeiDexQuery{} + queryData, err = json.Marshal(dex_req) + require.NoError(t, err) + query = wasmbinding.SeiQueryWrapper{Route: wasmbinding.DexRoute, QueryData: queryData} + rawQuery, err = json.Marshal(query) + require.NoError(t, err) + + _, err = customQuerier(testWrapper.Ctx, rawQuery) + require.Error(t, err) + require.Equal(t, err, dextypes.ErrUnknownSeiDexQuery) + epoch_req := epochbinding.SeiEpochQuery{} queryData, err = json.Marshal(epoch_req) require.NoError(t, err) @@ -161,6 +180,116 @@ func TestWasmGetOracleTwapsErrorHandling(t *testing.T) { require.Equal(t, err, oracletypes.ErrInvalidTwapLookback) } +func TestWasmGetDexTwaps(t *testing.T) { + testWrapper, customQuerier := SetupWasmbindingTest(t) + + req := dexbinding.SeiDexQuery{DexTwaps: &dextypes.QueryGetTwapsRequest{ + ContractAddr: app.TestContract, + LookbackSeconds: 200, + }} + queryData, err := json.Marshal(req) + require.NoError(t, err) + query := wasmbinding.SeiQueryWrapper{Route: wasmbinding.DexRoute, QueryData: queryData} + + rawQuery, err := json.Marshal(query) + require.NoError(t, err) + + testWrapper.Ctx = testWrapper.Ctx.WithBlockHeight(11).WithBlockTime(time.Unix(3600, 0)) + testWrapper.App.DexKeeper.AddRegisteredPair( + testWrapper.Ctx, + app.TestContract, + dextypes.Pair{PriceDenom: "sei", AssetDenom: "atom"}, + ) + testWrapper.App.DexKeeper.SetPriceState(testWrapper.Ctx, dextypes.Price{ + SnapshotTimestampInSeconds: 3600, + Price: sdk.NewDec(20), + Pair: &dextypes.Pair{PriceDenom: "sei", AssetDenom: "atom"}, + }, app.TestContract) + testWrapper.App.OracleKeeper.SetBaseExchangeRate(testWrapper.Ctx, oracleutils.MicroAtomDenom, sdk.NewDec(12)) + testWrapper.Ctx = testWrapper.Ctx.WithBlockHeight(14).WithBlockTime(time.Unix(3700, 0)) + + res, err := customQuerier(testWrapper.Ctx, rawQuery) + require.NoError(t, err) + + var parsedRes dextypes.QueryGetTwapsResponse + err = json.Unmarshal(res, &parsedRes) + require.NoError(t, err) + require.Equal(t, 1, len(parsedRes.Twaps)) + twap := *parsedRes.Twaps[0] + require.Equal(t, "sei", twap.Pair.PriceDenom) + require.Equal(t, "atom", twap.Pair.AssetDenom) + require.Equal(t, sdk.NewDec(20), twap.Twap) +} + +func TestWasmDexGetOrderByIdErrorHandling(t *testing.T) { + testWrapper, customQuerier := SetupWasmbindingTest(t) + + req := dexbinding.SeiDexQuery{GetOrderByID: &dextypes.QueryGetOrderByIDRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Id: 1, + }} + queryData, err := json.Marshal(req) + require.NoError(t, err) + query := wasmbinding.SeiQueryWrapper{Route: wasmbinding.DexRoute, QueryData: queryData} + + rawQuery, err := json.Marshal(query) + require.NoError(t, err) + + _, err = customQuerier(testWrapper.Ctx, rawQuery) + require.Error(t, err) + require.IsType(t, dextypes.ErrInvalidOrderID, err) +} + +func TestWasmGetOrderSimulation(t *testing.T) { + testWrapper, customQuerier := SetupWasmbindingTest(t) + + order := dextypes.Order{ + PositionDirection: dextypes.PositionDirection_LONG, + OrderType: dextypes.OrderType_LIMIT, + PriceDenom: "USDC", + AssetDenom: "SEI", + Price: sdk.MustNewDecFromStr("10"), + Quantity: sdk.OneDec(), + Data: "{\"position_effect\":\"OPEN\", \"leverage\":\"1\"}", + } + + req := dexbinding.SeiDexQuery{GetOrderSimulation: &dextypes.QueryOrderSimulationRequest{ + Order: &order, + }} + queryData, err := json.Marshal(req) + require.NoError(t, err) + query := wasmbinding.SeiQueryWrapper{Route: wasmbinding.DexRoute, QueryData: queryData} + + rawQuery, err := json.Marshal(query) + require.NoError(t, err) + + testWrapper.Ctx = testWrapper.Ctx.WithBlockHeight(11).WithBlockTime(time.Unix(3600, 0)) + testWrapper.Ctx = testWrapper.Ctx.WithContext(context.WithValue(testWrapper.Ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testWrapper.App.GetMemKey(dextypes.MemStoreKey)))) + testWrapper.App.DexKeeper.AddRegisteredPair( + testWrapper.Ctx, + app.TestContract, + dextypes.Pair{PriceDenom: "sei", AssetDenom: "atom"}, + ) + testWrapper.App.DexKeeper.SetPriceState(testWrapper.Ctx, dextypes.Price{ + SnapshotTimestampInSeconds: 3600, + Price: sdk.NewDec(20), + Pair: &dextypes.Pair{PriceDenom: "sei", AssetDenom: "atom"}, + }, app.TestContract) + testWrapper.App.OracleKeeper.SetBaseExchangeRate(testWrapper.Ctx, oracleutils.MicroAtomDenom, sdk.NewDec(12)) + testWrapper.Ctx = testWrapper.Ctx.WithBlockHeight(14).WithBlockTime(time.Unix(3700, 0)) + testWrapper.Ctx = testWrapper.Ctx.WithContext(context.WithValue(testWrapper.Ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testWrapper.App.GetMemKey(dextypes.MemStoreKey)))) + + res, err := customQuerier(testWrapper.Ctx, rawQuery) + require.NoError(t, err) + + var parsedRes dextypes.QueryOrderSimulationResponse + err = json.Unmarshal(res, &parsedRes) + require.NoError(t, err) + require.Equal(t, sdk.NewDec(0), *parsedRes.ExecutedQuantity) +} + func TestWasmGetEpoch(t *testing.T) { testWrapper, customQuerier := SetupWasmbindingTest(t) diff --git a/wasmbinding/wasm.go b/wasmbinding/wasm.go index bc2d492f2..0d50fb0cb 100644 --- a/wasmbinding/wasm.go +++ b/wasmbinding/wasm.go @@ -7,6 +7,8 @@ import ( codectypes "github.com/cosmos/cosmos-sdk/codec/types" aclkeeper "github.com/cosmos/cosmos-sdk/x/accesscontrol/keeper" authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + dexwasm "github.com/sei-protocol/sei-chain/x/dex/client/wasm" + dexkeeper "github.com/sei-protocol/sei-chain/x/dex/keeper" epochwasm "github.com/sei-protocol/sei-chain/x/epoch/client/wasm" epochkeeper "github.com/sei-protocol/sei-chain/x/epoch/keeper" evmwasm "github.com/sei-protocol/sei-chain/x/evm/client/wasm" @@ -19,6 +21,7 @@ import ( func RegisterCustomPlugins( oracle *oraclekeeper.Keeper, + dex *dexkeeper.Keeper, epoch *epochkeeper.Keeper, tokenfactory *tokenfactorykeeper.Keeper, _ *authkeeper.AccountKeeper, @@ -31,11 +34,12 @@ func RegisterCustomPlugins( aclKeeper aclkeeper.Keeper, evmKeeper *evmkeeper.Keeper, ) []wasmkeeper.Option { + dexHandler := dexwasm.NewDexWasmQueryHandler(dex) oracleHandler := oraclewasm.NewOracleWasmQueryHandler(oracle) epochHandler := epochwasm.NewEpochWasmQueryHandler(epoch) tokenfactoryHandler := tokenfactorywasm.NewTokenFactoryWasmQueryHandler(tokenfactory) evmHandler := evmwasm.NewEVMQueryHandler(evmKeeper) - wasmQueryPlugin := NewQueryPlugin(oracleHandler, epochHandler, tokenfactoryHandler, evmHandler) + wasmQueryPlugin := NewQueryPlugin(oracleHandler, dexHandler, epochHandler, tokenfactoryHandler, evmHandler) queryPluginOpt := wasmkeeper.WithQueryPlugins(&wasmkeeper.QueryPlugins{ Custom: CustomQuerier(wasmQueryPlugin), diff --git a/x/dex/README.md b/x/dex/README.md new file mode 100644 index 000000000..fd623e859 --- /dev/null +++ b/x/dex/README.md @@ -0,0 +1,57 @@ +## Abstract + +Provides fast order matching for CosmWasm contracts. + +## Contents +`dex` provides order placement/cancellation/settlement capabilities for registered contracts, as well as exchange price resulting from the order matching. The implementation of the exchange logic and store writes happen at the end of each block, based on in-memory data passed on by `dex` transactions in the same block. In other words, `DeliverTx` only adds data to memory (a custom data structure, not Cosmos's cache store), and +`EndBlock` uses those in-memory data to perform batched order matching. The `EndBlock` order matching process also involves calling `Sudo` endpoints defined on the registerd contracts, as long as those endpoints conform with the expected interface, so that the registered contracts can perform custom logic based on the exchange information. + +## Concepts +Contract Registration +A contract can be registered with `MsgRegisterContract` type. There are a few related concepts: +### Order-related Sudo Calls +For `dex` to perform order matching for a registered contract, it MUST define 3 `Sudo` endpoints: +- "bulk_order_placements": payload expected can be found in [x/dex/types/order_placement.go] +- "bulk_order_cancellations": payload expected can be found in [x/dex/types/order_cancellation.go] +- "settlement": payload expected can be found in [x/dex/types/settlement.go] +If any of the three endpoints is missing, or if the endpoint is ill-defined, `dex` will skip the contract's order matching. +### Asset Pair Registration +A contract may define one or more tradable pairs with `dex`. For example, a spot trading contract may define a pair with price denomination `USDC` and asset denomination `BTC`. The exact semantics for asset pair registration can be found in the `Governance` section below. A contract with no registered pair is valid - it simply won't have any trading activity in `dex`. +### Rent +A contract must deposit a certain amount of `usei` into `dex` upon registration or through subsequent top-ups. Those `usei`, also known as rent, will be consumed when the contract's `Sudo` endpoints are called based on the gas meter reading, and distributed to Sei validators. Note that if a `Sudo` endpoint fails, it would still charge rent for whatever the gas meter has already recorded before the failure happens. +### Contract Dependencies +A contract may dispatch messages to other contracts as part of its `Sudo` call responses. If that is the case, the contract must declare those other contracts as `Dependencies` in its registration. No circular dependency is allowed. `dex` will check if a dispatched message is against a declared dependency contract, and reject it if it's not declared. +## Batch Order Matching +Orders submitted via MsgPlaceOrders are aggregated at the end of a block and matched in batch. +### Sequence +TODO +### Clearing/Settlement Rules +TODO +## State + +## Governance + +Token pairs can be whitelisted with a contract address to the `dex` module via governance. The following is an example +proposal json to whitelist a token pair. + +```json + "dex": { + "params": { + "code_upload_access": { + "permission": "Everybody" + }, + "instantiate_default_permission": "Everybody" + } + }, +``` + +## Messages + +## Events + +## Parameters + +## Transactions + +## Queries + diff --git a/x/dex/ante.go b/x/dex/ante.go new file mode 100644 index 000000000..07e891f42 --- /dev/null +++ b/x/dex/ante.go @@ -0,0 +1,178 @@ +package dex + +import ( + "errors" + "math/big" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkacltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/sei-protocol/sei-chain/x/dex/utils" +) + +// TickSizeMultipleDecorator check if the place order tx's price is multiple of +// tick size +type TickSizeMultipleDecorator struct { + dexKeeper keeper.Keeper +} + +// NewTickSizeMultipleDecorator returns new ticksize multiple check decorator instance +func NewTickSizeMultipleDecorator(dexKeeper keeper.Keeper) TickSizeMultipleDecorator { + return TickSizeMultipleDecorator{ + dexKeeper: dexKeeper, + } +} + +// AnteHandle is the interface called in RunTx() function, which CheckTx() calls with the runTxModeCheck mode +func (tsmd TickSizeMultipleDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + if ctx.IsReCheckTx() { + return next(ctx, tx, simulate) + } + if !simulate { + if ctx.IsCheckTx() { + err := tsmd.CheckTickSizeMultiple(ctx, tx.GetMsgs()) + if err != nil { + return ctx, err + } + } + } + return next(ctx, tx, simulate) +} + +// CheckTickSizeMultiple checks whether the msgs comply with ticksize +func (tsmd TickSizeMultipleDecorator) CheckTickSizeMultiple(ctx sdk.Context, msgs []sdk.Msg) error { + for _, msg := range msgs { + switch msg.(type) { //nolint:gocritic,gosimple // the linter is telling us we can make this faster, and this should be addressed later. + case *types.MsgPlaceOrders: + msgPlaceOrders := msg.(*types.MsgPlaceOrders) //nolint:gosimple // the linter is telling us we can make this faster, and this should be addressed later. + contractAddr := msgPlaceOrders.ContractAddr + for _, order := range msgPlaceOrders.Orders { + priceTickSize, found := tsmd.dexKeeper.GetPriceTickSizeForPair(ctx, contractAddr, + types.Pair{ + PriceDenom: order.PriceDenom, + AssetDenom: order.AssetDenom, + }) + if !found { + return sdkerrors.Wrapf(sdkerrors.ErrKeyNotFound, "the pair {price:%s,asset:%s} has no price ticksize configured", order.PriceDenom, order.AssetDenom) + } + if !IsDecimalMultipleOf(order.Price, priceTickSize) { + // Allow Market Orders with Price 0 + if !(IsMarketOrder(order) && order.Price.IsZero()) { + return sdkerrors.Wrapf(errors.New("ErrPriceNotMultipleOfTickSize"), "price needs to be non-zero and multiple of price tick size") + } + } + quantityTickSize, found := tsmd.dexKeeper.GetQuantityTickSizeForPair(ctx, contractAddr, + types.Pair{ + PriceDenom: order.PriceDenom, + AssetDenom: order.AssetDenom, + }) + if !found { + return sdkerrors.Wrapf(sdkerrors.ErrKeyNotFound, "the pair {price:%s,asset:%s} has no quantity ticksize configured", order.PriceDenom, order.AssetDenom) + } + if !IsDecimalMultipleOf(order.Quantity, quantityTickSize) { + return sdkerrors.Wrapf(errors.New("ErrQuantityNotMultipleOfTickSize"), "quantity needs to be non-zero and multiple of quantity tick size") + } + } + continue + default: + // e.g. liquidation order don't come with price so always pass this check + return nil + } + } + + return nil +} + +// Check whether order is market order type +func IsMarketOrder(order *types.Order) bool { + return order.OrderType == types.OrderType_MARKET || order.OrderType == types.OrderType_FOKMARKET || order.OrderType == types.OrderType_FOKMARKETBYVALUE +} + +// Check whether decimal a is multiple of decimal b +func IsDecimalMultipleOf(a, b sdk.Dec) bool { + if a.LT(b) { + return false + } + quotient := sdk.NewDecFromBigInt(a.Quo(b).RoundInt().BigInt()) + return quotient.Mul(b).Equal(a) +} + +const DexGasFeeUnit = "usei" + +type CheckDexGasDecorator struct { + dexKeeper keeper.Keeper + checkTxMemState *dexcache.MemState +} + +func NewCheckDexGasDecorator(dexKeeper keeper.Keeper, checkTxMemState *dexcache.MemState) CheckDexGasDecorator { + return CheckDexGasDecorator{ + dexKeeper: dexKeeper, + checkTxMemState: checkTxMemState, + } +} + +// for a TX that contains dex gas-incurring messages, check if it provides enough gas based on dex params +func (d CheckDexGasDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + if ctx.IsReCheckTx() { + return next(ctx, tx, simulate) + } + params := d.dexKeeper.GetParams(ctx) + dexGasRequired := uint64(0) + var memState *dexcache.MemState + if ctx.IsCheckTx() { + memState = d.checkTxMemState + } else { + memState = utils.GetMemState(ctx.Context()) + } + for _, msg := range tx.GetMsgs() { + switch m := msg.(type) { + case *types.MsgPlaceOrders: + numDependencies := len(memState.GetContractToDependencies(ctx, m.ContractAddr, d.dexKeeper.GetContractWithoutGasCharge)) + dexGasRequired += params.DefaultGasPerOrder * uint64(len(m.Orders)*numDependencies) + for _, order := range m.Orders { + dexGasRequired += params.DefaultGasPerOrderDataByte * uint64(len(order.Data)) + } + case *types.MsgCancelOrders: + numDependencies := len(memState.GetContractToDependencies(ctx, m.ContractAddr, d.dexKeeper.GetContractWithoutGasCharge)) + dexGasRequired += params.DefaultGasPerCancel * uint64(len(m.Cancellations)*numDependencies) + } + } + if dexGasRequired == 0 { + return next(ctx, tx, simulate) + } + dexFeeRequired := sdk.NewDecFromBigInt(new(big.Int).SetUint64(dexGasRequired)).Mul(params.SudoCallGasPrice).RoundInt() + feeTx, ok := tx.(sdk.FeeTx) + if !ok { + return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") + } + for _, fee := range feeTx.GetFee() { + if fee.Denom == DexGasFeeUnit && fee.Amount.GTE(dexFeeRequired) { + return next(ctx, tx, simulate) + } + } + return ctx, sdkerrors.ErrInsufficientFee +} + +func (d CheckDexGasDecorator) AnteDeps(txDeps []sdkacltypes.AccessOperation, tx sdk.Tx, txIndex int, next sdk.AnteDepGenerator) (newTxDeps []sdkacltypes.AccessOperation, err error) { + deps := []sdkacltypes.AccessOperation{} + for _, msg := range tx.GetMsgs() { + // Error checking will be handled in AnteHandler + switch msg.(type) { + case *types.MsgPlaceOrders, *types.MsgCancelOrders: + deps = append(deps, []sdkacltypes.AccessOperation{ + // read the dex contract info + { + ResourceType: sdkacltypes.ResourceType_KV_DEX_CONTRACT, + AccessType: sdkacltypes.AccessType_READ, + IdentifierTemplate: "*", + }, + }...) + default: + continue + } + } + return next(append(txDeps, deps...), tx, txIndex) +} diff --git a/x/dex/ante_test.go b/x/dex/ante_test.go new file mode 100644 index 000000000..4d9ab4205 --- /dev/null +++ b/x/dex/ante_test.go @@ -0,0 +1,283 @@ +package dex_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/x/dex" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +type TestTx struct { + msgs []sdk.Msg + gas uint64 + fee sdk.Coins +} + +func (tx TestTx) GetMsgs() []sdk.Msg { + return tx.msgs +} + +func (tx TestTx) ValidateBasic() error { + return nil +} + +func (tx TestTx) GetGas() uint64 { + return tx.gas +} +func (tx TestTx) GetFee() sdk.Coins { + return tx.fee +} +func (tx TestTx) FeePayer() sdk.AccAddress { + return nil +} +func (tx TestTx) FeeGranter() sdk.AccAddress { + return nil +} + +func TestIsDecimalMultipleOf(t *testing.T) { + v1, _ := sdk.NewDecFromStr("2.4") + v2, _ := sdk.NewDecFromStr("1.2") + v3, _ := sdk.NewDecFromStr("2") + v4, _ := sdk.NewDecFromStr("100.5") + v5, _ := sdk.NewDecFromStr("0.5") + v6, _ := sdk.NewDecFromStr("1.5") + v7, _ := sdk.NewDecFromStr("1.01") + v8, _ := sdk.NewDecFromStr("3") + v9, _ := sdk.NewDecFromStr("5.4") + v10, _ := sdk.NewDecFromStr("0.3") + + assert.True(t, dex.IsDecimalMultipleOf(v1, v2)) + assert.True(t, !dex.IsDecimalMultipleOf(v2, v1)) + assert.True(t, !dex.IsDecimalMultipleOf(v3, v2)) + assert.True(t, dex.IsDecimalMultipleOf(v3, v5)) + assert.True(t, !dex.IsDecimalMultipleOf(v3, v6)) + assert.True(t, dex.IsDecimalMultipleOf(v4, v5)) + assert.True(t, !dex.IsDecimalMultipleOf(v2, v1)) + assert.True(t, dex.IsDecimalMultipleOf(v6, v5)) + assert.True(t, !dex.IsDecimalMultipleOf(v7, v3)) + assert.True(t, dex.IsDecimalMultipleOf(v8, v6)) + assert.True(t, dex.IsDecimalMultipleOf(v9, v10)) +} + +func TestCheckDexGasDecorator(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + decorator := dex.NewCheckDexGasDecorator(*keeper, dexcache.NewMemState(keeper.GetMemStoreKey())) + terminator := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { return ctx, nil } + tx := TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{}, {}}, keepertest.TestContract, sdk.NewCoins()), + types.NewMsgCancelOrders("someone", []*types.Cancellation{{}, {}, {}}, keepertest.TestContract), + }, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err := decorator.AnteHandle(ctx, tx, false, terminator) + require.Nil(t, err) + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{}, {}}, keepertest.TestContract, sdk.NewCoins()), + types.NewMsgCancelOrders("someone", []*types.Cancellation{{}, {}, {}}, keepertest.TestContract), + }, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(25499))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.NotNil(t, err) + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{}}, keepertest.TestContract, sdk.NewCoins()), + }, + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.NotNil(t, err) + tx = TestTx{ + msgs: []sdk.Msg{}, + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.Nil(t, err) + tx = TestTx{ + msgs: []sdk.Msg{types.NewMsgContractDepositRent(keepertest.TestContract, 10, keepertest.TestAccount)}, + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.Nil(t, err) + + // with data (insufficient fee) + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{Data: "data"}, {}}, keepertest.TestContract, sdk.NewCoins()), + }, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(11011))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.NotNil(t, err) + + // with data (sufficient fee) + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{Data: "data"}, {}}, keepertest.TestContract, sdk.NewCoins()), + }, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(11012))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.Nil(t, err) +} + +func TestTickSizeMultipleDecorator(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithIsCheckTx(true) + decorator := dex.NewTickSizeMultipleDecorator(*keeper) + terminator := func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { return ctx, nil } + + keeper.AddRegisteredPair(ctx, "contract", keepertest.TestPair) + keeper.SetPriceTickSizeForPair(ctx, "contract", keepertest.TestPair, *keepertest.TestPair.PriceTicksize) + keeper.SetQuantityTickSizeForPair(ctx, "contract", keepertest.TestPair, *keepertest.TestPair.PriceTicksize) + + price, _ := sdk.NewDecFromStr("25") + quantity, _ := sdk.NewDecFromStr("5") + smallerVal, _ := sdk.NewDecFromStr("0.01") + + // Market order with price zero allowed + tx := TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{ + ContractAddr: "contract", + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Price: sdk.ZeroDec(), + Quantity: quantity, + OrderType: types.OrderType_MARKET, + }}, "contract", sdk.NewCoins())}, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err := decorator.AnteHandle(ctx, tx, false, terminator) + require.Nil(t, err) + + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{ + ContractAddr: "contract", + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Price: sdk.ZeroDec(), + Quantity: quantity, + OrderType: types.OrderType_FOKMARKET, + }}, "contract", sdk.NewCoins())}, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.Nil(t, err) + + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{ + ContractAddr: "contract", + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Price: sdk.ZeroDec(), + Quantity: quantity, + OrderType: types.OrderType_FOKMARKETBYVALUE, + }}, "contract", sdk.NewCoins())}, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.Nil(t, err) + + // Non-market orders with price zero not allowed + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{ + ContractAddr: "contract", + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Price: sdk.ZeroDec(), + Quantity: quantity, + OrderType: types.OrderType_LIMIT, + }}, "contract", sdk.NewCoins())}, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.NotNil(t, err) + + // Non-zero Priced Market Order With Divisible Price + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{ + ContractAddr: "contract", + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Price: price, + Quantity: quantity, + OrderType: types.OrderType_MARKET, + }}, "contract", sdk.NewCoins())}, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.Nil(t, err) + + // Non-zero Priced Market Order Without Divisible Price + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{ + ContractAddr: "contract", + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Price: smallerVal, + Quantity: quantity, + OrderType: types.OrderType_MARKET, + }}, "contract", sdk.NewCoins())}, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.NotNil(t, err) + + // Limit Order With Divisible Price + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{ + ContractAddr: "contract", + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Price: price, + Quantity: quantity, + OrderType: types.OrderType_LIMIT, + }}, "contract", sdk.NewCoins())}, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.Nil(t, err) + + // Limit Orders without Divisible Price + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{ + ContractAddr: "contract", + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Price: smallerVal, + Quantity: quantity, + OrderType: types.OrderType_LIMIT, + }}, "contract", sdk.NewCoins())}, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.NotNil(t, err) + + // All order quantities must be divisible by quantity tick size + tx = TestTx{ + msgs: []sdk.Msg{ + types.NewMsgPlaceOrders("someone", []*types.Order{{ + ContractAddr: "contract", + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Price: price, + Quantity: smallerVal, + OrderType: types.OrderType_LIMIT, + }}, "contract", sdk.NewCoins())}, + fee: sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(27500))), + } + _, err = decorator.AnteHandle(ctx, tx, false, terminator) + require.NotNil(t, err) +} diff --git a/x/dex/cache/cache.go b/x/dex/cache/cache.go new file mode 100644 index 000000000..915843d9c --- /dev/null +++ b/x/dex/cache/cache.go @@ -0,0 +1,318 @@ +package dex + +import ( + "fmt" + "sync" + "time" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/sei-protocol/sei-chain/utils/datastructures" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +const SynchronizationTimeoutInSeconds = 5 + +type MemState struct { + storeKey sdk.StoreKey + + // TODO: all of these need to be in the memstore + contractsToProcessMtx *sync.RWMutex + contractsToDepsMtx *sync.Mutex +} + +func NewMemState(storeKey sdk.StoreKey) *MemState { + return &MemState{ + storeKey: storeKey, + contractsToDepsMtx: &sync.Mutex{}, + contractsToProcessMtx: &sync.RWMutex{}, + } +} + +func (s *MemState) GetAllBlockOrders(ctx sdk.Context, contractAddr types.ContractAddress) (list []*types.Order) { + s.SynchronizeAccess(ctx, contractAddr) + store := prefix.NewStore( + ctx.KVStore(s.storeKey), + types.MemOrderPrefix( + string(contractAddr), + ), + ) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Order + if err := val.Unmarshal(iterator.Value()); err != nil { + panic(err) + } + list = append(list, &val) + } + return +} + +func (s *MemState) GetBlockOrders(ctx sdk.Context, contractAddr types.ContractAddress, pair types.Pair) *BlockOrders { + s.SynchronizeAccess(ctx, contractAddr) + return NewOrders( + prefix.NewStore( + ctx.KVStore(s.storeKey), + types.MemOrderPrefixForPair( + string(contractAddr), pair.PriceDenom, pair.AssetDenom, + ), + ), + ) +} + +func (s *MemState) GetBlockCancels(ctx sdk.Context, contractAddr types.ContractAddress, pair types.Pair) *BlockCancellations { + s.SynchronizeAccess(ctx, contractAddr) + return NewCancels( + prefix.NewStore( + ctx.KVStore(s.storeKey), + types.MemCancelPrefixForPair( + string(contractAddr), pair.PriceDenom, pair.AssetDenom, + ), + ), + ) +} + +func (s *MemState) GetDepositInfo(ctx sdk.Context, contractAddr types.ContractAddress) *DepositInfo { + s.SynchronizeAccess(ctx, contractAddr) + return NewDepositInfo( + prefix.NewStore( + ctx.KVStore(s.storeKey), + types.MemDepositPrefix(string(contractAddr)), + ), + ) +} + +func (s *MemState) GetContractToDependencies(ctx sdk.Context, contractAddress string, loader func(sdk.Context, string) (types.ContractInfoV2, error)) []string { + s.contractsToDepsMtx.Lock() + defer s.contractsToDepsMtx.Unlock() + + store := ctx.KVStore(s.storeKey) + + // GET from memstate + bz := store.Get(types.MemDownstreamContractsKey(contractAddress)) + if bz != nil { + var contracts types.DownsteamContracts + if err := contracts.Unmarshal(bz); err != nil { + panic(err) + } + return contracts.ContractAddrs + } + loadedDownstreams := GetAllDownstreamContracts(ctx, contractAddress, loader) + // if we have to get all downstreams, save them to memstate + downstreamContracts := types.DownsteamContracts{ + ContractAddrs: loadedDownstreams, + } + contractsBz, err := downstreamContracts.Marshal() + if err != nil { + panic(err) + } + store.Set(types.MemDownstreamContractsKey(contractAddress), contractsBz) + return loadedDownstreams +} + +func (s *MemState) ClearContractToDependencies(ctx sdk.Context) { + s.contractsToDepsMtx.Lock() + defer s.contractsToDepsMtx.Unlock() + DeepDelete(ctx.KVStore(s.storeKey), types.KeyPrefix(types.MemDownstreamContracts), func(_ []byte) bool { return true }) +} + +func (s *MemState) SetDownstreamsToProcess(ctx sdk.Context, contractAddress string, loader func(sdk.Context, string) (types.ContractInfoV2, error)) { + s.contractsToProcessMtx.Lock() + defer s.contractsToProcessMtx.Unlock() + contracts := s.GetContractToDependencies(ctx, contractAddress, loader) + store := ctx.KVStore(s.storeKey) + for _, contract := range contracts { + // Add each to memstate instead - simply set to 1 for some value indicating presence + store.Set(types.MemContractsToProcessKey(contract), []byte{1}) + } +} + +func (s *MemState) ContractsToProcessContains(ctx sdk.Context, contractAddress string) bool { + s.contractsToProcessMtx.RLock() + defer s.contractsToProcessMtx.RUnlock() + store := ctx.KVStore(s.storeKey) + return store.Has(types.MemContractsToProcessKey(contractAddress)) +} + +func (s *MemState) GetContractToProcessOrderedSlice(ctx sdk.Context) []string { + s.contractsToProcessMtx.RLock() + defer s.contractsToProcessMtx.RUnlock() + orderedContracts := []string{} + store := ctx.KVStore(s.storeKey) + iter := sdk.KVStorePrefixIterator(store, types.KeyPrefix(types.MemContractsToProcess)) + for ; iter.Valid(); iter.Next() { + // get key + key := iter.Key() + // because we know length prefix is 1 byte, and the rest of the key is ONLY the contract addr, this lets us get the contract address bytes + contractAddrBytes := key[len(types.KeyPrefix(types.MemContractsToProcess))+1:] + // parse contract address from key + contractAddr := sdk.AccAddress(contractAddrBytes).String() + orderedContracts = append(orderedContracts, contractAddr) + } + return orderedContracts +} + +func (s *MemState) Clear(ctx sdk.Context) { + s.contractsToProcessMtx.Lock() + defer s.contractsToProcessMtx.Unlock() + DeepDelete(ctx.KVStore(s.storeKey), types.KeyPrefix(types.MemOrderKey), func(_ []byte) bool { return true }) + DeepDelete(ctx.KVStore(s.storeKey), types.KeyPrefix(types.MemCancelKey), func(_ []byte) bool { return true }) + DeepDelete(ctx.KVStore(s.storeKey), types.KeyPrefix(types.MemDepositKey), func(_ []byte) bool { return true }) + DeepDelete(ctx.KVStore(s.storeKey), types.KeyPrefix(types.MemContractsToProcess), func(_ []byte) bool { return true }) +} + +func (s *MemState) ClearCancellationForPair(ctx sdk.Context, contractAddr types.ContractAddress, pair types.Pair) { + s.SynchronizeAccess(ctx, contractAddr) + DeepDelete(ctx.KVStore(s.storeKey), types.KeyPrefix(types.MemCancelKey), func(v []byte) bool { + var c types.Cancellation + if err := c.Unmarshal(v); err != nil { + panic(err) + } + return c.ContractAddr == string(contractAddr) && c.PriceDenom == pair.PriceDenom && c.AssetDenom == pair.AssetDenom + }) +} + +func (s *MemState) DeepCopy() *MemState { + return &MemState{ + storeKey: s.storeKey, + contractsToDepsMtx: s.contractsToDepsMtx, // passing by pointer + contractsToProcessMtx: s.contractsToProcessMtx, // passing by pointer + } +} + +func (s *MemState) DeepFilterAccount(ctx sdk.Context, account string) { + DeepDelete(ctx.KVStore(s.storeKey), types.KeyPrefix(types.MemOrderKey), func(v []byte) bool { + var o types.Order + if err := o.Unmarshal(v); err != nil { + panic(err) + } + return o.Account == account + }) + DeepDelete(ctx.KVStore(s.storeKey), types.KeyPrefix(types.MemCancelKey), func(v []byte) bool { + var c types.Cancellation + if err := c.Unmarshal(v); err != nil { + panic(err) + } + return c.Creator == account + }) + DeepDelete(ctx.KVStore(s.storeKey), types.KeyPrefix(types.MemDepositKey), func(v []byte) bool { + var d types.DepositInfoEntry + if err := d.Unmarshal(v); err != nil { + panic(err) + } + return d.Creator == account + }) +} + +func (s *MemState) SynchronizeAccess(ctx sdk.Context, contractAddr types.ContractAddress) { + executingContract := GetExecutingContract(ctx) + if executingContract == nil { + // not accessed by contract. no need to synchronize + return + } + targetContractAddr := string(contractAddr) + if executingContract.ContractAddr == targetContractAddr { + // access by the contract itself does not need synchronization + return + } + for _, dependency := range executingContract.Dependencies { + if dependency.Dependency != targetContractAddr { + continue + } + terminationSignals := GetTerminationSignals(ctx) + if terminationSignals == nil { + // synchronization should fail in the case of no termination signal to prevent race conditions. + panic("no termination signal map found in context") + } + targetChannel, ok := terminationSignals.Load(dependency.ImmediateElderSibling) + if !ok { + // synchronization should fail in the case of no termination signal to prevent race conditions. + panic(fmt.Sprintf("no termination signal channel for contract %s in context", dependency.ImmediateElderSibling)) + } + + select { + case <-targetChannel: + // since buffered channel can only be consumed once, we need to + // requeue so that it can unblock other goroutines that waits for + // the same channel. + targetChannel <- struct{}{} + case <-time.After(SynchronizationTimeoutInSeconds * time.Second): + // synchronization should fail in the case of timeout to prevent race conditions. + panic(fmt.Sprintf("timing out waiting for termination of %s", dependency.ImmediateElderSibling)) + } + + return + } + + // fail loudly so that the offending contract can be rolled back. + // eventually we will automatically de-register contracts that have to be rolled back + // so that this would not become a point of attack in terms of performance. + panic(fmt.Sprintf("Contract %s trying to access state of %s which is not a registered dependency", executingContract.ContractAddr, targetContractAddr)) +} + +func DeepDelete(kvStore sdk.KVStore, storePrefix []byte, matcher func([]byte) bool) { + store := prefix.NewStore( + kvStore, + storePrefix, + ) + // Getting all KVs first before applying `matcher` in case `matcher` contains + // store read/write logics. + // Wrapping getter into its own function to make sure iterator is always closed + // before `matcher` logic runs. + keyValuesGetter := func() ([][]byte, [][]byte) { + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + defer iterator.Close() + keys, values := [][]byte{}, [][]byte{} + for ; iterator.Valid(); iterator.Next() { + keys = append(keys, iterator.Key()) + values = append(values, iterator.Value()) + } + return keys, values + } + keys, values := keyValuesGetter() + for i, key := range keys { + if matcher(values[i]) { + store.Delete(key) + } + } +} + +// BFS traversal over a acyclic graph +// Includes the root contract itself. +func GetAllDownstreamContracts(ctx sdk.Context, contractAddress string, loader func(sdk.Context, string) (types.ContractInfoV2, error)) []string { + res := []string{contractAddress} + seen := datastructures.NewSyncSet(res) + downstreams := []*types.ContractInfoV2{} + populater := func(target *types.ContractInfoV2) { + for _, dep := range target.Dependencies { + if downstream, err := loader(ctx, dep.Dependency); err == nil && !seen.Contains(downstream.ContractAddr) { + if !downstream.Suspended { + downstreams = append(downstreams, &downstream) + seen.Add(downstream.ContractAddr) + } + } else { + // either getting the dependency returned an error, or there is a cycle in the graph. Either way + // is bad and should cause the triggering tx to fail + panic(fmt.Sprintf("getting dependency %s for %s returned an error, or there is a cycle in the dependency graph", dep.Dependency, target.ContractAddr)) + } + } + } + // init first layer downstreams + if contract, err := loader(ctx, contractAddress); err == nil { + populater(&contract) + } else { + return res + } + + for len(downstreams) > 0 { + downstream := downstreams[0] + res = append(res, downstream.ContractAddr) + populater(downstream) + downstreams = downstreams[1:] + } + return res +} diff --git a/x/dex/cache/cache_test.go b/x/dex/cache/cache_test.go new file mode 100644 index 000000000..c6603e791 --- /dev/null +++ b/x/dex/cache/cache_test.go @@ -0,0 +1,225 @@ +package dex_test + +import ( + "context" + "testing" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/utils/datastructures" + dex "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/sei-protocol/sei-chain/x/store" + "github.com/stretchr/testify/require" +) + +const ( + TEST_CONTRACT = "test" +) + +func TestDeepCopy(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + }) + stateTwo := stateOne.DeepCopy() + cachedCtx, _ := store.GetCachedContext(ctx) + stateTwo.GetBlockOrders(cachedCtx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 2, + Account: "test", + ContractAddr: TEST_CONTRACT, + }) + // old state must not be changed + require.Equal(t, 1, len(stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get())) + // new state must be changed + require.Equal(t, 2, len(stateTwo.GetBlockOrders(cachedCtx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get())) +} + +func TestDeepFilterAccounts(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 2, + Account: "test2", + ContractAddr: TEST_CONTRACT, + }) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 1, + Creator: "test", + }) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 2, + Creator: "test2", + }) + stateOne.GetDepositInfo(ctx, types.ContractAddress(TEST_CONTRACT)).Add(&types.DepositInfoEntry{ + Creator: "test", + }) + stateOne.GetDepositInfo(ctx, types.ContractAddress(TEST_CONTRACT)).Add(&types.DepositInfoEntry{ + Creator: "test2", + }) + + stateOne.DeepFilterAccount(ctx, "test") + require.Equal(t, 1, len(stateOne.GetAllBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT)))) + require.Equal(t, 1, len(stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get())) + require.Equal(t, 1, len(stateOne.GetDepositInfo(ctx, types.ContractAddress(TEST_CONTRACT)).Get())) +} + +func TestDeepDelete(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + }) + dex.DeepDelete(ctx.KVStore(keeper.GetStoreKey()), types.KeyPrefix(types.MemOrderKey), func(_ []byte) bool { return true }) +} + +func TestClear(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + }) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 2, + ContractAddr: TEST_CONTRACT, + }) + stateOne.Clear(ctx) + require.Equal(t, 0, len(stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get())) + require.Equal(t, 0, len(stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get())) +} + +func TestClearCancellationForPair(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 1, + ContractAddr: TEST_CONTRACT, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 2, + ContractAddr: TEST_CONTRACT, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 3, + ContractAddr: TEST_CONTRACT, + PriceDenom: "USDC", + AssetDenom: "SEI", + }) + stateOne.ClearCancellationForPair(ctx, TEST_CONTRACT, types.Pair{ + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + require.Equal(t, 1, len(stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get())) + require.Equal(t, uint64(3), stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get()[0].Id) +} + +func TestSynchronization(t *testing.T) { + k, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(k.GetMemStoreKey()) + targetContract := types.ContractAddress(TEST_CONTRACT) + // no go context + require.NotPanics(t, func() { stateOne.SynchronizeAccess(ctx, targetContract) }) + // no executing contract + goCtx := context.Background() + ctx = ctx.WithContext(goCtx) + require.NotPanics(t, func() { stateOne.SynchronizeAccess(ctx, targetContract) }) + // executing contract same as target contract + executingContract := types.ContractInfoV2{ContractAddr: TEST_CONTRACT} + ctx = ctx.WithContext(context.WithValue(goCtx, dex.CtxKeyExecutingContract, executingContract)) + require.NotPanics(t, func() { stateOne.SynchronizeAccess(ctx, targetContract) }) + // executing contract attempting to access non-dependency + executingContract.ContractAddr = "executing" + ctx = ctx.WithContext(context.WithValue(goCtx, dex.CtxKeyExecutingContract, executingContract)) + require.Panics(t, func() { stateOne.SynchronizeAccess(ctx, targetContract) }) + // no termination map + executingContract.Dependencies = []*types.ContractDependencyInfo{ + {Dependency: TEST_CONTRACT, ImmediateElderSibling: "elder"}, + } + ctx = ctx.WithContext(context.WithValue(goCtx, dex.CtxKeyExecutingContract, executingContract)) + require.Panics(t, func() { stateOne.SynchronizeAccess(ctx, targetContract) }) + // no termination signal channel for sibling + terminationSignals := datastructures.NewTypedSyncMap[string, chan struct{}]() + goCtx = context.WithValue(goCtx, dex.CtxKeyExecutingContract, executingContract) + goCtx = context.WithValue(goCtx, dex.CtxKeyExecTermSignal, terminationSignals) + ctx = ctx.WithContext(goCtx) + require.Panics(t, func() { stateOne.SynchronizeAccess(ctx, targetContract) }) + // termination signal times out + siblingChan := make(chan struct{}, 1) + terminationSignals.Store("elder", siblingChan) + require.Panics(t, func() { stateOne.SynchronizeAccess(ctx, targetContract) }) + // termination signal sent + go func() { + siblingChan <- struct{}{} + }() + require.NotPanics(t, func() { stateOne.SynchronizeAccess(ctx, targetContract) }) + <-siblingChan // the channel should be re-populated +} + +func TestGetAllDownstreamContracts(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keeper.SetContract(ctx, &types.ContractInfoV2{ + ContractAddr: "sei1cnuw3f076wgdyahssdkd0g3nr96ckq8cwa2mh029fn5mgf2fmcmsae2elf", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei1ery8l6jquynn9a4cz2pff6khg8c68f7urt33l5n9dng2cwzz4c4q4hncrd", + }, + }, + }) + keeper.SetContract(ctx, &types.ContractInfoV2{ + ContractAddr: "sei1ery8l6jquynn9a4cz2pff6khg8c68f7urt33l5n9dng2cwzz4c4q4hncrd", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei1wl59k23zngj34l7d42y9yltask7rjlnxgccawc7ltrknp6n52fpsj6ctln", + }, { + Dependency: "sei1udfs22xpxle475m2nz7u47jfa3vngncdegmczwwdx00cmetypa3sman25q", + }, + }, + }) + keeper.SetContract(ctx, &types.ContractInfoV2{ + ContractAddr: "sei1wl59k23zngj34l7d42y9yltask7rjlnxgccawc7ltrknp6n52fpsj6ctln", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei1stwdtk6ja0705v8qmtukcp4vd422p5vy4jr5wdc4qk44c57k955qcannhd", + }, + }, + }) + keeper.SetContract(ctx, &types.ContractInfoV2{ + ContractAddr: "sei1stwdtk6ja0705v8qmtukcp4vd422p5vy4jr5wdc4qk44c57k955qcannhd", + }) + keeper.SetContract(ctx, &types.ContractInfoV2{ + ContractAddr: "sei1udfs22xpxle475m2nz7u47jfa3vngncdegmczwwdx00cmetypa3sman25q", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei14rse3e7rkc3qt7drmlulwlkrlzqvh7hv277zv05kyfuwl74udx5s9r7lm3", + }, + }, + Suspended: true, + }) + keeper.SetContract(ctx, &types.ContractInfoV2{ + ContractAddr: "sei14rse3e7rkc3qt7drmlulwlkrlzqvh7hv277zv05kyfuwl74udx5s9r7lm3", + }) + keeper.SetContract(ctx, &types.ContractInfoV2{ + ContractAddr: "sei182jzjwdyl5fw43yujnlljddgtrkr04dpd30ywp2yn724u7qhtaqsjev6mv", + }) + + require.Equal(t, []string{ + "sei1ery8l6jquynn9a4cz2pff6khg8c68f7urt33l5n9dng2cwzz4c4q4hncrd", + "sei1wl59k23zngj34l7d42y9yltask7rjlnxgccawc7ltrknp6n52fpsj6ctln", + "sei1stwdtk6ja0705v8qmtukcp4vd422p5vy4jr5wdc4qk44c57k955qcannhd", + }, dex.GetAllDownstreamContracts(ctx, "sei1ery8l6jquynn9a4cz2pff6khg8c68f7urt33l5n9dng2cwzz4c4q4hncrd", keeper.GetContractWithoutGasCharge)) +} diff --git a/x/dex/cache/cancel.go b/x/dex/cache/cancel.go new file mode 100644 index 000000000..ec195a46d --- /dev/null +++ b/x/dex/cache/cancel.go @@ -0,0 +1,65 @@ +package dex + +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" +) + +type BlockCancellations struct { + cancelStore *prefix.Store +} + +func NewCancels(cancelStore prefix.Store) *BlockCancellations { + return &BlockCancellations{cancelStore: &cancelStore} +} + +func (o *BlockCancellations) Has(cancel *types.Cancellation) bool { + keybz := make([]byte, 8) + binary.BigEndian.PutUint64(keybz, cancel.Id) + return o.cancelStore.Has(keybz) +} + +func (o *BlockCancellations) Get() (list []*types.Cancellation) { + iterator := sdk.KVStorePrefixIterator(o.cancelStore, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Cancellation + if err := val.Unmarshal(iterator.Value()); err != nil { + panic(err) + } + list = append(list, &val) + } + + return +} + +func (o *BlockCancellations) GetIdsToCancel() (list []uint64) { + iterator := sdk.KVStorePrefixIterator(o.cancelStore, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Cancellation + if err := val.Unmarshal(iterator.Value()); err != nil { + panic(err) + } + list = append(list, val.Id) + } + + return +} + +func (o *BlockCancellations) Add(newItem *types.Cancellation) { + keybz := make([]byte, 8) + binary.BigEndian.PutUint64(keybz, newItem.Id) + valbz, err := newItem.Marshal() + if err != nil { + panic(err) + } + o.cancelStore.Set(keybz, valbz) +} diff --git a/x/dex/cache/cancel_test.go b/x/dex/cache/cancel_test.go new file mode 100644 index 000000000..8f9d51d80 --- /dev/null +++ b/x/dex/cache/cancel_test.go @@ -0,0 +1,76 @@ +package dex_test + +import ( + "testing" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dex "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestCancelGetIdsToCancel(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 1, + Creator: "abc", + ContractAddr: TEST_CONTRACT, + }) + ids := stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).GetIdsToCancel() + require.Equal(t, 1, len(ids)) + require.Equal(t, uint64(1), ids[0]) +} + +func TestCancelGetCancels(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 1, + Creator: "abc", + ContractAddr: TEST_CONTRACT, + }) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 2, + Creator: "def", + ContractAddr: TEST_CONTRACT, + }) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 3, + Creator: "efg", + ContractAddr: TEST_CONTRACT, + }) + stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Cancellation{ + Id: 4, + Creator: "efg", + ContractAddr: TEST_CONTRACT, + }) + + cancels := stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get() + require.Equal(t, 4, len(cancels)) + require.True(t, stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Has(&types.Cancellation{ + Id: 1, + Creator: "abc", + ContractAddr: TEST_CONTRACT, + })) + require.True(t, stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Has(&types.Cancellation{ + Id: 2, + Creator: "def", + ContractAddr: TEST_CONTRACT, + })) + require.True(t, stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Has(&types.Cancellation{ + Id: 3, + Creator: "efg", + ContractAddr: TEST_CONTRACT, + })) + require.True(t, stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Has(&types.Cancellation{ + Id: 4, + Creator: "efg", + ContractAddr: TEST_CONTRACT, + })) + require.False(t, stateOne.GetBlockCancels(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Has(&types.Cancellation{ + Id: 5, + Creator: "efg", + ContractAddr: TEST_CONTRACT, + })) +} diff --git a/x/dex/cache/context.go b/x/dex/cache/context.go new file mode 100644 index 000000000..8c427f577 --- /dev/null +++ b/x/dex/cache/context.go @@ -0,0 +1,44 @@ +package dex + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/utils/datastructures" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +type CtxKeyType string + +const ( + CtxKeyExecTermSignal = CtxKeyType("execution-termination-signals") + CtxKeyExecutingContract = CtxKeyType("executing-contract") +) + +func GetExecutingContract(ctx sdk.Context) *types.ContractInfoV2 { + if ctx.Context() == nil { + return nil + } + executingContract := ctx.Context().Value(CtxKeyExecutingContract) + if executingContract == nil { + return nil + } + contract, ok := executingContract.(types.ContractInfoV2) + if !ok { + return nil + } + return &contract +} + +func GetTerminationSignals(ctx sdk.Context) *datastructures.TypedSyncMap[string, chan struct{}] { + if ctx.Context() == nil { + return nil + } + signals := ctx.Context().Value(CtxKeyExecTermSignal) + if signals == nil { + return nil + } + typedSignals, ok := signals.(*datastructures.TypedSyncMap[string, chan struct{}]) + if !ok { + return nil + } + return typedSignals +} diff --git a/x/dex/cache/deposit.go b/x/dex/cache/deposit.go new file mode 100644 index 000000000..1df6b2622 --- /dev/null +++ b/x/dex/cache/deposit.go @@ -0,0 +1,51 @@ +package dex + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +type DepositInfo struct { + store *prefix.Store +} + +func NewDepositInfo(store prefix.Store) *DepositInfo { + return &DepositInfo{store: &store} +} + +func (d *DepositInfo) Get() (list []*types.DepositInfoEntry) { + iterator := sdk.KVStorePrefixIterator(d.store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.DepositInfoEntry + if err := val.Unmarshal(iterator.Value()); err != nil { + panic(err) + } + list = append(list, &val) + } + + return +} + +func (d *DepositInfo) Add(newItem *types.DepositInfoEntry) { + key := types.MemDepositSubprefix(newItem.Creator, newItem.Denom) + if val, err := newItem.Marshal(); err != nil { + panic(err) + } else if existing := d.store.Get(key); existing == nil { + d.store.Set(key, val) + } else { + existingItem := types.DepositInfoEntry{} + if err := existingItem.Unmarshal(existing); err != nil { + panic(err) + } + newItem.Amount = newItem.Amount.Add(existingItem.Amount) + newVal, err := newItem.Marshal() + if err != nil { + panic(err) + } + d.store.Set(key, newVal) + } +} diff --git a/x/dex/cache/deposit_test.go b/x/dex/cache/deposit_test.go new file mode 100644 index 000000000..364ffa3d1 --- /dev/null +++ b/x/dex/cache/deposit_test.go @@ -0,0 +1,48 @@ +package dex_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dex "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestDepositAdd(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + deposits := dex.NewMemState(keeper.GetMemStoreKey()).GetDepositInfo(ctx, types.ContractAddress(keepertest.TestContract)) + deposit := types.DepositInfoEntry{ + Creator: "abc", + Amount: sdk.MustNewDecFromStr("1.2"), + } + deposits.Add(&deposit) + depositsState := deposits.Get() + require.Equal(t, 1, len(depositsState)) + require.Equal(t, sdk.MustNewDecFromStr("1.2"), depositsState[0].Amount) + + deposit = types.DepositInfoEntry{ + Creator: "abc", + Amount: sdk.MustNewDecFromStr("1.3"), + } + deposits.Add(&deposit) + depositsState = deposits.Get() + require.Equal(t, 1, len(depositsState)) + require.Equal(t, sdk.MustNewDecFromStr("2.5"), depositsState[0].Amount) + + deposit = types.DepositInfoEntry{ + Creator: "def", + Amount: sdk.MustNewDecFromStr("1.1"), + } + deposits.Add(&deposit) + depositsState = deposits.Get() + require.Equal(t, 2, len(depositsState)) + if depositsState[0].Creator == "abc" { + require.Equal(t, sdk.MustNewDecFromStr("2.5"), depositsState[0].Amount) + require.Equal(t, sdk.MustNewDecFromStr("1.1"), depositsState[1].Amount) + } else { + require.Equal(t, sdk.MustNewDecFromStr("2.5"), depositsState[1].Amount) + require.Equal(t, sdk.MustNewDecFromStr("1.1"), depositsState[0].Amount) + } +} diff --git a/x/dex/cache/order.go b/x/dex/cache/order.go new file mode 100644 index 000000000..03fac3aec --- /dev/null +++ b/x/dex/cache/order.go @@ -0,0 +1,142 @@ +package dex + +import ( + "encoding/binary" + "sort" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +type BlockOrders struct { + orderStore *prefix.Store +} + +func NewOrders(orderStore prefix.Store) *BlockOrders { + return &BlockOrders{orderStore: &orderStore} +} + +func (o *BlockOrders) Add(newItem *types.Order) { + keybz := make([]byte, 8) + binary.BigEndian.PutUint64(keybz, newItem.Id) + valbz, err := newItem.Marshal() + if err != nil { + panic(err) + } + o.orderStore.Set(keybz, valbz) +} + +func (o *BlockOrders) GetByID(id uint64) *types.Order { + keybz := make([]byte, 8) + binary.BigEndian.PutUint64(keybz, id) + var val types.Order + if err := val.Unmarshal(o.orderStore.Get(keybz)); err != nil { + panic(err) + } + return &val +} + +func (o *BlockOrders) Get() (list []*types.Order) { + iterator := sdk.KVStorePrefixIterator(o.orderStore, []byte{}) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + var val types.Order + if err := val.Unmarshal(iterator.Value()); err != nil { + panic(err) + } + list = append(list, &val) + } + + return +} + +func (o *BlockOrders) MarkFailedToPlace(failedOrders []types.UnsuccessfulOrder) { + failedOrdersMap := map[uint64]types.UnsuccessfulOrder{} + for _, failedOrder := range failedOrders { + failedOrdersMap[failedOrder.ID] = failedOrder + } + + keys, vals := o.getKVsToSet(failedOrdersMap) + for i, key := range keys { + o.orderStore.Set(key, vals[i]) + } +} + +// getKVsToSet iterate through the kvstore and append the key,val items to a list. +// We should avoid writing or reading from the store directly within the iterator. +func (o *BlockOrders) getKVsToSet(failedOrdersMap map[uint64]types.UnsuccessfulOrder) ([][]byte, [][]byte) { + iterator := sdk.KVStorePrefixIterator(o.orderStore, []byte{}) + + defer iterator.Close() + + var keys [][]byte + var vals [][]byte + for ; iterator.Valid(); iterator.Next() { + var val types.Order + if err := val.Unmarshal(iterator.Value()); err != nil { + panic(err) + } + if failedOrder, ok := failedOrdersMap[val.Id]; ok { + val.Status = types.OrderStatus_FAILED_TO_PLACE + val.StatusDescription = failedOrder.Reason + } + bz, err := val.Marshal() + if err != nil { + panic(err) + } + keys = append(keys, iterator.Key()) + vals = append(vals, bz) + } + return keys, vals +} + +func (o *BlockOrders) GetSortedMarketOrders(direction types.PositionDirection) []*types.Order { + res := o.getOrdersByCriteria(types.OrderType_MARKET, direction) + res = append(res, o.getOrdersByCriteria(types.OrderType_FOKMARKET, direction)...) + res = append(res, o.getOrdersByCriteria(types.OrderType_FOKMARKETBYVALUE, direction)...) + sort.SliceStable(res, func(i, j int) bool { + // a price of 0 indicates that there is no worst price for the order, so it should + // always be ranked at the top. + if res[i].Price.IsZero() { + return true + } else if res[j].Price.IsZero() { + return false + } + switch direction { + case types.PositionDirection_LONG: + return res[i].Price.GT(res[j].Price) + case types.PositionDirection_SHORT: + return res[i].Price.LT(res[j].Price) + default: + panic("Unknown direction") + } + }) + return res +} + +func (o *BlockOrders) GetLimitOrders(direction types.PositionDirection) []*types.Order { + return o.getOrdersByCriteria(types.OrderType_LIMIT, direction) +} + +func (o *BlockOrders) getOrdersByCriteria(orderType types.OrderType, direction types.PositionDirection) []*types.Order { + res := []*types.Order{} + iterator := sdk.KVStorePrefixIterator(o.orderStore, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Order + if err := val.Unmarshal(iterator.Value()); err != nil { + panic(err) + } + if val.OrderType != orderType || val.PositionDirection != direction { + continue + } + if val.Status == types.OrderStatus_FAILED_TO_PLACE { + continue + } + res = append(res, &val) + } + return res +} diff --git a/x/dex/cache/order_test.go b/x/dex/cache/order_test.go new file mode 100644 index 000000000..b5ab03715 --- /dev/null +++ b/x/dex/cache/order_test.go @@ -0,0 +1,257 @@ +package dex_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dex "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMarkFailedToPlace(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + }) + unsuccessfulOrder := types.UnsuccessfulOrder{ + ID: 1, + Reason: "some reason", + } + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).MarkFailedToPlace([]types.UnsuccessfulOrder{unsuccessfulOrder}) + require.Equal(t, types.OrderStatus_FAILED_TO_PLACE, + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get()[0].Status) + require.Equal(t, "some reason", + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Get()[0].StatusDescription) +} + +func TestGetByID(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 1, + Account: "test1", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_LIMIT, + Price: sdk.MustNewDecFromStr("150"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 2, + Account: "test2", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_MARKET, + Price: sdk.MustNewDecFromStr("100"), + }) + + order1 := stateOne.GetBlockOrders( + ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).GetByID(uint64(1)) + order2 := stateOne.GetBlockOrders( + ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).GetByID(uint64(2)) + require.Equal(t, uint64(1), order1.Id) + require.Equal(t, uint64(2), order2.Id) + require.Equal(t, "test1", order1.Account) + require.Equal(t, "test2", order2.Account) + require.Equal(t, TEST_CONTRACT, order1.ContractAddr) + require.Equal(t, TEST_CONTRACT, order2.ContractAddr) + require.Equal(t, types.PositionDirection_LONG, order1.PositionDirection) + require.Equal(t, types.PositionDirection_SHORT, order2.PositionDirection) + require.Equal(t, types.OrderType_LIMIT, order1.OrderType) + require.Equal(t, types.OrderType_MARKET, order2.OrderType) + require.Equal(t, sdk.MustNewDecFromStr("150"), order1.Price) + require.Equal(t, sdk.MustNewDecFromStr("100"), order2.Price) +} + +func TestGetSortedMarketOrders(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + stateOne := dex.NewMemState(keeper.GetMemStoreKey()) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_MARKET, + Price: sdk.MustNewDecFromStr("150"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 2, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_MARKET, + Price: sdk.MustNewDecFromStr("100"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 3, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_MARKET, + Price: sdk.MustNewDecFromStr("0"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 4, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_MARKET, + Price: sdk.MustNewDecFromStr("100"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 5, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_MARKET, + Price: sdk.MustNewDecFromStr("80"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 6, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_MARKET, + Price: sdk.MustNewDecFromStr("0"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 7, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_LIMIT, + Price: sdk.MustNewDecFromStr("100"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 8, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_LIMIT, + Price: sdk.MustNewDecFromStr("100"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 9, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_FOKMARKET, + Price: sdk.MustNewDecFromStr("100"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 10, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_FOKMARKET, + Price: sdk.MustNewDecFromStr("0"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 11, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_FOKMARKET, + Price: sdk.MustNewDecFromStr("150"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 12, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_FOKMARKET, + Price: sdk.MustNewDecFromStr("0"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 13, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_FOKMARKET, + Price: sdk.MustNewDecFromStr("150"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 14, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_FOKMARKET, + Price: sdk.MustNewDecFromStr("100"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 15, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_FOKMARKETBYVALUE, + Price: sdk.MustNewDecFromStr("100"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 16, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_FOKMARKETBYVALUE, + Price: sdk.MustNewDecFromStr("0"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 17, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_FOKMARKETBYVALUE, + Price: sdk.MustNewDecFromStr("150"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 18, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_FOKMARKETBYVALUE, + Price: sdk.MustNewDecFromStr("0"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 19, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_FOKMARKETBYVALUE, + Price: sdk.MustNewDecFromStr("150"), + }) + stateOne.GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).Add(&types.Order{ + Id: 20, + Account: "test", + ContractAddr: TEST_CONTRACT, + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_FOKMARKETBYVALUE, + Price: sdk.MustNewDecFromStr("100"), + }) + + marketBuys := stateOne.GetBlockOrders( + ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).GetSortedMarketOrders(types.PositionDirection_LONG) + require.Equal(t, uint64(16), marketBuys[0].Id) + require.Equal(t, uint64(10), marketBuys[1].Id) + require.Equal(t, uint64(3), marketBuys[2].Id) + require.Equal(t, uint64(1), marketBuys[3].Id) + require.Equal(t, uint64(11), marketBuys[4].Id) + require.Equal(t, uint64(17), marketBuys[5].Id) + require.Equal(t, uint64(2), marketBuys[6].Id) + require.Equal(t, uint64(9), marketBuys[7].Id) + require.Equal(t, uint64(15), marketBuys[8].Id) + + marketSells := stateOne.GetBlockOrders( + ctx, types.ContractAddress(TEST_CONTRACT), keepertest.TestPair).GetSortedMarketOrders(types.PositionDirection_SHORT) + require.Equal(t, uint64(18), marketSells[0].Id) + require.Equal(t, uint64(12), marketSells[1].Id) + require.Equal(t, uint64(6), marketSells[2].Id) + require.Equal(t, uint64(5), marketSells[3].Id) + require.Equal(t, uint64(4), marketSells[4].Id) + require.Equal(t, uint64(14), marketSells[5].Id) + require.Equal(t, uint64(20), marketSells[6].Id) + require.Equal(t, uint64(13), marketSells[7].Id) + require.Equal(t, uint64(19), marketSells[8].Id) +} diff --git a/x/dex/client/cli/query/query.go b/x/dex/client/cli/query/query.go new file mode 100644 index 000000000..9270b81c3 --- /dev/null +++ b/x/dex/client/cli/query/query.go @@ -0,0 +1,48 @@ +package query + +import ( + "fmt" + // "strings" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + // "github.com/cosmos/cosmos-sdk/client/flags" + // sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// GetQueryCmd returns the cli query commands for this module +func GetQueryCmd() *cobra.Command { + // Group dex queries under a subcommand + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("Querying commands for the %s module", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + + cmd.AddCommand(CmdQueryParams()) + cmd.AddCommand(CmdListLongBook()) + cmd.AddCommand(CmdShowLongBook()) + cmd.AddCommand(CmdListShortBook()) + cmd.AddCommand(CmdShowShortBook()) + cmd.AddCommand(CmdGetPrice()) + cmd.AddCommand(CmdGetLatestPrice()) + cmd.AddCommand(CmdGetPrices()) + cmd.AddCommand(CmdGetTwaps()) + cmd.AddCommand(CmdGetAssetList()) + cmd.AddCommand(CmdGetAssetMetadata()) + cmd.AddCommand(CmdGetRegisteredPairs()) + cmd.AddCommand(CmdGetRegisteredContract()) + cmd.AddCommand(CmdGetOrders()) + cmd.AddCommand(CmdGetOrdersByID()) + cmd.AddCommand(CmdGetMatchResult()) + cmd.AddCommand(CmdGetOrderCount()) + + // this line is used by starport scaffolding # 1 + + return cmd +} diff --git a/x/dex/client/cli/query/query_asset_list.go b/x/dex/client/cli/query/query_asset_list.go new file mode 100644 index 000000000..7615cbfed --- /dev/null +++ b/x/dex/client/cli/query/query_asset_list.go @@ -0,0 +1,80 @@ +package query + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdGetAssetList() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-asset-list", + Short: "Query Asset List", + Long: strings.TrimSpace(` + Returns the metadata for all assets. Dex asset metadata includes information such as IBC info (for IBC assets), the asset type, and standard token metadata from the bank module. + `), + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryAssetListRequest{} + + res, err := queryClient.AssetList(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func CmdGetAssetMetadata() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-asset-metadata [denom]", + Short: "Query Asset Metadata", + Long: strings.TrimSpace(` + Returns the metadata for a specific asset based on the passed in denom. Dex asset metadata includes information such as IBC info (for IBC assets), the asset type, and standard token metadata from the bank module. + `), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + denom := args[0] + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryAssetMetadataRequest{ + Denom: denom, + } + + res, err := queryClient.AssetMetadata(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_get_latest_price.go b/x/dex/client/cli/query/query_get_latest_price.go new file mode 100644 index 000000000..52bbcb3f0 --- /dev/null +++ b/x/dex/client/cli/query/query_get_latest_price.go @@ -0,0 +1,53 @@ +package query + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdGetLatestPrice() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-latest-price [contract-address] [price-denom] [asset-denom]", + Short: "Query getLatestPrice", + Long: strings.TrimSpace(` + Get the latest price from a dex specified by the contract-address. The price and asset denom are used to specify the dex pair for which to return the latest price. For the price at a specific timestamp use get-price instead or for all prices use get-prices. + `), + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) (err error) { + reqContractAddr := args[0] + reqPriceDenom := args[1] + reqAssetDenom := args[2] + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryGetLatestPriceRequest{ + ContractAddr: reqContractAddr, + PriceDenom: reqPriceDenom, + AssetDenom: reqAssetDenom, + } + + res, err := queryClient.GetLatestPrice(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_get_order_count.go b/x/dex/client/cli/query/query_get_order_count.go new file mode 100644 index 000000000..105fcbdaa --- /dev/null +++ b/x/dex/client/cli/query/query_get_order_count.go @@ -0,0 +1,52 @@ +package query + +import ( + "context" + "fmt" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +func CmdGetOrderCount() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-order-count [contract] [price denom] [asset denom] [LONG|SHORT] [price]", + Short: "get number of orders at a price leve", + Args: cobra.ExactArgs(5), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + var direction types.PositionDirection + switch args[3] { + case "LONG": + direction = types.PositionDirection_LONG + case "SHORT": + direction = types.PositionDirection_SHORT + default: + return fmt.Errorf("unknown direction %s", args[3]) + } + price := sdk.MustNewDecFromStr(args[4]) + res, err := queryClient.GetOrderCount(context.Background(), &types.QueryGetOrderCountRequest{ + ContractAddr: args[0], + PriceDenom: args[1], + AssetDenom: args[2], + PositionDirection: direction, + Price: &price, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_get_price.go b/x/dex/client/cli/query/query_get_price.go new file mode 100644 index 000000000..06c9d9dbd --- /dev/null +++ b/x/dex/client/cli/query/query_get_price.go @@ -0,0 +1,58 @@ +package query + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdGetPrice() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-price [contract-address] [timestamp] [price-denom] [asset-denom]", + Short: "Query getPrice", + Long: strings.TrimSpace(` + Get the price for a pair from a dex specified by the contract-address. The price and asset denom are used to specify the dex pair for which to return the latest price. The timestamp is used to query the price for that specific timestamp. For the latest price use get-latest-price instead or for all prices use get-prices. + `), + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) (err error) { + reqContractAddr := args[0] + reqTimestamp, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return err + } + reqPriceDenom := args[2] + reqAssetDenom := args[3] + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryGetPriceRequest{ + ContractAddr: reqContractAddr, + PriceDenom: reqPriceDenom, + AssetDenom: reqAssetDenom, + Timestamp: reqTimestamp, + } + + res, err := queryClient.GetPrice(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_get_prices.go b/x/dex/client/cli/query/query_get_prices.go new file mode 100644 index 000000000..7637379b0 --- /dev/null +++ b/x/dex/client/cli/query/query_get_prices.go @@ -0,0 +1,53 @@ +package query + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdGetPrices() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-prices [contract-address] [price-denom] [asset-denom]", + Short: "Query getPrices", + Long: strings.TrimSpace(` + Get all the prices for a pair from a dex specified by the contract-address. The price and asset denom are used to specify the dex pair for which to return the latest price. For the latest price use get-latest-price instead or for a specific timestamp use get-price. + `), + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) (err error) { + reqContractAddr := args[0] + reqPriceDenom := args[1] + reqAssetDenom := args[2] + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryGetPricesRequest{ + ContractAddr: reqContractAddr, + PriceDenom: reqPriceDenom, + AssetDenom: reqAssetDenom, + } + + res, err := queryClient.GetPrices(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_get_twaps.go b/x/dex/client/cli/query/query_get_twaps.go new file mode 100644 index 000000000..798394b3b --- /dev/null +++ b/x/dex/client/cli/query/query_get_twaps.go @@ -0,0 +1,53 @@ +package query + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdGetTwaps() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-twaps [contract-address] [lookback]", + Short: "Query getPrice", + Long: strings.TrimSpace(` + Get the TWAPs (Time weighted average prices) for all registered dex pairs for a specific orderbook by [contract-address] with a specific lookback duration over which to compute the weighted average. + `), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) (err error) { + reqContractAddr := args[0] + reqLookback, err := strconv.ParseUint(args[1], 10, 64) + if err != nil { + return err + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryGetTwapsRequest{ + ContractAddr: reqContractAddr, + LookbackSeconds: reqLookback, + } + + res, err := queryClient.GetTwaps(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_long_book.go b/x/dex/client/cli/query/query_long_book.go new file mode 100644 index 000000000..bf735d901 --- /dev/null +++ b/x/dex/client/cli/query/query_long_book.go @@ -0,0 +1,90 @@ +package query + +import ( + "context" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +func CmdListLongBook() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-long-book [contract address] [price denom] [asset denom]", + Short: "list all longBook", + Long: strings.TrimSpace(` + Lists all of a long book's information for a given contract address and pair specified by price denom and asset denom. + `), + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + reqPriceDenom := args[1] + reqAssetDenom := args[2] + + params := &types.QueryAllLongBookRequest{ + Pagination: pageReq, + ContractAddr: args[0], + PriceDenom: reqPriceDenom, + AssetDenom: reqAssetDenom, + } + + res, err := queryClient.LongBookAll(context.Background(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddPaginationFlagsToCmd(cmd, cmd.Use) + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func CmdShowLongBook() *cobra.Command { + cmd := &cobra.Command{ + Use: "show-long-book [contract address] [price] [price denom] [asset denom]", + Short: "shows a longBook", + Long: strings.TrimSpace(` + Gets a long book's information at a specific price for a given contract address and pair specified by price denopm and asset denom. + `), + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + contractAddr := args[0] + reqPriceDenom := args[2] + reqAssetDenom := args[3] + + params := &types.QueryGetLongBookRequest{ + Price: args[1], + ContractAddr: contractAddr, + PriceDenom: reqPriceDenom, + AssetDenom: reqAssetDenom, + } + res, err := queryClient.LongBook(context.Background(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_long_book_test.go b/x/dex/client/cli/query/query_long_book_test.go new file mode 100644 index 000000000..cd878dc7b --- /dev/null +++ b/x/dex/client/cli/query/query_long_book_test.go @@ -0,0 +1,176 @@ +package query_test + +import ( + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/client/flags" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + "github.com/stretchr/testify/require" + tmcli "github.com/tendermint/tendermint/libs/cli" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/testutil/network" + "github.com/sei-protocol/sei-chain/testutil/nullify" + "github.com/sei-protocol/sei-chain/x/dex/client/cli/query" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func networkWithLongBookObjects(t *testing.T, n int) (*network.Network, []types.LongBook) { + t.Helper() + cfg := network.DefaultConfig() + state := types.GenesisState{} + longBookList := []types.LongBook{} + require.NoError(t, cfg.Codec.UnmarshalJSON(cfg.GenesisState[types.ModuleName], &state)) + + for i := 0; i < n; i++ { + longBook := types.LongBook{ + Price: sdk.NewDec(int64(1 + i)), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(int64(1 + i)), + Quantity: sdk.NewDec(int64(i)), + Allocations: []*types.Allocation{{Account: "abc", Quantity: sdk.NewDec(int64(i)), OrderId: 1}}, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + }, + } + nullify.Fill(&longBook) + longBookList = append(longBookList, longBook) + } + + contractInfo := types.ContractInfoV2{ + CodeId: uint64(1), + ContractAddr: "sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc", + } + contractState := []types.ContractState{ + { + LongBookList: longBookList, + ContractInfo: contractInfo, + }, + } + state.ContractState = contractState + buf, err := cfg.Codec.MarshalJSON(&state) + require.NoError(t, err) + cfg.GenesisState[types.ModuleName] = buf + return network.New(t, cfg), state.ContractState[0].LongBookList +} + +func TestShowLongBook(t *testing.T) { + net, objs := networkWithLongBookObjects(t, 2) + + ctx := net.Validators[0].ClientCtx + common := []string{ + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + } + for _, tc := range []struct { + desc string + price string + args []string + err error + obj types.LongBook + }{ + { + desc: "found", + price: objs[1].Entry.Price.String(), + args: common, + obj: objs[1], + }, + { + desc: "not found", + price: "not_found", + args: common, + err: status.Error(codes.InvalidArgument, "not found"), + }, + } { + tc := tc + t.Run(tc.desc, func(t *testing.T) { + // the longbook orders are from genesis contract as created from networkWithLongBookObjects + args := []string{"sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc", tc.price, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom} + args = append(args, tc.args...) + out, err := clitestutil.ExecTestCLICmd(ctx, query.CmdShowLongBook(), args) + if tc.err != nil { + stat, ok := status.FromError(tc.err) + require.True(t, ok) + require.ErrorIs(t, stat.Err(), tc.err) + } else { + require.NoError(t, err) + var resp types.QueryGetLongBookResponse + require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) + require.NotNil(t, resp.LongBook) + require.Equal(t, + nullify.Fill(&tc.obj), + nullify.Fill(&resp.LongBook), + ) + } + }) + } +} + +func TestListLongBook(t *testing.T) { + net, objs := networkWithLongBookObjects(t, 5) + + ctx := net.Validators[0].ClientCtx + request := func(next []byte, offset, limit uint64, total bool) []string { + args := []string{ + "sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc", TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom, + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + } + if next == nil { + args = append(args, fmt.Sprintf("--%s=%d", flags.FlagOffset, offset)) + } else { + args = append(args, fmt.Sprintf("--%s=%s", flags.FlagPageKey, next)) + } + args = append(args, fmt.Sprintf("--%s=%d", flags.FlagLimit, limit)) + if total { + args = append(args, fmt.Sprintf("--%s", flags.FlagCountTotal)) + } + return args + } + t.Run("ByOffset", func(t *testing.T) { + step := 2 + for i := 0; i < len(objs); i += step { + args := request(nil, uint64(i), uint64(step), false) + out, err := clitestutil.ExecTestCLICmd(ctx, query.CmdListLongBook(), args) + require.NoError(t, err) + var resp types.QueryAllLongBookResponse + require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) + require.LessOrEqual(t, len(resp.LongBook), step) + require.Subset(t, + nullify.Fill(objs), + nullify.Fill(resp.LongBook), + ) + } + }) + t.Run("ByKey", func(t *testing.T) { + step := 2 + var next []byte + for i := 0; i < len(objs); i += step { + args := request(next, 0, uint64(step), false) + out, err := clitestutil.ExecTestCLICmd(ctx, query.CmdListLongBook(), args) + require.NoError(t, err) + var resp types.QueryAllLongBookResponse + require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) + require.LessOrEqual(t, len(resp.LongBook), step) + require.Subset(t, + nullify.Fill(objs), + nullify.Fill(resp.LongBook), + ) + next = resp.Pagination.NextKey + } + }) + t.Run("Total", func(t *testing.T) { + args := request(nil, 0, uint64(len(objs)), true) + out, err := clitestutil.ExecTestCLICmd(ctx, query.CmdListLongBook(), args) + require.NoError(t, err) + var resp types.QueryAllLongBookResponse + require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) + require.NoError(t, err) + require.Equal(t, len(objs), int(resp.Pagination.Total)) + require.ElementsMatch(t, + nullify.Fill(objs), + nullify.Fill(resp.LongBook), + ) + }) +} diff --git a/x/dex/client/cli/query/query_match_result.go b/x/dex/client/cli/query/query_match_result.go new file mode 100644 index 000000000..c1a3fe194 --- /dev/null +++ b/x/dex/client/cli/query/query_match_result.go @@ -0,0 +1,49 @@ +package query + +import ( + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +func CmdGetMatchResult() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-match-result [contract-address]", + Short: "Query get match result by contract", + Long: strings.TrimSpace(` + Gets the match result information for an orderbook specified by the given contract address. The match result information includes the orders, settlements, and cancellations for the orderbook. + `), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + contractAddr := args[0] + if err != nil { + return err + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryGetMatchResultRequest{ + ContractAddr: contractAddr, + } + + res, err := queryClient.GetMatchResult(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_orders.go b/x/dex/client/cli/query/query_orders.go new file mode 100644 index 000000000..1c054c8b1 --- /dev/null +++ b/x/dex/client/cli/query/query_orders.go @@ -0,0 +1,96 @@ +package query + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdGetOrders() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-orders [contract-address] [account]", + Short: "Query get orders for account", + Long: strings.TrimSpace(` + Get all orders for an account and orderbook specified by contract address. + `), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) (err error) { + reqContractAddr := args[0] + reqAccount := args[1] + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryGetOrdersRequest{ + ContractAddr: reqContractAddr, + Account: reqAccount, + } + + res, err := queryClient.GetOrders(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func CmdGetOrdersByID() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-orders-by-id [contract-address] [price-denom] [asset-denom] [id]", + Short: "Query get order by ID", + Long: strings.TrimSpace(` + Get a specific order by ID for an account and orderbook specified by contract address. + `), + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) (err error) { + contractAddr := args[0] + priceDenom := args[1] + assetDenom := args[2] + orderID, err := strconv.ParseUint(args[3], 10, 64) + if err != nil { + return err + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryGetOrderByIDRequest{ + ContractAddr: contractAddr, + PriceDenom: priceDenom, + AssetDenom: assetDenom, + Id: orderID, + } + + res, err := queryClient.GetOrder(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_params.go b/x/dex/client/cli/query/query_params.go new file mode 100644 index 000000000..052866740 --- /dev/null +++ b/x/dex/client/cli/query/query_params.go @@ -0,0 +1,34 @@ +package query + +import ( + "context" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +func CmdQueryParams() *cobra.Command { + cmd := &cobra.Command{ + Use: "params", + Short: "shows the parameters of the module", + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + res, err := queryClient.Params(context.Background(), &types.QueryParamsRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_registered_contract.go b/x/dex/client/cli/query/query_registered_contract.go new file mode 100644 index 000000000..f779c6fe3 --- /dev/null +++ b/x/dex/client/cli/query/query_registered_contract.go @@ -0,0 +1,48 @@ +package query + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdGetRegisteredContract() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-registered-contract [contract address]", + Short: "Query Registered Contract", + Long: strings.TrimSpace(` + List the registered contract information specified by contract address. + `), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + contractAddr := args[0] + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryRegisteredContractRequest{ + ContractAddr: contractAddr, + } + + res, err := queryClient.GetRegisteredContract(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_registered_pairs.go b/x/dex/client/cli/query/query_registered_pairs.go new file mode 100644 index 000000000..2b854976c --- /dev/null +++ b/x/dex/client/cli/query/query_registered_pairs.go @@ -0,0 +1,48 @@ +package query + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdGetRegisteredPairs() *cobra.Command { + cmd := &cobra.Command{ + Use: "get-registered-pairs [contract address]", + Short: "Query Registered Pairs", + Long: strings.TrimSpace(` + List all of the registered pairs for an orderbook specified by contract address. + `), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + contractAddr := args[0] + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryRegisteredPairsRequest{ + ContractAddr: contractAddr, + } + + res, err := queryClient.GetRegisteredPairs(cmd.Context(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_short_book.go b/x/dex/client/cli/query/query_short_book.go new file mode 100644 index 000000000..b16e477ce --- /dev/null +++ b/x/dex/client/cli/query/query_short_book.go @@ -0,0 +1,92 @@ +package query + +import ( + "context" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +func CmdListShortBook() *cobra.Command { + cmd := &cobra.Command{ + Use: "list-short-book [contract address] [price denom] [asset denom]", + Short: "list all shortBook", + Long: strings.TrimSpace(` + Lists all of a short book's information for a given contract address and pair specified by price denopm and asset denom. + `), + Args: cobra.ExactArgs(3), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + pageReq, err := client.ReadPageRequest(cmd.Flags()) + if err != nil { + return err + } + + reqPriceDenom := args[1] + reqAssetDenom := args[2] + + queryClient := types.NewQueryClient(clientCtx) + + params := &types.QueryAllShortBookRequest{ + Pagination: pageReq, + ContractAddr: args[0], + PriceDenom: reqPriceDenom, + AssetDenom: reqAssetDenom, + } + + res, err := queryClient.ShortBookAll(context.Background(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddPaginationFlagsToCmd(cmd, cmd.Use) + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func CmdShowShortBook() *cobra.Command { + cmd := &cobra.Command{ + Use: "show-short-book [contract address] [price] [price denom] [asset denom]", + Short: "shows a shortBook", + Long: strings.TrimSpace(` + Gets a short book's information at a specific price for a given contract address and pair specified by price denopm and asset denom. + `), + Args: cobra.ExactArgs(4), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx := client.GetClientContextFromCmd(cmd) + + queryClient := types.NewQueryClient(clientCtx) + + contractAddr := args[0] + reqPriceDenom := args[2] + reqAssetDenom := args[3] + + params := &types.QueryGetShortBookRequest{ + Price: args[1], + ContractAddr: contractAddr, + PriceDenom: reqPriceDenom, + AssetDenom: reqAssetDenom, + } + + res, err := queryClient.ShortBook(context.Background(), params) + if err != nil { + return err + } + + return clientCtx.PrintProto(res) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/query/query_short_book_test.go b/x/dex/client/cli/query/query_short_book_test.go new file mode 100644 index 000000000..1bfe5bbbb --- /dev/null +++ b/x/dex/client/cli/query/query_short_book_test.go @@ -0,0 +1,181 @@ +package query_test + +import ( + "fmt" + "testing" + + "github.com/cosmos/cosmos-sdk/client/flags" + clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/testutil/network" + "github.com/sei-protocol/sei-chain/testutil/nullify" + "github.com/sei-protocol/sei-chain/x/dex/client/cli/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" + tmcli "github.com/tendermint/tendermint/libs/cli" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func TEST_PAIR() types.Pair { + return types.Pair{ + PriceDenom: "usdc", + AssetDenom: "atom", + } +} + +func networkWithShortBookObjects(t *testing.T, n int) (*network.Network, []types.ShortBook) { + t.Helper() + cfg := network.DefaultConfig() + state := types.GenesisState{} + shortBookList := []types.ShortBook{} + require.NoError(t, cfg.Codec.UnmarshalJSON(cfg.GenesisState[types.ModuleName], &state)) + + for i := 0; i < n; i++ { + shortBook := types.ShortBook{ + Price: sdk.NewDec(int64(1 + i)), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(int64(1 + i)), + Quantity: sdk.NewDec(int64(i)), + Allocations: []*types.Allocation{{Account: "abc", Quantity: sdk.NewDec(int64(i)), OrderId: 1}}, + PriceDenom: TEST_PAIR().PriceDenom, + AssetDenom: TEST_PAIR().AssetDenom, + }, + } + nullify.Fill(&shortBook) + shortBookList = append(shortBookList, shortBook) + } + + contractInfo := types.ContractInfoV2{ + CodeId: uint64(1), + ContractAddr: "sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc", + } + contractState := []types.ContractState{ + { + ShortBookList: shortBookList, + ContractInfo: contractInfo, + }, + } + state.ContractState = contractState + buf, err := cfg.Codec.MarshalJSON(&state) + require.NoError(t, err) + cfg.GenesisState[types.ModuleName] = buf + return network.New(t, cfg), state.ContractState[0].ShortBookList +} + +func TestShowShortBook(t *testing.T) { + net, objs := networkWithShortBookObjects(t, 2) + + ctx := net.Validators[0].ClientCtx + common := []string{ + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + } + for _, tc := range []struct { + desc string + price string + args []string + err error + obj types.ShortBook + }{ + { + desc: "found", + price: objs[1].Entry.Price.String(), + args: common, + obj: objs[1], + }, + { + desc: "not found", + price: "not_found", + args: common, + err: status.Error(codes.InvalidArgument, "not found"), + }, + } { + tc := tc + t.Run(tc.desc, func(t *testing.T) { + args := []string{"sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc", tc.price, TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom} + args = append(args, tc.args...) + out, err := clitestutil.ExecTestCLICmd(ctx, query.CmdShowShortBook(), args) + if tc.err != nil { + stat, ok := status.FromError(tc.err) + require.True(t, ok) + require.ErrorIs(t, stat.Err(), tc.err) + } else { + require.NoError(t, err) + var resp types.QueryGetShortBookResponse + require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) + require.NotNil(t, resp.ShortBook) + require.Equal(t, + nullify.Fill(&tc.obj), + nullify.Fill(&resp.ShortBook), + ) + } + }) + } +} + +func TestListShortBook(t *testing.T) { + net, objs := networkWithShortBookObjects(t, 5) + + ctx := net.Validators[0].ClientCtx + request := func(next []byte, offset, limit uint64, total bool) []string { + args := []string{ + "sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc", TEST_PAIR().PriceDenom, TEST_PAIR().AssetDenom, + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + } + if next == nil { + args = append(args, fmt.Sprintf("--%s=%d", flags.FlagOffset, offset)) + } else { + args = append(args, fmt.Sprintf("--%s=%s", flags.FlagPageKey, next)) + } + args = append(args, fmt.Sprintf("--%s=%d", flags.FlagLimit, limit)) + if total { + args = append(args, fmt.Sprintf("--%s", flags.FlagCountTotal)) + } + return args + } + t.Run("ByOffset", func(t *testing.T) { + step := 2 + for i := 0; i < len(objs); i += step { + args := request(nil, uint64(i), uint64(step), false) + out, err := clitestutil.ExecTestCLICmd(ctx, query.CmdListShortBook(), args) + require.NoError(t, err) + var resp types.QueryAllShortBookResponse + require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) + require.LessOrEqual(t, len(resp.ShortBook), step) + require.Subset(t, + nullify.Fill(objs), + nullify.Fill(resp.ShortBook), + ) + } + }) + t.Run("ByKey", func(t *testing.T) { + step := 2 + var next []byte + for i := 0; i < len(objs); i += step { + args := request(next, 0, uint64(step), false) + out, err := clitestutil.ExecTestCLICmd(ctx, query.CmdListShortBook(), args) + require.NoError(t, err) + var resp types.QueryAllShortBookResponse + require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) + require.LessOrEqual(t, len(resp.ShortBook), step) + require.Subset(t, + nullify.Fill(objs), + nullify.Fill(resp.ShortBook), + ) + next = resp.Pagination.NextKey + } + }) + t.Run("Total", func(t *testing.T) { + args := request(nil, 0, uint64(len(objs)), true) + out, err := clitestutil.ExecTestCLICmd(ctx, query.CmdListShortBook(), args) + require.NoError(t, err) + var resp types.QueryAllShortBookResponse + require.NoError(t, net.Config.Codec.UnmarshalJSON(out.Bytes(), &resp)) + require.NoError(t, err) + require.Equal(t, len(objs), int(resp.Pagination.Total)) + require.ElementsMatch(t, + nullify.Fill(objs), + nullify.Fill(resp.ShortBook), + ) + }) +} diff --git a/x/dex/client/cli/tx/gov_tx.go b/x/dex/client/cli/tx/gov_tx.go new file mode 100644 index 000000000..92e2c018a --- /dev/null +++ b/x/dex/client/cli/tx/gov_tx.go @@ -0,0 +1,60 @@ +package tx + +import ( + "strings" + + "github.com/sei-protocol/sei-chain/x/dex/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + cutils "github.com/sei-protocol/sei-chain/x/dex/client/utils" + + "github.com/spf13/cobra" +) + +// NewAddAssetProposalTxCmd returns a CLI command handler for creating +// a add asset proposal governance transaction. +func NewAddAssetProposalTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "add-asset-proposal [proposal-file]", + Args: cobra.ExactArgs(1), + Short: "Submit an add asset proposal", + Long: strings.TrimSpace(` + Submit a proposal to add a list of assets and corresponding metadata to dex assets. + `), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + proposal, err := cutils.ParseAddAssetMetadataProposalJSON(clientCtx.LegacyAmino, args[0]) + if err != nil { + return err + } + + // Convert proposal to RegisterPairsProposal Type + from := clientCtx.GetFromAddress() + + content := types.AddAssetMetadataProposal{Title: proposal.Title, Description: proposal.Description, AssetList: proposal.AssetList} + + deposit, err := sdk.ParseCoinsNormalized(proposal.Deposit) + if err != nil { + return err + } + + msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, from) + if err != nil { + return err + } + + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/tx/tx.go b/x/dex/client/cli/tx/tx.go new file mode 100644 index 000000000..9c7ab93e8 --- /dev/null +++ b/x/dex/client/cli/tx/tx.go @@ -0,0 +1,40 @@ +package tx + +import ( + "fmt" + + "github.com/spf13/cobra" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +//nolint:deadcode,unused // I assume we'll use this later. +const ( + flagPacketTimeoutTimestamp = "packet-timeout-timestamp" + listSeparator = "," +) + +// GetTxCmd returns the transaction commands for this module +func GetTxCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: types.ModuleName, + Short: fmt.Sprintf("%s transactions subcommands", types.ModuleName), + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + cmd.AddCommand(CmdPlaceOrders()) + cmd.AddCommand(CmdCancelOrders()) + cmd.AddCommand(CmdRegisterContract()) + cmd.AddCommand(CmdRegisterPairs()) + cmd.AddCommand(CmdUnregisterContract()) + cmd.AddCommand(CmdContractDepositRent()) + cmd.AddCommand(CmdUpdatePriceTickSize()) + cmd.AddCommand(CmdUpdateQuantityTickSize()) + cmd.AddCommand(NewAddAssetProposalTxCmd()) + cmd.AddCommand(CmdUnsuspendContract()) + // this line is used by starport scaffolding # 1 + + return cmd +} diff --git a/x/dex/client/cli/tx/tx_cancel_orders.go b/x/dex/client/cli/tx/tx_cancel_orders.go new file mode 100644 index 000000000..9ba16b5d5 --- /dev/null +++ b/x/dex/client/cli/tx/tx_cancel_orders.go @@ -0,0 +1,75 @@ +package tx + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdCancelOrders() *cobra.Command { + cmd := &cobra.Command{ + Use: "cancel-orders [contract address] [cancellations...]", + Short: "Bulk cancel orders", + Long: strings.TrimSpace(` + Cancel orders placed on an orderbook specified by contract-address. Cancellations are represented as strings with the cancellation details separated by "?". Cancellation details format is OrderID?PositionDirection?Price?PriceDenom?AssetDenom. + + Example: "1234?LONG?1.01?USDC?ATOM" + `), + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) (err error) { + argContractAddr := args[0] + if err != nil { + return err + } + cancellations := []*types.Cancellation{} + for _, cancellation := range args[1:] { + newCancel := types.Cancellation{} + cancelDetails := strings.Split(cancellation, "?") + newCancel.Id, err = strconv.ParseUint(cancelDetails[0], 10, 64) + if err != nil { + return err + } + argPositionDir, err := types.GetPositionDirectionFromStr(cancelDetails[1]) + if err != nil { + return err + } + newCancel.PositionDirection = argPositionDir + argPrice, err := sdk.NewDecFromStr(cancelDetails[2]) + if err != nil { + return err + } + newCancel.Price = argPrice + newCancel.PriceDenom = cancelDetails[3] + newCancel.AssetDenom = cancelDetails[4] + cancellations = append(cancellations, &newCancel) + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgCancelOrders( + clientCtx.GetFromAddress().String(), + cancellations, + argContractAddr, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/tx/tx_contract_deposit_rent.go b/x/dex/client/cli/tx/tx_contract_deposit_rent.go new file mode 100644 index 000000000..fd24176eb --- /dev/null +++ b/x/dex/client/cli/tx/tx_contract_deposit_rent.go @@ -0,0 +1,52 @@ +package tx + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cast" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdContractDepositRent() *cobra.Command { + cmd := &cobra.Command{ + Use: "contract-deposit-rent [contract address] [amount]", + Short: "Contract deposit rent", + Long: strings.TrimSpace(` + Deposit rent for an orderbook specified by contract-address. This rent allows the contract to be executed via dex hooks for calculating order updates and position settlement. + `), + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) (err error) { + argContractAddr := args[0] + argDeposit, err := cast.ToUint64E(args[1]) + if err != nil { + return err + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgContractDepositRent( + argContractAddr, + argDeposit, + clientCtx.GetFromAddress().String(), + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/tx/tx_place_orders.go b/x/dex/client/cli/tx/tx_place_orders.go new file mode 100644 index 000000000..183a0efa2 --- /dev/null +++ b/x/dex/client/cli/tx/tx_place_orders.go @@ -0,0 +1,98 @@ +package tx + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +const ( + flagAmount = "amount" +) + +func CmdPlaceOrders() *cobra.Command { + cmd := &cobra.Command{ + Use: "place-orders [contract address] [orders...] --amount [coins,optional]", + Short: "Bulk place orders", + Long: strings.TrimSpace(` + Place orders on an orderbook specified by contract-address. Orders are represented as strings with the order details separated by "?". Cancellation details format is OrderDirection?Quantity?Price?PriceAsset?QuoteAsset?OrderType?OrderData?AdditionalParams. + More info here: https://docs.seinetwork.io/smart-contracts-and-local-development/dex-module-tutorial#placeorders + `), + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) (err error) { + argContractAddr := args[0] + orders := []*types.Order{} + for _, order := range args[1:] { + newOrder := types.Order{} + orderDetails := strings.Split(order, "?") + argPositionDir, err := types.GetPositionDirectionFromStr(orderDetails[0]) + if err != nil { + return err + } + newOrder.PositionDirection = argPositionDir + argPrice, err := sdk.NewDecFromStr(orderDetails[1]) + if err != nil { + return err + } + newOrder.Price = argPrice + argQuantity, err := sdk.NewDecFromStr(orderDetails[2]) + if err != nil { + return err + } + newOrder.Quantity = argQuantity + newOrder.PriceDenom = orderDetails[3] + newOrder.AssetDenom = orderDetails[4] + argOrderType, err := types.GetOrderTypeFromStr(orderDetails[5]) + if err != nil { + return err + } + newOrder.OrderType = argOrderType + newOrder.Data = orderDetails[6] + if newOrder.OrderType == types.OrderType_FOKMARKETBYVALUE { + argNominal, err := sdk.NewDecFromStr(orderDetails[7]) + if err != nil { + return err + } + newOrder.Nominal = argNominal + } + orders = append(orders, &newOrder) + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + amountStr, err := cmd.Flags().GetString(flagAmount) + if err != nil { + return err + } + + amount, err := sdk.ParseCoinsNormalized(amountStr) + if err != nil { + return err + } + + msg := types.NewMsgPlaceOrders( + clientCtx.GetFromAddress().String(), + orders, + argContractAddr, + amount, + ) + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + cmd.Flags().String(flagAmount, "", "Coins to send to the contract along with command") + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/tx/tx_register_contract.go b/x/dex/client/cli/tx/tx_register_contract.go new file mode 100644 index 000000000..312435ab9 --- /dev/null +++ b/x/dex/client/cli/tx/tx_register_contract.go @@ -0,0 +1,68 @@ +package tx + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cast" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdRegisterContract() *cobra.Command { + cmd := &cobra.Command{ + Use: "register-contract [contract address] [code id] [(deprecated)] [need order matching] [deposit] [dependency1,dependency2,...]", + Short: "Register exchange contract", + Long: strings.TrimSpace(` + Register a contract with the dex module for order matching hooks. The available order matching functions are BulkOrderPlacements, BulkOrderCancellations, Settlement. A deposit can also be specified as the initial rent to allocate for the execution of the order matching. + Other orderbooks that are dependencies can also be specified so that dex orderbook processing can be performed in the appropriate order. + `), + Args: cobra.MinimumNArgs(5), + RunE: func(cmd *cobra.Command, args []string) (err error) { + argContractAddr := args[0] + argCodeID, err := cast.ToUint64E(args[1]) + if err != nil { + return err + } + argNeedMatching, err := strconv.ParseBool(args[3]) + if err != nil { + return err + } + argDeposit, err := cast.ToUint64E(args[4]) + if err != nil { + return err + } + var dependencies []*types.ContractDependencyInfo + for _, dependency := range args[5:] { + dependencies = append(dependencies, &types.ContractDependencyInfo{Dependency: dependency}) + } + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgRegisterContract( + clientCtx.GetFromAddress().String(), + argCodeID, + argContractAddr, + argNeedMatching, + dependencies, + argDeposit, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/tx/tx_register_pairs.go b/x/dex/client/cli/tx/tx_register_pairs.go new file mode 100644 index 000000000..61411c52c --- /dev/null +++ b/x/dex/client/cli/tx/tx_register_pairs.go @@ -0,0 +1,54 @@ +package tx + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + cutils "github.com/sei-protocol/sei-chain/x/dex/client/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdRegisterPairs() *cobra.Command { + cmd := &cobra.Command{ + Use: "register-pairs [register-pairs-file]", + Short: "Register pairs for a contract", + Long: strings.TrimSpace(` + This allows for registering new pairs with a json file representing the various pairs to be registered. The pairs are specified within the file using the contract address for the orderbook along with pair information. + `), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + registerTx, err := cutils.ParseRegisterPairsTxJSON(clientCtx.LegacyAmino, args[0]) + if err != nil { + return err + } + + txBatchContractPair, err := registerTx.BatchContractPair.ToMultipleBatchContractPair() + if err != nil { + return err + } + + msg := types.NewMsgRegisterPairs( + clientCtx.GetFromAddress().String(), + txBatchContractPair, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/tx/tx_unregister_contract.go b/x/dex/client/cli/tx/tx_unregister_contract.go new file mode 100644 index 000000000..08c187658 --- /dev/null +++ b/x/dex/client/cli/tx/tx_unregister_contract.go @@ -0,0 +1,46 @@ +package tx + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdUnregisterContract() *cobra.Command { + cmd := &cobra.Command{ + Use: "unregister-contract [contract address]", + Short: "Unregister exchange contract", + Long: strings.TrimSpace(` + Unregisters an exchange contract so it no longer receives the execution hooks or order matching hooks. + `), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + argContractAddr := args[0] + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgUnregisterContract( + clientCtx.GetFromAddress().String(), + argContractAddr, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/tx/tx_unsuspend_contract.go b/x/dex/client/cli/tx/tx_unsuspend_contract.go new file mode 100644 index 000000000..ce9203ca9 --- /dev/null +++ b/x/dex/client/cli/tx/tx_unsuspend_contract.go @@ -0,0 +1,46 @@ +package tx + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdUnsuspendContract() *cobra.Command { + cmd := &cobra.Command{ + Use: "unsuspend-contract [contract address]", + Short: "Unsuspend exchange contract", + Long: strings.TrimSpace(` + Unsuspend an exchange contract which was suspended due to Sudo malfunctioning, at a cost to its rent. + `), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + argContractAddr := args[0] + + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + msg := types.NewMsgUnsuspendContract( + clientCtx.GetFromAddress().String(), + argContractAddr, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/tx/tx_update_price_tick_size.go b/x/dex/client/cli/tx/tx_update_price_tick_size.go new file mode 100644 index 000000000..44dfedfe8 --- /dev/null +++ b/x/dex/client/cli/tx/tx_update_price_tick_size.go @@ -0,0 +1,54 @@ +package tx + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + cutils "github.com/sei-protocol/sei-chain/x/dex/client/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdUpdatePriceTickSize() *cobra.Command { + cmd := &cobra.Command{ + Use: "update-price-tick-size [update-price-tick-size-file]", + Short: "Update price tick size for a market", + Long: strings.TrimSpace(` + Updates the price tick size for a specific pair for an orderbook specified by contract address. The file contains a list of pair info, new tick size, and contract addresses to allow for updating multiple tick sizes in one transaction. + `), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + tickTx, err := cutils.ParseUpdateTickSizeTxJSON(clientCtx.LegacyAmino, args[0]) + if err != nil { + return err + } + + txTick, err := tickTx.TickSizes.ToTickSizes() + if err != nil { + return err + } + + msg := types.NewMsgUpdatePriceTickSize( + clientCtx.GetFromAddress().String(), + txTick, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/cli/tx/tx_update_quantity_tick_size.go b/x/dex/client/cli/tx/tx_update_quantity_tick_size.go new file mode 100644 index 000000000..5e46f50a0 --- /dev/null +++ b/x/dex/client/cli/tx/tx_update_quantity_tick_size.go @@ -0,0 +1,54 @@ +package tx + +import ( + "strconv" + "strings" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/client/tx" + cutils "github.com/sei-protocol/sei-chain/x/dex/client/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/spf13/cobra" +) + +var _ = strconv.Itoa(0) + +func CmdUpdateQuantityTickSize() *cobra.Command { + cmd := &cobra.Command{ + Use: "update-quantity-tick-size [update-quantity-tick-size-file]", + Short: "Update quantity tick size for a market", + Long: strings.TrimSpace(` + Updates the quantity tick size for a specific pair for an orderbook specified by contract address. The file contains a list of pair info, new tick size, and contract addresses to allow for updating multiple tick sizes in one transaction. + `), + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + tickTx, err := cutils.ParseUpdateTickSizeTxJSON(clientCtx.LegacyAmino, args[0]) + if err != nil { + return err + } + + txTick, err := tickTx.TickSizes.ToTickSizes() + if err != nil { + return err + } + + msg := types.NewMsgUpdateQuantityTickSize( + clientCtx.GetFromAddress().String(), + txTick, + ) + if err := msg.ValidateBasic(); err != nil { + return err + } + return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg) + }, + } + + flags.AddTxFlagsToCmd(cmd) + + return cmd +} diff --git a/x/dex/client/utils/utils.go b/x/dex/client/utils/utils.go new file mode 100644 index 000000000..a151b652c --- /dev/null +++ b/x/dex/client/utils/utils.go @@ -0,0 +1,203 @@ +package utils + +import ( + "errors" + "os" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" +) + +type ( + PairJSON struct { + PriceDenom string `json:"price_denom" yaml:"price_denom"` + AssetDenom string `json:"asset_denom" yaml:"asset_denom"` + PriceTickSize string `json:"price_tick_size" yaml:"tick_size"` + QuantityTickSize string `json:"quantity_tick_size" yaml:"tick_size"` + } + + TickSizeJSON struct { + Pair PairJSON `json:"pair" yaml:"pair"` + TickSize sdk.Dec `json:"tick_size" yaml:"tick_size"` + ContractAddr string `json:"contract_addr" yaml:"contract_addr"` + } + + PairsJSON []PairJSON + TickSizesJSON []TickSizeJSON + AssetListJSON []dextypes.AssetMetadata + + // ParamChangeJSON defines a parameter change used in JSON input. This + // allows values to be specified in raw JSON instead of being string encoded. + BatchContractPairJSON struct { + ContractAddr string `json:"contract_addr" yaml:"contract_addr"` + Pairs PairsJSON `json:"pairs" yaml:"pairs"` + } + + MultipleBatchContractPairJSON []BatchContractPairJSON + + // RegisterPairsTxJSON defines a RegisterPairsTx + // to parse register pair tx's from a JSON file. + RegisterPairsTxJSON struct { + BatchContractPair MultipleBatchContractPairJSON `json:"batch_contract_pair" yaml:"batch_contract_pair"` + } + + UpdateTickSizeTxJSON struct { + TickSizes TickSizesJSON `json:"tick_size_list" yaml:"tick_size_list"` + } + + AddAssetMetadataProposalJSON struct { + Title string `json:"title" yaml:"title"` + Description string `json:"description" yaml:"description"` + AssetList AssetListJSON `json:"asset_list" yaml:"asset_list"` + Deposit string `json:"deposit" yaml:"deposit"` + } +) + +// TODO: ADD utils to convert Each type to dex/type (string to denom) +func NewPair(pair PairJSON) (dextypes.Pair, error) { + PriceDenom := pair.PriceDenom + AssetDenom := pair.AssetDenom + priceTicksize, err := sdk.NewDecFromStr(pair.PriceTickSize) + if err != nil { + return dextypes.Pair{}, errors.New("price ticksize: str to decimal conversion err") + } + if priceTicksize.LTE(sdk.ZeroDec()) { + return dextypes.Pair{}, errors.New("price ticksize: value cannot be zero or negative") + } + quantityTicksize, err := sdk.NewDecFromStr(pair.QuantityTickSize) + if err != nil { + return dextypes.Pair{}, errors.New("quantity ticksize: str to decimal conversion err") + } + if quantityTicksize.LTE(sdk.ZeroDec()) { + return dextypes.Pair{}, errors.New("quantity ticksize: value cannot be zero or negative") + } + return dextypes.Pair{PriceDenom: PriceDenom, AssetDenom: AssetDenom, PriceTicksize: &priceTicksize, QuantityTicksize: &quantityTicksize}, nil +} + +// ToParamChange converts a ParamChangeJSON object to ParamChange. +func (bcp BatchContractPairJSON) ToBatchContractPair() (dextypes.BatchContractPair, error) { + pairs := make([]*dextypes.Pair, len(bcp.Pairs)) + for i, p := range bcp.Pairs { + newPair, err := NewPair(p) + if err != nil { + return dextypes.BatchContractPair{}, nil + } + pairs[i] = &newPair + } + return dextypes.BatchContractPair{ContractAddr: bcp.ContractAddr, Pairs: pairs}, nil +} + +func (ts TickSizeJSON) ToTickSize() (dextypes.TickSize, error) { + // validate the tick size here + pair, err := NewPair(ts.Pair) + if err != nil { + return dextypes.TickSize{}, err + } + return dextypes.TickSize{ + Pair: &pair, + Ticksize: ts.TickSize, + ContractAddr: ts.ContractAddr, + }, nil +} + +// ToParamChanges converts a slice of ParamChangeJSON objects to a slice of +// ParamChange. +func (mbcp MultipleBatchContractPairJSON) ToMultipleBatchContractPair() ([]dextypes.BatchContractPair, error) { + res := make([]dextypes.BatchContractPair, len(mbcp)) + for i, bcp := range mbcp { + newBatch, err := bcp.ToBatchContractPair() + if err != nil { + return res, nil + } + res[i] = newBatch + } + return res, nil +} + +func (tss TickSizesJSON) ToTickSizes() ([]dextypes.TickSize, error) { + res := make([]dextypes.TickSize, len(tss)) + for i, ts := range tss { + ticksize, err := ts.ToTickSize() + if err != nil { + return res, nil + } + res[i] = ticksize + } + return res, nil +} + +// ParseRegisterPairsTxJSON reads and parses a RegisterPairsTxJSON from +// a file. +func ParseRegisterPairsTxJSON(cdc *codec.LegacyAmino, txFile string) (RegisterPairsTxJSON, error) { + registerTx := RegisterPairsTxJSON{} + + contents, err := os.ReadFile(txFile) + if err != nil { + return registerTx, err + } + + if err := cdc.UnmarshalJSON(contents, ®isterTx); err != nil { + return registerTx, err + } + + return registerTx, nil +} + +// ParseUpdateTickSizeTxJSON reads and parses a UpdateTickSizeTxJSON from +// a file. +func ParseUpdateTickSizeTxJSON(cdc *codec.LegacyAmino, txFile string) (UpdateTickSizeTxJSON, error) { + tickTx := UpdateTickSizeTxJSON{} + + contents, err := os.ReadFile(txFile) + if err != nil { + return tickTx, err + } + + if err := cdc.UnmarshalJSON(contents, &tickTx); err != nil { + return tickTx, err + } + + return tickTx, nil +} + +// ParseAddAssetMetadataProposalJSON reads and parses an AddAssetMetadataProposalJSON from +// a file. +func ParseAddAssetMetadataProposalJSON(cdc *codec.LegacyAmino, proposalFile string) (AddAssetMetadataProposalJSON, error) { + proposal := AddAssetMetadataProposalJSON{} + + contents, err := os.ReadFile(proposalFile) + if err != nil { + return proposal, err + } + + if err := cdc.UnmarshalJSON(contents, &proposal); err != nil { + return proposal, err + } + + // Verify base denoms specified in proposal are well formed + // Additionally verify that the asset "display" field is included in denom unit + for _, asset := range proposal.AssetList { + err := sdk.ValidateDenom(asset.Metadata.Base) + if err != nil { + return AddAssetMetadataProposalJSON{}, err + } + + // The display denom must have an associated DenomUnit field + display := asset.Metadata.Display + found := false + for _, denomUnit := range asset.Metadata.DenomUnits { + if denomUnit.Denom == display { + found = true + break + } + } + + if !found { + return AddAssetMetadataProposalJSON{}, errors.New("Display denom " + display + " has no associated DenomUnit in Metadata.") + } + + } + + return proposal, nil +} diff --git a/x/dex/client/wasm/bindings/queries.go b/x/dex/client/wasm/bindings/queries.go new file mode 100644 index 000000000..12fbe2a10 --- /dev/null +++ b/x/dex/client/wasm/bindings/queries.go @@ -0,0 +1,12 @@ +package bindings + +import "github.com/sei-protocol/sei-chain/x/dex/types" + +type SeiDexQuery struct { + // queries the dex TWAPs + DexTwaps *types.QueryGetTwapsRequest `json:"dex_twaps,omitempty"` + GetOrders *types.QueryGetOrdersRequest `json:"get_orders,omitempty"` + GetOrderByID *types.QueryGetOrderByIDRequest `json:"get_order_by_id,omitempty"` + GetOrderSimulation *types.QueryOrderSimulationRequest `json:"order_simulation,omitempty"` + GetLatestPrice *types.QueryGetLatestPriceRequest `json:"get_latest_price,omitempty"` +} diff --git a/x/dex/client/wasm/encoder.go b/x/dex/client/wasm/encoder.go new file mode 100644 index 000000000..0a56156a4 --- /dev/null +++ b/x/dex/client/wasm/encoder.go @@ -0,0 +1,36 @@ +package wasm + +import ( + "encoding/json" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/wasmbinding/bindings" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func EncodeDexPlaceOrders(rawMsg json.RawMessage, sender sdk.AccAddress) ([]sdk.Msg, error) { + encodedPlaceOrdersMsg := bindings.PlaceOrders{} + if err := json.Unmarshal(rawMsg, &encodedPlaceOrdersMsg); err != nil { + return []sdk.Msg{}, types.ErrEncodeDexPlaceOrders + } + placeOrdersMsg := types.MsgPlaceOrders{ + Creator: sender.String(), + Orders: encodedPlaceOrdersMsg.Orders, + ContractAddr: encodedPlaceOrdersMsg.ContractAddr, + Funds: encodedPlaceOrdersMsg.Funds, + } + return []sdk.Msg{&placeOrdersMsg}, nil +} + +func EncodeDexCancelOrders(rawMsg json.RawMessage, sender sdk.AccAddress) ([]sdk.Msg, error) { + encodedCancelOrdersMsg := bindings.CancelOrders{} + if err := json.Unmarshal(rawMsg, &encodedCancelOrdersMsg); err != nil { + return []sdk.Msg{}, types.ErrEncodeDexCancelOrders + } + cancelOrdersMsg := types.MsgCancelOrders{ + Creator: sender.String(), + Cancellations: encodedCancelOrdersMsg.Cancellations, + ContractAddr: encodedCancelOrdersMsg.ContractAddr, + } + return []sdk.Msg{&cancelOrdersMsg}, nil +} diff --git a/x/dex/client/wasm/query.go b/x/dex/client/wasm/query.go new file mode 100644 index 000000000..41f86f162 --- /dev/null +++ b/x/dex/client/wasm/query.go @@ -0,0 +1,48 @@ +package wasm + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +type DexWasmQueryHandler struct { + dexKeeper keeper.Keeper +} + +func NewDexWasmQueryHandler(keeper *keeper.Keeper) *DexWasmQueryHandler { + return &DexWasmQueryHandler{ + dexKeeper: *keeper, + } +} + +func (handler DexWasmQueryHandler) GetDexTwap(ctx sdk.Context, req *types.QueryGetTwapsRequest) (*types.QueryGetTwapsResponse, error) { + c := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: &handler.dexKeeper} + return wrapper.GetTwaps(c, req) +} + +func (handler DexWasmQueryHandler) GetOrders(ctx sdk.Context, req *types.QueryGetOrdersRequest) (*types.QueryGetOrdersResponse, error) { + c := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: &handler.dexKeeper} + return wrapper.GetOrders(c, req) +} + +func (handler DexWasmQueryHandler) GetOrderByID(ctx sdk.Context, req *types.QueryGetOrderByIDRequest) (*types.QueryGetOrderByIDResponse, error) { + c := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: &handler.dexKeeper} + return wrapper.GetOrder(c, req) +} + +func (handler DexWasmQueryHandler) GetOrderSimulation(ctx sdk.Context, req *types.QueryOrderSimulationRequest) (*types.QueryOrderSimulationResponse, error) { + c := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: &handler.dexKeeper} + return wrapper.GetOrderSimulation(c, req) +} + +func (handler DexWasmQueryHandler) GetLatestPrice(ctx sdk.Context, req *types.QueryGetLatestPriceRequest) (*types.QueryGetLatestPriceResponse, error) { + c := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: &handler.dexKeeper} + return wrapper.GetLatestPrice(c, req) +} diff --git a/x/dex/contract/abci.go b/x/dex/contract/abci.go new file mode 100644 index 000000000..712c01c67 --- /dev/null +++ b/x/dex/contract/abci.go @@ -0,0 +1,323 @@ +package contract + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "github.com/cosmos/cosmos-sdk/telemetry" + "github.com/cosmos/cosmos-sdk/utils/tracing" + "github.com/sei-protocol/sei-chain/utils/logging" + + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + "github.com/sei-protocol/sei-chain/store/whitelist/multi" + seisync "github.com/sei-protocol/sei-chain/sync" + "github.com/sei-protocol/sei-chain/utils/datastructures" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + dexkeeperabci "github.com/sei-protocol/sei-chain/x/dex/keeper/abci" + dexkeeperutils "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/sei-protocol/sei-chain/x/store" + otrace "go.opentelemetry.io/otel/trace" +) + +const LogRunnerRunAfter = 10 * time.Second +const LogExecSigSendAfter = 2 * time.Second + +type environment struct { + validContractsInfo []types.ContractInfoV2 + failedContractAddressesToErrors *datastructures.TypedSyncMap[string, error] + outOfRentContractAddresses datastructures.SyncSet[string] + settlementsByContract *datastructures.TypedSyncMap[string, []*types.SettlementEntry] + executionTerminationSignals *datastructures.TypedSyncMap[string, chan struct{}] + registeredPairs *datastructures.TypedSyncMap[string, []types.Pair] + orderBooks *datastructures.TypedNestedSyncMap[string, types.PairString, *types.OrderBook] + + finalizeMsgMutex *sync.Mutex + eventManagerMutex *sync.Mutex +} + +func EndBlockerAtomic(ctx sdk.Context, keeper *keeper.Keeper, validContractsInfo []types.ContractInfoV2, tracingInfo *tracing.Info) ([]types.ContractInfoV2, []types.ContractInfoV2, map[string]string, sdk.Context, bool) { + tracer := tracingInfo.Tracer + spanCtx, span := tracingInfo.Start("DexEndBlockerAtomic") + defer span.End() + defer telemetry.MeasureSince(time.Now(), "dex", "end_blocker_atomic") + + env := newEnv(ctx, validContractsInfo, keeper) + cachedCtx, msCached := cacheContext(ctx, env) + memStateCopy := dexutils.GetMemState(cachedCtx.Context()).DeepCopy() + contractsToProcess := memStateCopy.GetContractToProcessOrderedSlice(cachedCtx) + preRunRents := keeper.GetRentsForContracts(cachedCtx, contractsToProcess) + + handleDeposits(spanCtx, cachedCtx, env, keeper, tracer) + + runner := NewParallelRunner(func(contract types.ContractInfoV2) { + OrderMatchingRunnable(spanCtx, cachedCtx, env, keeper, contract, tracer) + }, validContractsInfo, cachedCtx) + + _, err := logging.LogIfNotDoneAfter(ctx.Logger(), func() (struct{}, error) { + runner.Run() + return struct{}{}, nil + }, LogRunnerRunAfter, "runner run") + if err != nil { + // this should never happen + panic(err) + } + + handleSettlements(spanCtx, cachedCtx, env, keeper, tracer) + handleUnfulfilledMarketOrders(spanCtx, cachedCtx, env, keeper, tracer) + + telemetry.IncrCounter(float32(env.failedContractAddressesToErrors.Len()), "dex", "total_failed_contracts") + // No error is thrown for any contract. This should happen most of the time. + if env.failedContractAddressesToErrors.Len() == 0 { + postRunRents := keeper.GetRentsForContracts(cachedCtx, contractsToProcess) + TransferRentFromDexToCollector(cachedCtx, keeper.BankKeeper, preRunRents, postRunRents) + msCached.Write() + return env.validContractsInfo, []types.ContractInfoV2{}, map[string]string{}, ctx, true + } + + failedContractsToReasons := map[string]string{} + failedContractsPreRents := map[string]uint64{} + failedContractsPostRents := map[string]uint64{} + // persistent contract rent charges for failed contracts and discard everything else + env.failedContractAddressesToErrors.Range(func(failedContractAddress string, failedReason error) bool { + cachedContract, err := keeper.GetContract(cachedCtx, failedContractAddress) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error %s when getting updated contract %s to persist rent balance", err, failedContractAddress)) + return true + } + contract, err := keeper.GetContract(ctx, failedContractAddress) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error %s when getting contract %s to persist rent balance", err, failedContractAddress)) + return true + } + contract.RentBalance = cachedContract.RentBalance + failedContractsPreRents[failedContractAddress] = preRunRents[failedContractAddress] + failedContractsPostRents[failedContractAddress] = contract.RentBalance + err = keeper.SetContract(ctx, &contract) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error %s when persisting contract %s's rent balance", err, failedContractAddress)) + return true + } + failedContractsToReasons[failedContractAddress] = dexutils.GetTruncatedErrors(failedReason) + return true + }) + TransferRentFromDexToCollector(ctx, keeper.BankKeeper, failedContractsPreRents, failedContractsPostRents) + + // restore keeper in-memory state + newGoContext := context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, memStateCopy) + return filterNewValidContracts(ctx, env), getOutOfRentContracts(env), failedContractsToReasons, ctx.WithContext(newGoContext), false +} + +func newEnv(ctx sdk.Context, validContractsInfo []types.ContractInfoV2, keeper *keeper.Keeper) *environment { + settlementsByContract := datastructures.NewTypedSyncMap[string, []*types.SettlementEntry]() + executionTerminationSignals := datastructures.NewTypedSyncMap[string, chan struct{}]() + registeredPairs := datastructures.NewTypedSyncMap[string, []types.Pair]() + allContractAndPairs := map[string][]types.Pair{} + for _, contract := range validContractsInfo { + settlementsByContract.Store(contract.ContractAddr, []*types.SettlementEntry{}) + executionTerminationSignals.Store(contract.ContractAddr, make(chan struct{}, 1)) + contractPairs := keeper.GetAllRegisteredPairs(ctx, contract.ContractAddr) + registeredPairs.Store(contract.ContractAddr, contractPairs) + allContractAndPairs[contract.ContractAddr] = contractPairs + } + // Parallelize populating orderbooks for performance improvements + orderBooks := dexkeeperutils.PopulateAllOrderbooks(ctx, keeper, allContractAndPairs) + return &environment{ + validContractsInfo: validContractsInfo, + failedContractAddressesToErrors: datastructures.NewTypedSyncMap[string, error](), + outOfRentContractAddresses: datastructures.NewSyncSet([]string{}), + settlementsByContract: settlementsByContract, + executionTerminationSignals: executionTerminationSignals, + registeredPairs: registeredPairs, + orderBooks: orderBooks, + finalizeMsgMutex: &sync.Mutex{}, + eventManagerMutex: &sync.Mutex{}, + } +} + +func (e *environment) addError(contractAddr string, err error) { + if err == types.ErrInsufficientRent { + e.outOfRentContractAddresses.Add(contractAddr) + return + } + e.failedContractAddressesToErrors.Store(contractAddr, err) +} + +func cacheContext(ctx sdk.Context, env *environment) (sdk.Context, sdk.CacheMultiStore) { + cachedCtx, msCached := store.GetCachedContext(ctx) + goCtx := context.WithValue(cachedCtx.Context(), dexcache.CtxKeyExecTermSignal, env.executionTerminationSignals) + cachedCtx = cachedCtx.WithContext(goCtx) + return cachedCtx, msCached +} + +func decorateContextForContract(ctx sdk.Context, contractInfo types.ContractInfoV2) sdk.Context { + goCtx := context.WithValue(ctx.Context(), dexcache.CtxKeyExecutingContract, contractInfo) + whitelistedStore := multi.NewStore(ctx.MultiStore(), GetWhitelistMap(contractInfo.ContractAddr)) + newEventManager := sdk.NewEventManager() + return ctx.WithContext(goCtx).WithMultiStore(whitelistedStore).WithEventManager(newEventManager).WithGasMeter( + seisync.NewGasWrapper(sdk.NewInfiniteGasMeterWithMultiplier(ctx)), + ) +} + +func handleDeposits(spanCtx context.Context, ctx sdk.Context, env *environment, keeper *keeper.Keeper, tracer *otrace.Tracer) { + // Handle deposit sequentially since they mutate `bank` state which is shared by all contracts + _, span := (*tracer).Start(spanCtx, "handleDeposits") + defer span.End() + defer telemetry.MeasureSince(time.Now(), "dex", "handle_deposits") + keeperWrapper := dexkeeperabci.KeeperWrapper{Keeper: keeper} + for _, contract := range env.validContractsInfo { + if !dexutils.GetMemState(ctx.Context()).ContractsToProcessContains(ctx, contract.ContractAddr) { + continue + } + if !contract.NeedOrderMatching { + continue + } + if err := keeperWrapper.HandleEBDeposit(spanCtx, ctx, tracer, contract.ContractAddr); err != nil { + env.addError(contract.ContractAddr, err) + } + } +} + +func handleSettlements(ctx context.Context, sdkCtx sdk.Context, env *environment, keeper *keeper.Keeper, tracer *otrace.Tracer) { + _, span := (*tracer).Start(ctx, "DexEndBlockerHandleSettlements") + defer span.End() + defer telemetry.MeasureSince(time.Now(), "dex", "handle_settlements") + contractsNeedOrderMatching := datastructures.NewSyncSet([]string{}) + for _, contract := range env.validContractsInfo { + if contract.NeedOrderMatching { + contractsNeedOrderMatching.Add(contract.ContractAddr) + } + } + env.settlementsByContract.Range(func(contractAddr string, settlements []*types.SettlementEntry) bool { + if !contractsNeedOrderMatching.Contains(contractAddr) { + return true + } + if err := HandleSettlements(sdkCtx, contractAddr, keeper, settlements); err != nil { + sdkCtx.Logger().Error(fmt.Sprintf("Error handling settlements for %s", contractAddr)) + env.addError(contractAddr, err) + } + return true + }) +} + +func handleUnfulfilledMarketOrders(ctx context.Context, sdkCtx sdk.Context, env *environment, keeper *keeper.Keeper, tracer *otrace.Tracer) { + // Cancel unfilled market orders + defer telemetry.MeasureSince(time.Now(), "dex", "handle_unfulfilled_market_orders") + for _, contract := range env.validContractsInfo { + if !dexutils.GetMemState(sdkCtx.Context()).ContractsToProcessContains(sdkCtx, contract.ContractAddr) { + return + } + if contract.NeedOrderMatching { + registeredPairs, found := env.registeredPairs.Load(contract.ContractAddr) + if !found { + continue + } + if err := CancelUnfulfilledMarketOrders(ctx, sdkCtx, contract.ContractAddr, keeper, registeredPairs, tracer); err != nil { + sdkCtx.Logger().Error(fmt.Sprintf("Error cancelling unfulfilled market orders for %s", contract.ContractAddr)) + env.addError(contract.ContractAddr, err) + } + } + } +} + +func OrderMatchingRunnable(ctx context.Context, sdkContext sdk.Context, env *environment, keeper *keeper.Keeper, contractInfo types.ContractInfoV2, tracer *otrace.Tracer) { + defer func() { + if err := recover(); err != nil { + telemetry.IncrCounter(1, "recovered_panics") + msg := fmt.Sprintf("PANIC RECOVERED during order matching: %s", err) + sdkContext.Logger().Error(msg) + if env != nil { + env.addError(contractInfo.ContractAddr, errors.New(msg)) + } + } + }() + _, span := (*tracer).Start(ctx, "OrderMatchingRunnable") + defer span.End() + defer telemetry.MeasureSince(time.Now(), "dex", "order_matching_runnable") + defer func() { + if channel, ok := env.executionTerminationSignals.Load(contractInfo.ContractAddr); ok { + _, err := logging.LogIfNotDoneAfter(sdkContext.Logger(), func() (struct{}, error) { + channel <- struct{}{} + return struct{}{}, nil + }, LogExecSigSendAfter, fmt.Sprintf("send execution terminal signal for %s", contractInfo.ContractAddr)) + if err != nil { + // this should never happen + panic(err) + } + } + }() + if !dexutils.GetMemState(sdkContext.Context()).ContractsToProcessContains(sdkContext, contractInfo.ContractAddr) { + return + } + if !contractInfo.NeedOrderMatching { + return + } + parentSdkContext := sdkContext + sdkContext = decorateContextForContract(sdkContext, contractInfo) + sdkContext.Logger().Debug(fmt.Sprintf("End block for %s with balance of %d", contractInfo.ContractAddr, contractInfo.RentBalance)) + pairs, pairFound := env.registeredPairs.Load(contractInfo.ContractAddr) + orderBooks, found := env.orderBooks.Load(contractInfo.ContractAddr) + + if !pairFound || !found { + sdkContext.Logger().Error(fmt.Sprintf("No pair or order book for %s", contractInfo.ContractAddr)) + env.addError(contractInfo.ContractAddr, errors.New("no pair found (internal error)")) + } else if settlements, err := HandleExecutionForContract(ctx, sdkContext, contractInfo, keeper, pairs, orderBooks, tracer); err != nil { + sdkContext.Logger().Error(fmt.Sprintf("Error for EndBlock of %s", contractInfo.ContractAddr)) + env.addError(contractInfo.ContractAddr, err) + } else { + env.settlementsByContract.Store(contractInfo.ContractAddr, settlements) + } + + // ordering of events doesn't matter since events aren't part of consensus + env.eventManagerMutex.Lock() + defer env.eventManagerMutex.Unlock() + parentSdkContext.EventManager().EmitEvents(sdkContext.EventManager().Events()) +} + +func filterNewValidContracts(ctx sdk.Context, env *environment) []types.ContractInfoV2 { + newValidContracts := []types.ContractInfoV2{} + for _, contract := range env.validContractsInfo { + if _, ok := env.failedContractAddressesToErrors.Load(contract.ContractAddr); !ok && !env.outOfRentContractAddresses.Contains(contract.ContractAddr) { + newValidContracts = append(newValidContracts, contract) + } + } + env.failedContractAddressesToErrors.Range(func(failedContractAddress string, _ error) bool { + dexutils.GetMemState(ctx.Context()).DeepFilterAccount(ctx, failedContractAddress) + return true + }) + for _, outOfRentContractAddress := range env.outOfRentContractAddresses.ToOrderedSlice(datastructures.StringComparator) { + dexutils.GetMemState(ctx.Context()).DeepFilterAccount(ctx, outOfRentContractAddress) + } + return newValidContracts +} + +func getOutOfRentContracts(env *environment) []types.ContractInfoV2 { + outOfRentContracts := []types.ContractInfoV2{} + for _, contract := range env.validContractsInfo { + if env.outOfRentContractAddresses.Contains(contract.ContractAddr) { + outOfRentContracts = append(outOfRentContracts, contract) + } + } + return outOfRentContracts +} + +func TransferRentFromDexToCollector(ctx sdk.Context, bankKeeper bankkeeper.Keeper, preRents map[string]uint64, postRents map[string]uint64) { + total := uint64(0) + for addr, preRent := range preRents { + if postRent, ok := postRents[addr]; ok { + total += preRent - postRent + } else { + total += preRent + } + } + if err := bankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, authtypes.FeeCollectorName, sdk.NewCoins(sdk.NewCoin("usei", sdk.NewIntFromUint64(total)))); err != nil { + ctx.Logger().Error("sending coins from dex to fee collector failed due to %s", err) + } +} diff --git a/x/dex/contract/abci_test.go b/x/dex/contract/abci_test.go new file mode 100644 index 000000000..3d0b7650b --- /dev/null +++ b/x/dex/contract/abci_test.go @@ -0,0 +1,43 @@ +package contract_test + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/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/types" + minttypes "github.com/sei-protocol/sei-chain/x/mint/types" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestTransferRentFromDexToCollector(t *testing.T) { + preRents := map[string]uint64{"abc": 100, "def": 50} + postRents := map[string]uint64{"abc": 70} + + // expected total is (100 - 70) + 50 = 80 + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + bankkeeper := testApp.BankKeeper + err := bankkeeper.MintCoins(ctx, minttypes.ModuleName, sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100)))) + require.Nil(t, err) + err = bankkeeper.SendCoinsFromModuleToModule(ctx, minttypes.ModuleName, types.ModuleName, sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100)))) + require.Nil(t, err) + contract.TransferRentFromDexToCollector(ctx, bankkeeper, preRents, postRents) + dexBalance := bankkeeper.GetBalance(ctx, testApp.AccountKeeper.GetModuleAddress(types.ModuleName), "usei") + require.Equal(t, int64(20), dexBalance.Amount.Int64()) + collectorBalance := bankkeeper.GetBalance(ctx, testApp.AccountKeeper.GetModuleAddress(authtypes.FeeCollectorName), "usei") + require.Equal(t, int64(80), collectorBalance.Amount.Int64()) +} + +func TestOrderMatchingRunnablePanicHandler(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + require.NotPanics(t, func() { + contract.OrderMatchingRunnable(context.Background(), ctx, nil, nil, types.ContractInfoV2{}, nil) + }) +} diff --git a/x/dex/contract/dag.go b/x/dex/contract/dag.go new file mode 100644 index 000000000..761a9d7c2 --- /dev/null +++ b/x/dex/contract/dag.go @@ -0,0 +1,78 @@ +package contract + +import ( + "github.com/sei-protocol/sei-chain/utils/datastructures" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +type node struct { + contractAddr string + incomingNodes *datastructures.SyncSet[string] +} + +// Kahn's algorithm +func TopologicalSortContractInfo(contracts []types.ContractInfoV2) ([]types.ContractInfoV2, error) { + contractAddrToContractInfo := map[string]types.ContractInfoV2{} + for _, contract := range contracts { + contractAddrToContractInfo[contract.ContractAddr] = contract + } + + res := []types.ContractInfoV2{} + nodes := initNodes(contracts) + frontierNodes, nonFrontierNodes := splitNodesByFrontier(nodes) + for len(frontierNodes) > 0 { + for _, frontierNode := range frontierNodes { + if contract, ok := contractAddrToContractInfo[frontierNode.contractAddr]; ok { + res = append(res, contract) + } + for _, nonFrontierNode := range nonFrontierNodes { + nonFrontierNode.incomingNodes.Remove(frontierNode.contractAddr) + } + } + frontierNodes, nonFrontierNodes = splitNodesByFrontier(nonFrontierNodes) + } + if len(nonFrontierNodes) > 0 { + return []types.ContractInfoV2{}, types.ErrCircularContractDependency + } + return res, nil +} + +func initNodes(contracts []types.ContractInfoV2) map[string]node { + res := map[string]node{} + for _, contract := range contracts { + if _, ok := res[contract.ContractAddr]; !ok { + emptyIncomingNodes := datastructures.NewSyncSet([]string{}) + res[contract.ContractAddr] = node{ + contractAddr: contract.ContractAddr, + incomingNodes: &emptyIncomingNodes, + } + } + if contract.Dependencies == nil { + continue + } + for _, dependentContract := range contract.Dependencies { + dependentAddr := dependentContract.Dependency + if _, ok := res[dependentAddr]; !ok { + emptyIncomingNodes := datastructures.NewSyncSet([]string{}) + res[dependentAddr] = node{ + contractAddr: dependentAddr, + incomingNodes: &emptyIncomingNodes, + } + } + res[dependentAddr].incomingNodes.Add(contract.ContractAddr) + } + } + return res +} + +func splitNodesByFrontier(nodes map[string]node) (map[string]node, map[string]node) { + frontierNodes, nonFrontierNodes := map[string]node{}, map[string]node{} + for contractAddr, node := range nodes { + if node.incomingNodes.Size() == 0 { + frontierNodes[contractAddr] = node + } else { + nonFrontierNodes[contractAddr] = node + } + } + return frontierNodes, nonFrontierNodes +} diff --git a/x/dex/contract/dag_test.go b/x/dex/contract/dag_test.go new file mode 100644 index 000000000..a5842ca21 --- /dev/null +++ b/x/dex/contract/dag_test.go @@ -0,0 +1,110 @@ +package contract_test + +import ( + "testing" + + "github.com/sei-protocol/sei-chain/x/dex/contract" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +// A -> B -> C +func TestTopologicalSortContractInfoSimple(t *testing.T) { + a := types.ContractInfoV2{ + ContractAddr: "A", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "B", + }, + }, + } + b := types.ContractInfoV2{ + ContractAddr: "B", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "C", + }, + }, + } + c := types.ContractInfoV2{ + ContractAddr: "C", + } + res, err := contract.TopologicalSortContractInfo([]types.ContractInfoV2{b, c, a}) + require.Nil(t, err) + require.Equal(t, "A", res[0].ContractAddr) + require.Equal(t, "B", res[1].ContractAddr) + require.Equal(t, "C", res[2].ContractAddr) +} + +// A -> B, C -> D +func TestTopologicalSortContractInfoIsolated(t *testing.T) { + a := types.ContractInfoV2{ + ContractAddr: "A", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "B", + }, + }, + } + b := types.ContractInfoV2{ + ContractAddr: "B", + } + c := types.ContractInfoV2{ + ContractAddr: "C", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "D", + }, + }, + } + d := types.ContractInfoV2{ + ContractAddr: "D", + } + res, err := contract.TopologicalSortContractInfo([]types.ContractInfoV2{b, c, a, d}) + require.Nil(t, err) + aidx, bidx, cidx, didx := -1, -1, -1, -1 + for i, c := range res { + if c.ContractAddr == "A" { + aidx = i + } else if c.ContractAddr == "B" { + bidx = i + } else if c.ContractAddr == "C" { + cidx = i + } else if c.ContractAddr == "D" { + didx = i + } + } + require.True(t, aidx != -1 && aidx < bidx) + require.True(t, cidx != -1 && cidx < didx) +} + +// A -> B -> C -> A +func TestTopologicalSortContractInfoCircular(t *testing.T) { + a := types.ContractInfoV2{ + ContractAddr: "A", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "B", + }, + }, + } + b := types.ContractInfoV2{ + ContractAddr: "B", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "C", + }, + }, + } + c := types.ContractInfoV2{ + ContractAddr: "C", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "A", + }, + }, + } + res, err := contract.TopologicalSortContractInfo([]types.ContractInfoV2{b, c, a}) + require.NotNil(t, err) + require.Equal(t, 0, len(res)) +} diff --git a/x/dex/contract/execution.go b/x/dex/contract/execution.go new file mode 100644 index 000000000..2c1614f1e --- /dev/null +++ b/x/dex/contract/execution.go @@ -0,0 +1,219 @@ +package contract + +import ( + "context" + "fmt" + "time" + + otrace "go.opentelemetry.io/otel/trace" + + "github.com/cosmos/cosmos-sdk/telemetry" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/store/whitelist/multi" + "github.com/sei-protocol/sei-chain/utils/datastructures" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + dexkeeperabci "github.com/sei-protocol/sei-chain/x/dex/keeper/abci" + dexkeeperutils "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "go.opentelemetry.io/otel/attribute" +) + +func CallPreExecutionHooks( + ctx context.Context, + sdkCtx sdk.Context, + contractAddr string, + dexkeeper *keeper.Keeper, + registeredPairs []types.Pair, + tracer *otrace.Tracer, +) error { + spanCtx, span := (*tracer).Start(ctx, "PreExecutionHooks") + defer span.End() + span.SetAttributes(attribute.String("contract", contractAddr)) + abciWrapper := dexkeeperabci.KeeperWrapper{Keeper: dexkeeper} + if err := abciWrapper.HandleEBCancelOrders(spanCtx, sdkCtx, tracer, contractAddr, registeredPairs); err != nil { + return err + } + return abciWrapper.HandleEBPlaceOrders(spanCtx, sdkCtx, tracer, contractAddr, registeredPairs) +} + +func ExecutePair( + ctx sdk.Context, + contractAddr string, + pair types.Pair, + dexkeeper *keeper.Keeper, + orderbook *types.OrderBook, +) []*types.SettlementEntry { + typedContractAddr := types.ContractAddress(contractAddr) + + // First cancel orders + cancelForPair(ctx, dexkeeper, typedContractAddr, pair) + // Add all limit orders to the orderbook + orders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, typedContractAddr, pair) + limitBuys := orders.GetLimitOrders(types.PositionDirection_LONG) + limitSells := orders.GetLimitOrders(types.PositionDirection_SHORT) + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, limitBuys, limitSells) + // Fill market orders + marketOrderOutcome := matchMarketOrderForPair(ctx, typedContractAddr, pair, orderbook) + // Fill limit orders + limitOrderOutcome := exchange.MatchLimitOrders(ctx, orderbook) + totalOutcome := marketOrderOutcome.Merge(&limitOrderOutcome) + + dexkeeperutils.SetPriceStateFromExecutionOutcome(ctx, dexkeeper, typedContractAddr, pair, totalOutcome) + + return totalOutcome.Settlements +} + +func cancelForPair( + ctx sdk.Context, + keeper *keeper.Keeper, + contractAddress types.ContractAddress, + pair types.Pair, +) { + cancels := dexutils.GetMemState(ctx.Context()).GetBlockCancels(ctx, contractAddress, pair) + exchange.CancelOrders(ctx, keeper, contractAddress, pair, cancels.Get()) +} + +func matchMarketOrderForPair( + ctx sdk.Context, + typedContractAddr types.ContractAddress, + pair types.Pair, + orderbook *types.OrderBook, +) exchange.ExecutionOutcome { + orders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, typedContractAddr, pair) + marketBuys := orders.GetSortedMarketOrders(types.PositionDirection_LONG) + marketSells := orders.GetSortedMarketOrders(types.PositionDirection_SHORT) + marketBuyOutcome := exchange.MatchMarketOrders( + ctx, + marketBuys, + orderbook.Shorts, + types.PositionDirection_LONG, + orders, + ) + marketSellOutcome := exchange.MatchMarketOrders( + ctx, + marketSells, + orderbook.Longs, + types.PositionDirection_SHORT, + orders, + ) + return marketBuyOutcome.Merge(&marketSellOutcome) +} + +func GetMatchResults( + ctx sdk.Context, + typedContractAddr types.ContractAddress, + pair types.Pair, +) ([]*types.Order, []*types.Cancellation) { + orderResults := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, typedContractAddr, pair).Get() + cancelResults := dexutils.GetMemState(ctx.Context()).GetBlockCancels(ctx, typedContractAddr, pair).Get() + return orderResults, cancelResults +} + +func GetOrderIDToSettledQuantities(settlements []*types.SettlementEntry) map[uint64]sdk.Dec { + res := map[uint64]sdk.Dec{} + for _, settlement := range settlements { + if _, ok := res[settlement.OrderId]; !ok { + res[settlement.OrderId] = sdk.ZeroDec() + } + res[settlement.OrderId] = res[settlement.OrderId].Add(settlement.Quantity) + } + return res +} + +func ExecutePairsInParallel(ctx sdk.Context, contractAddr string, dexkeeper *keeper.Keeper, registeredPairs []types.Pair, orderBooks *datastructures.TypedSyncMap[types.PairString, *types.OrderBook]) []*types.SettlementEntry { + typedContractAddr := types.ContractAddress(contractAddr) + orderResults := []*types.Order{} + cancelResults := []*types.Cancellation{} + settlements := []*types.SettlementEntry{} + + // mu := sync.Mutex{} + // wg := sync.WaitGroup{} + + for _, pair := range registeredPairs { + // wg.Add(1) + + pair := pair + pairCtx := ctx.WithMultiStore(multi.NewStore(ctx.MultiStore(), GetPerPairWhitelistMap(contractAddr, pair))).WithEventManager(sdk.NewEventManager()) + // go func() { + func() { + // defer wg.Done() + pairCopy := pair + pairStr := types.GetPairString(&pairCopy) + orderbook, found := orderBooks.Load(pairStr) + if !found { + panic(fmt.Sprintf("Orderbook not found for %s", pairCopy.String())) + } + pairSettlements := ExecutePair(pairCtx, contractAddr, pair, dexkeeper, orderbook) + orderIDToSettledQuantities := GetOrderIDToSettledQuantities(pairSettlements) + PrepareCancelUnfulfilledMarketOrders(pairCtx, typedContractAddr, pairCopy, orderIDToSettledQuantities) + + // mu.Lock() + // defer mu.Unlock() + orders, cancels := GetMatchResults(ctx, typedContractAddr, pairCopy) + orderResults = append(orderResults, orders...) + cancelResults = append(cancelResults, cancels...) + settlements = append(settlements, pairSettlements...) + // ordering of events doesn't matter since events aren't part of consensus + ctx.EventManager().EmitEvents(pairCtx.EventManager().Events()) + }() + } + // wg.Wait() + dexkeeper.SetMatchResult(ctx, contractAddr, types.NewMatchResult(orderResults, cancelResults, settlements)) + + return settlements +} + +func HandleExecutionForContract( + ctx context.Context, + sdkCtx sdk.Context, + contract types.ContractInfoV2, + dexkeeper *keeper.Keeper, + registeredPairs []types.Pair, + orderBooks *datastructures.TypedSyncMap[types.PairString, *types.OrderBook], + tracer *otrace.Tracer, +) ([]*types.SettlementEntry, error) { + executionStart := time.Now() + defer telemetry.ModuleMeasureSince(types.ModuleName, executionStart, "handle_execution_for_contract_ms") + contractAddr := contract.ContractAddr + + // Call contract hooks so that contracts can do internal bookkeeping + if err := CallPreExecutionHooks(ctx, sdkCtx, contractAddr, dexkeeper, registeredPairs, tracer); err != nil { + return []*types.SettlementEntry{}, err + } + settlements := ExecutePairsInParallel(sdkCtx, contractAddr, dexkeeper, registeredPairs, orderBooks) + defer EmitSettlementMetrics(settlements) + + return settlements, nil +} + +// Emit metrics for settlements +func EmitSettlementMetrics(settlements []*types.SettlementEntry) { + if len(settlements) > 0 { + telemetry.ModuleSetGauge( + types.ModuleName, + float32(len(settlements)), + "num_settlements", + ) + for _, s := range settlements { + telemetry.IncrCounter( + 1, + "num_settlements_order_type_"+s.GetOrderType(), + ) + telemetry.IncrCounter( + 1, + "num_settlements_position_direction"+s.GetPositionDirection(), + ) + telemetry.IncrCounter( + 1, + "num_settlements_asset_denom_"+s.GetAssetDenom(), + ) + telemetry.IncrCounter( + 1, + "num_settlements_price_denom_"+s.GetPriceDenom(), + ) + } + } +} diff --git a/x/dex/contract/execution_test.go b/x/dex/contract/execution_test.go new file mode 100644 index 000000000..fea46b35f --- /dev/null +++ b/x/dex/contract/execution_test.go @@ -0,0 +1,373 @@ +package contract_test + +import ( + "testing" + "time" + + "github.com/sei-protocol/sei-chain/utils/datastructures" + dexutil "github.com/sei-protocol/sei-chain/x/dex/utils" + + 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" + keeperutil "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TEST_PAIR() types.Pair { + return types.Pair{ + PriceDenom: "usdc", + AssetDenom: "atom", + } +} + +const ( + TEST_ACCOUNT = "test_account" + TEST_CONTRACT = "test" + TestTimestamp uint64 = 10000 + TestHeight uint64 = 1 +) + +func TestExecutePair(t *testing.T) { + pair := types.Pair{ + PriceDenom: "USDC", + AssetDenom: "ATOM", + } + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(98), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(98), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.LongBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "def", + Quantity: sdk.NewDec(3), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, l := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, keepertest.TestContract, l) + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(101), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(101), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 7, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.ShortBook{ + Price: sdk.NewDec(115), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(115), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 8, + Account: "def", + Quantity: sdk.NewDec(3), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, s := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, keepertest.TestContract, s) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress(keepertest.TestContract), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + + settlements := contract.ExecutePair( + ctx, + TEST_CONTRACT, + pair, + dexkeeper, + orderbook, + ) + require.Equal(t, len(settlements), 0) + + // add Market orders to the orderbook + dexutil.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), pair).Add( + &types.Order{ + Id: 1, + Account: TEST_ACCOUNT, + ContractAddr: TEST_CONTRACT, + Price: sdk.MustNewDecFromStr("97"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutil.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), pair).Add( + &types.Order{ + Id: 2, + Account: TEST_ACCOUNT, + ContractAddr: TEST_CONTRACT, + Price: sdk.MustNewDecFromStr("100"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutil.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), pair).Add( + &types.Order{ + Id: 3, + Account: TEST_ACCOUNT, + ContractAddr: TEST_CONTRACT, + Price: sdk.MustNewDecFromStr("200"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_MARKET, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + + settlements = contract.ExecutePair( + ctx, + TEST_CONTRACT, + pair, + dexkeeper, + orderbook, + ) + + require.Equal(t, 2, len(settlements)) + require.Equal(t, uint64(7), settlements[0].OrderId) + require.Equal(t, uint64(3), settlements[1].OrderId) + + // get match results + matches, cancels := contract.GetMatchResults( + ctx, + TEST_CONTRACT, + pair, + ) + require.Equal(t, 3, len(matches)) + require.Equal(t, 0, len(cancels)) +} + +func TestExecutePairInParallel(t *testing.T) { + pair := types.Pair{ + PriceDenom: "USDC", + AssetDenom: "ATOM", + } + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(98), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(98), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.LongBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "def", + Quantity: sdk.NewDec(3), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, l := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, TEST_CONTRACT, l) + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(101), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(101), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 7, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.ShortBook{ + Price: sdk.NewDec(115), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(115), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 8, + Account: "def", + Quantity: sdk.NewDec(3), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, s := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, TEST_CONTRACT, s) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress(TEST_CONTRACT), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + + // execute in parallel simple path + orderbooks := datastructures.NewTypedSyncMap[types.PairString, *types.OrderBook]() + orderbooks.Store(types.GetPairString(&pair), orderbook) + settlements := contract.ExecutePairsInParallel( + ctx, + TEST_CONTRACT, + dexkeeper, + []types.Pair{pair}, + orderbooks, + ) + + require.Equal(t, len(settlements), 0) + + // add Market orders to the orderbook + dexutil.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), pair).Add( + &types.Order{ + Id: 1, + Account: TEST_ACCOUNT, + ContractAddr: TEST_CONTRACT, + Price: sdk.MustNewDecFromStr("97"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutil.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), pair).Add( + &types.Order{ + Id: 2, + Account: TEST_ACCOUNT, + ContractAddr: TEST_CONTRACT, + Price: sdk.MustNewDecFromStr("100"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutil.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), pair).Add( + &types.Order{ + Id: 3, + Account: TEST_ACCOUNT, + ContractAddr: TEST_CONTRACT, + Price: sdk.MustNewDecFromStr("200"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_MARKET, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutil.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(TEST_CONTRACT), pair).Add( + &types.Order{ + Id: 11, + Account: TEST_ACCOUNT, + ContractAddr: TEST_CONTRACT, + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_MARKET, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + + settlements = contract.ExecutePairsInParallel( + ctx, + TEST_CONTRACT, + dexkeeper, + []types.Pair{pair}, + orderbooks, + ) + + require.Equal(t, 2, len(settlements)) + require.Equal(t, uint64(7), settlements[0].OrderId) + require.Equal(t, uint64(3), settlements[1].OrderId) +} + +func TestGetOrderIDToSettledQuantities(t *testing.T) { + settlements := []*types.SettlementEntry{ + { + OrderId: 1, + Quantity: sdk.MustNewDecFromStr("100"), + }, + { + OrderId: 2, + Quantity: sdk.MustNewDecFromStr("200"), + }, + } + + idMapping := contract.GetOrderIDToSettledQuantities(settlements) + + require.Equal(t, 2, len(idMapping)) + require.Equal(t, sdk.MustNewDecFromStr("100"), idMapping[1]) + require.Equal(t, sdk.MustNewDecFromStr("200"), idMapping[2]) +} + +func TestEmitSettlementMetrics(t *testing.T) { + settlements := []*types.SettlementEntry{ + { + OrderId: 1, + Quantity: sdk.MustNewDecFromStr("100"), + }, + { + OrderId: 2, + Quantity: sdk.MustNewDecFromStr("200"), + }, + } + + require.NotPanics(t, func() { contract.EmitSettlementMetrics(settlements) }) +} diff --git a/x/dex/contract/market_order.go b/x/dex/contract/market_order.go new file mode 100644 index 000000000..3901f83e8 --- /dev/null +++ b/x/dex/contract/market_order.go @@ -0,0 +1,68 @@ +package contract + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + dexkeeperabci "github.com/sei-protocol/sei-chain/x/dex/keeper/abci" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "go.opentelemetry.io/otel/attribute" + otrace "go.opentelemetry.io/otel/trace" +) + +func PrepareCancelUnfulfilledMarketOrders( + ctx sdk.Context, + typedContractAddr types.ContractAddress, + pair types.Pair, + orderIDToSettledQuantities map[uint64]sdk.Dec, +) { + dexutils.GetMemState(ctx.Context()).ClearCancellationForPair(ctx, typedContractAddr, pair) + for _, marketOrderID := range getUnfulfilledPlacedMarketOrderIds(ctx, typedContractAddr, pair, orderIDToSettledQuantities) { + dexutils.GetMemState(ctx.Context()).GetBlockCancels(ctx, typedContractAddr, pair).Add(&types.Cancellation{ + Id: marketOrderID, + Initiator: types.CancellationInitiator_USER, + }) + } +} + +func getUnfulfilledPlacedMarketOrderIds( + ctx sdk.Context, + typedContractAddr types.ContractAddress, + pair types.Pair, + orderIDToSettledQuantities map[uint64]sdk.Dec, +) []uint64 { + res := []uint64{} + for _, order := range dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, typedContractAddr, pair).Get() { + if order.Status == types.OrderStatus_FAILED_TO_PLACE { + continue + } + if order.OrderType == types.OrderType_MARKET || order.OrderType == types.OrderType_FOKMARKET { + if settledQuantity, ok := orderIDToSettledQuantities[order.Id]; !ok || settledQuantity.LT(order.Quantity) { + res = append(res, order.Id) + } + } else if order.OrderType == types.OrderType_FOKMARKETBYVALUE { + // cancel market order by nominal if zero quantity is executed + if _, ok := orderIDToSettledQuantities[order.Id]; !ok { + res = append(res, order.Id) + } + } + } + return res +} + +func CancelUnfulfilledMarketOrders( + ctx context.Context, + sdkCtx sdk.Context, + contractAddr string, + dexkeeper *keeper.Keeper, + registeredPairs []types.Pair, + tracer *otrace.Tracer, +) error { + spanCtx, span := (*tracer).Start(ctx, "CancelUnfulfilledMarketOrders") + span.SetAttributes(attribute.String("contract", contractAddr)) + defer span.End() + abciWrapper := dexkeeperabci.KeeperWrapper{Keeper: dexkeeper} + return abciWrapper.HandleEBCancelOrders(spanCtx, sdkCtx, tracer, contractAddr, registeredPairs) +} diff --git a/x/dex/contract/runner.go b/x/dex/contract/runner.go new file mode 100644 index 000000000..6e3797f3f --- /dev/null +++ b/x/dex/contract/runner.go @@ -0,0 +1,178 @@ +package contract + +import ( + "fmt" + "sync/atomic" + "time" + + "github.com/cosmos/cosmos-sdk/telemetry" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/utils/datastructures" + "github.com/sei-protocol/sei-chain/utils/logging" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +const LogAfter = 10 * time.Second + +type ParallelRunner struct { + runnable func(contract types.ContractInfoV2) + + contractAddrToInfo *datastructures.TypedSyncMap[types.ContractAddress, *types.ContractInfoV2] + readyContracts *datastructures.TypedSyncMap[types.ContractAddress, struct{}] + readyCnt int64 + inProgressCnt int64 + someContractFinished chan struct{} + done chan struct{} + sdkCtx sdk.Context +} + +func NewParallelRunner(runnable func(contract types.ContractInfoV2), contracts []types.ContractInfoV2, ctx sdk.Context) ParallelRunner { + contractAddrToInfo := datastructures.NewTypedSyncMap[types.ContractAddress, *types.ContractInfoV2]() + contractsFrontier := datastructures.NewTypedSyncMap[types.ContractAddress, struct{}]() + for _, contract := range contracts { + // runner will mutate ContractInfo fields + copyContract := contract + typedContractAddr := types.ContractAddress(contract.ContractAddr) + contractAddrToInfo.Store(typedContractAddr, ©Contract) + if copyContract.NumIncomingDependencies == 0 { + contractsFrontier.Store(typedContractAddr, struct{}{}) + } + } + return ParallelRunner{ + runnable: runnable, + contractAddrToInfo: contractAddrToInfo, + readyContracts: contractsFrontier, + readyCnt: int64(contractsFrontier.Len()), + inProgressCnt: 0, + someContractFinished: make(chan struct{}), + done: make(chan struct{}, 1), + sdkCtx: ctx, + } +} + +// We define "frontier contract" as a contract which: +// 1. Has not finished running yet, and +// 2. either: +// a. has no other contracts depending on it, or +// b. for which all contracts that depend on it have already finished. +// +// Consequently, the set of frontier contracts will mutate throughout the +// `Run` method, until all contracts finish their runs. +// The key principle here is that at any moment, we can have all frontier +// contracts running concurrently, since there must be no ancestral +// relationships among them due to the definition above. +// The simplest implementation would be: +// ``` +// while there is any contract left: +// +// run all frontier contracts concurrently +// wait for all runs to finish +// update the frontier set +// +// ``` +// We can illustrate why this implementation is not optimal with the following +// example: +// +// Suppose we have four contracts, where A depends on B, and C depends on +// D. The run for A, B, C, D takes 5s, 5s, 8s, 2s, respectively. +// With the implementation above, the first iteration would take 8s since +// it runs A and C, and the second iteration would take 5s since it runs +// B and D. However C doesn't actually need to wait for B to finish, and +// if C runs immediately after A finishes, the whole process would take +// max(5 + 5, 8 + 2) = 10s, which is 3s faster than the implementation +// above. +// +// So we can optimize the implementation to be: +// ``` +// while there is any contract left: +// +// run all frontier contracts concurrently +// wait for any existing run (could be from previous iteration) to finish +// update the frontier set +// +// ``` +// With the example above, the whole process would take 3 iterations: +// Iter 1 (A, C run): 5s since it finishes when A finishes +// Iter 2 (B run): 3s since it finishes when C finishes +// Iter 3 (D run): 2s since it finishes when B, D finish +// +// The following `Run` method implements the pseudocode above. +func (r *ParallelRunner) Run() { + if atomic.LoadInt64(&r.inProgressCnt) == 0 && atomic.LoadInt64(&r.readyCnt) == 0 { + return + } + // The ordering of the two conditions below matters, since readyCnt + // is updated before inProgressCnt. + for atomic.LoadInt64(&r.inProgressCnt) > 0 || atomic.LoadInt64(&r.readyCnt) > 0 { + // r.readyContracts represent all frontier contracts that have + // not started running yet. + r.readyContracts.Range(func(key types.ContractAddress, _ struct{}) bool { + atomic.AddInt64(&r.inProgressCnt, 1) + go r.wrapRunnable(key) + // Since the frontier contract has started running, we need + // to remove it from r.readyContracts so that it won't + // double-run. + r.readyContracts.Delete(key) + // The reason we use a separate readyCnt is because `sync.Map` + // doesn't provide an atomic way to get its length. + atomic.AddInt64(&r.readyCnt, -1) + return true + }) + // This corresponds to the "wait for any existing run (could be + // from previous iteration) to finish" part in the pseudocode above. + _, err := logging.LogIfNotDoneAfter(r.sdkCtx.Logger(), func() (struct{}, error) { + <-r.someContractFinished + return struct{}{}, nil + }, LogAfter, "dex_parallel_runner_wait") + if err != nil { + // this should never happen + panic(err) + } + } + + // make sure there is no orphaned goroutine blocked on channel send + r.done <- struct{}{} +} + +func (r *ParallelRunner) wrapRunnable(contractAddr types.ContractAddress) { + defer func() { + if err := recover(); err != nil { + telemetry.IncrCounter(1, "recovered_panics") + r.sdkCtx.Logger().Error(fmt.Sprintf("panic in parallel runner recovered: %s", err)) + } + + atomic.AddInt64(&r.inProgressCnt, -1) // this has to happen after any potential increment to readyCnt + select { + case r.someContractFinished <- struct{}{}: + case <-r.done: + // make sure other goroutines can also receive from 'done' + r.done <- struct{}{} + } + }() + + contractInfo, _ := r.contractAddrToInfo.Load(contractAddr) + r.runnable(*contractInfo) + + // Check if there is any contract that should be promoted to the frontier set. + if contractInfo.Dependencies != nil { + for _, dependency := range contractInfo.Dependencies { + dependentContract := dependency.Dependency + typedDependentContract := types.ContractAddress(dependentContract) + dependentInfo, ok := r.contractAddrToInfo.Load(typedDependentContract) + if !ok { + // If we cannot find the dependency in the contract address info, then it's not a valid contract in this round + r.sdkCtx.Logger().Error(fmt.Sprintf("Couldn't find dependency %s of contract %s in the contract address info", contractInfo.ContractAddr, dependentContract)) + continue + } + // It's okay to mutate ContractInfo here since it's a copy made in the runner's + // constructor. + newNumIncomingPaths := atomic.AddInt64(&dependentInfo.NumIncomingDependencies, -1) + // This corresponds to the "for which all contracts that depend on it have + // already finished." definition for frontier contract. + if newNumIncomingPaths == 0 { + r.readyContracts.Store(typedDependentContract, struct{}{}) + atomic.AddInt64(&r.readyCnt, 1) + } + } + } +} diff --git a/x/dex/contract/runner_test.go b/x/dex/contract/runner_test.go new file mode 100644 index 000000000..bf7e8c1d7 --- /dev/null +++ b/x/dex/contract/runner_test.go @@ -0,0 +1,141 @@ +package contract_test + +import ( + "sync" + "sync/atomic" + "testing" + "time" + + 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/types" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +var ( + counter int64 = 0 + dependencyCheck = sync.Map{} + testApp = keepertest.TestApp() + sdkCtx = testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) +) + +func noopRunnable(_ types.ContractInfoV2) { + atomic.AddInt64(&counter, 1) +} + +func idleRunnable(_ types.ContractInfoV2) { + time.Sleep(5 * time.Second) + atomic.AddInt64(&counter, 1) +} + +func panicRunnable(_ types.ContractInfoV2) { + panic("") +} + +func dependencyCheckRunnable(contractInfo types.ContractInfoV2) { + if contractInfo.ContractAddr == "C" { + _, hasA := dependencyCheck.Load("A") + _, hasB := dependencyCheck.Load("B") + if !hasA || !hasB { + return + } + } + dependencyCheck.Store(contractInfo.ContractAddr, struct{}{}) +} + +func TestRunnerSingleContract(t *testing.T) { + counter = 0 + contractInfo := types.ContractInfoV2{ + ContractAddr: "A", + NumIncomingDependencies: 0, + } + runner := contract.NewParallelRunner(noopRunnable, []types.ContractInfoV2{contractInfo}, sdkCtx) + runner.Run() + require.Equal(t, int64(1), counter) +} + +func TestRunnerParallelContract(t *testing.T) { + counter = 0 + contractInfoA := types.ContractInfoV2{ + ContractAddr: "A", + NumIncomingDependencies: 0, + } + contractInfoB := types.ContractInfoV2{ + ContractAddr: "B", + NumIncomingDependencies: 0, + } + runner := contract.NewParallelRunner(idleRunnable, []types.ContractInfoV2{contractInfoA, contractInfoB}, sdkCtx) + start := time.Now() + runner.Run() + end := time.Now() + duration := end.Sub(start) + require.Equal(t, int64(2), counter) + require.True(t, duration.Seconds() < 10) // would not be flaky unless it's running on really slow hardware +} + +func TestRunnerParallelContractWithDependency(t *testing.T) { + counter = 0 + contractInfoA := types.ContractInfoV2{ + ContractAddr: "A", + NumIncomingDependencies: 0, + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "C", + }, + }, + } + contractInfoB := types.ContractInfoV2{ + ContractAddr: "B", + NumIncomingDependencies: 0, + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "C", + }, + }, + } + contractInfoC := types.ContractInfoV2{ + ContractAddr: "C", + NumIncomingDependencies: 2, + } + runner := contract.NewParallelRunner(dependencyCheckRunnable, []types.ContractInfoV2{contractInfoC, contractInfoB, contractInfoA}, sdkCtx) + runner.Run() + _, hasC := dependencyCheck.Load("C") + require.True(t, hasC) +} + +func TestRunnerParallelContractWithInvalidDependency(t *testing.T) { + dependencyCheck = sync.Map{} + counter = 0 + contractInfoA := types.ContractInfoV2{ + ContractAddr: "A", + NumIncomingDependencies: 0, + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "C", + }, + }, + } + contractInfoB := types.ContractInfoV2{ + ContractAddr: "B", + NumIncomingDependencies: 0, + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "C", + }, + }, + } + runner := contract.NewParallelRunner(dependencyCheckRunnable, []types.ContractInfoV2{contractInfoB, contractInfoA}, sdkCtx) + runner.Run() + _, hasC := dependencyCheck.Load("C") + require.False(t, hasC) +} + +func TestRunnerPanicContract(t *testing.T) { + contractInfo := types.ContractInfoV2{ + ContractAddr: "A", + NumIncomingDependencies: 0, + } + runner := contract.NewParallelRunner(panicRunnable, []types.ContractInfoV2{contractInfo}, sdkCtx) + require.NotPanics(t, runner.Run) +} diff --git a/x/dex/contract/settlement.go b/x/dex/contract/settlement.go new file mode 100644 index 000000000..e840388e4 --- /dev/null +++ b/x/dex/contract/settlement.go @@ -0,0 +1,39 @@ +package contract + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + dexkeeperutils "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func HandleSettlements( + ctx sdk.Context, + contractAddr string, + dexkeeper *keeper.Keeper, + settlements []*types.SettlementEntry, +) error { + return callSettlementHook(ctx, contractAddr, dexkeeper, settlements) +} + +func callSettlementHook( + ctx sdk.Context, + contractAddr string, + dexkeeper *keeper.Keeper, + settlementEntries []*types.SettlementEntry, +) error { + if len(settlementEntries) == 0 { + return nil + } + _, currentEpoch := dexkeeper.IsNewEpoch(ctx) + nativeSettlementMsg := types.SudoSettlementMsg{ + Settlement: types.Settlements{ + Epoch: int64(currentEpoch), + Entries: settlementEntries, + }, + } + if _, err := dexkeeperutils.CallContractSudo(ctx, dexkeeper, contractAddr, nativeSettlementMsg, dexkeeper.GetSettlementGasAllowance(ctx, len(settlementEntries))); err != nil { + return err + } + return nil +} diff --git a/x/dex/contract/whitelist.go b/x/dex/contract/whitelist.go new file mode 100644 index 000000000..d6ab9a8a9 --- /dev/null +++ b/x/dex/contract/whitelist.go @@ -0,0 +1,91 @@ +package contract + +import ( + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/utils" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +var DexWhitelistedKeys = []string{ + types.LongBookKey, + types.ShortBookKey, + types.OrderKey, + types.AccountActiveOrdersKey, + types.CancelKey, + types.TwapKey, + types.PriceKey, + types.NextOrderIDKey, + types.MatchResultKey, + types.LongOrderCountKey, + types.ShortOrderCountKey, + keeper.ContractPrefixKey, +} + +var DexMemWhitelistedKeys = []string{ + types.MemOrderKey, + types.MemDepositKey, + types.MemCancelKey, +} + +var WasmWhitelistedKeys = []string{ + string(wasmtypes.ContractStorePrefix), +} + +func GetWhitelistMap(contractAddr string) map[string][]string { + res := map[string][]string{} + res[storetypes.NewKVStoreKey(types.StoreKey).Name()] = GetDexWhitelistedPrefixes(contractAddr) + res[storetypes.NewKVStoreKey(wasmtypes.StoreKey).Name()] = GetWasmWhitelistedPrefixes(contractAddr) + res[storetypes.NewKVStoreKey(types.MemStoreKey).Name()] = GetDexMemWhitelistedPrefixes(contractAddr) + return res +} + +func GetPerPairWhitelistMap(contractAddr string, pair types.Pair) map[string][]string { + res := map[string][]string{} + res[storetypes.NewKVStoreKey(types.StoreKey).Name()] = GetDexPerPairWhitelistedPrefixes(contractAddr, pair) + res[storetypes.NewKVStoreKey(types.MemStoreKey).Name()] = GetDexMemPerPairWhitelistedPrefixes(contractAddr, pair) + return res +} + +func GetDexWhitelistedPrefixes(contractAddr string) []string { + return utils.Map(DexWhitelistedKeys, func(key string) string { + return string(append( + types.KeyPrefix(key), types.AddressKeyPrefix(contractAddr)..., + )) + }) +} + +func GetDexMemWhitelistedPrefixes(contractAddr string) []string { + return utils.Map(DexMemWhitelistedKeys, func(key string) string { + return string(append( + types.KeyPrefix(key), types.AddressKeyPrefix(contractAddr)..., + )) + }) +} + +func GetWasmWhitelistedPrefixes(contractAddr string) []string { + addr, _ := sdk.AccAddressFromBech32(contractAddr) + return utils.Map(WasmWhitelistedKeys, func(key string) string { + return string(append( + []byte(key), addr..., + )) + }) +} + +func GetDexPerPairWhitelistedPrefixes(contractAddr string, pair types.Pair) []string { + return utils.Map(DexWhitelistedKeys, func(key string) string { + return string(append(append( + types.KeyPrefix(key), types.AddressKeyPrefix(contractAddr)..., + ), types.PairPrefix(pair.PriceDenom, pair.AssetDenom)...)) + }) +} + +func GetDexMemPerPairWhitelistedPrefixes(contractAddr string, pair types.Pair) []string { + return utils.Map(DexMemWhitelistedKeys, func(key string) string { + return string(append(append( + types.KeyPrefix(key), types.AddressKeyPrefix(contractAddr)..., + ), types.PairPrefix(pair.PriceDenom, pair.AssetDenom)...)) + }) +} diff --git a/x/dex/contract/whitelist_test.go b/x/dex/contract/whitelist_test.go new file mode 100644 index 000000000..79fb70174 --- /dev/null +++ b/x/dex/contract/whitelist_test.go @@ -0,0 +1,28 @@ +package contract_test + +import ( + "encoding/hex" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/contract" + "github.com/stretchr/testify/require" +) + +func TestGetWasmPrefixes(t *testing.T) { + wasmWhitelistedPrefixes := contract.GetWasmWhitelistedPrefixes("sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m") + + wasmPrefixBytes, _ := hex.DecodeString("03" + "ade4a5f5803a439835c636395a8d648dee57b2fc90d98dc17fa887159b69638b") + require.Equal(t, []byte(wasmWhitelistedPrefixes[0]), wasmPrefixBytes) +} + +func TestGetDexPrefixes(t *testing.T) { + dexWhitelistedPrefixes := contract.GetDexWhitelistedPrefixes("sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m") + addr, _ := sdk.AccAddressFromBech32("sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m") + + for i, dexKeys := range contract.DexWhitelistedKeys { + len := []byte{byte(32)} + prefix := append(append([]byte(dexKeys), len...), addr...) + require.Equal(t, string(prefix), dexWhitelistedPrefixes[i]) + } +} diff --git a/x/dex/example/add-asset-metadata-proposal.json b/x/dex/example/add-asset-metadata-proposal.json new file mode 100644 index 000000000..80365fad2 --- /dev/null +++ b/x/dex/example/add-asset-metadata-proposal.json @@ -0,0 +1,55 @@ +{ + "title": "Add usdc asset to asset list", + "description": "gov proposal to update asset list", + "asset_list": [ + { + "ibc_info": { + "source_channel": "channel-1", + "dst_channel": "channel-2", + "source_denom": "uusdc", + "source_chain_id": "axelar" + }, + "type_asset": "erc20", + "metadata": { + "description": "Circle's stablecoin on Axelar", + "denom_units": [ + { + "denom": "ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858", + "exponent": 0, + "aliases": ["uusdc"] + }, + { + "denom": "axlusdc", + "exponent": 6 + } + ], + "base": "ibc/D189335C6E4A68B513C10AB227BF1C1D38C746766278BA3EEB4FB14124F1D858", + "name": "USD Coin", + "display": "axlusdc", + "symbol": "USDC" + } + }, + { + "type_asset": "native", + "metadata": { + "description": "Native token of Sei Network", + "denom_units": [ + { + "denom": "usei", + "exponent": 0, + "aliases": ["usei"] + }, + { + "denom": "sei", + "exponent": 6 + } + ], + "base": "SEI", + "name": "sei", + "display": "usei", + "symbol": "SEI" + } + } + ], + "deposit": "500000usei" +} diff --git a/x/dex/example/register-pair-tx.json b/x/dex/example/register-pair-tx.json new file mode 100644 index 000000000..61d285599 --- /dev/null +++ b/x/dex/example/register-pair-tx.json @@ -0,0 +1,15 @@ +{ + "batch_contract_pair": [ + { + "contract_addr": "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m", + "pairs": [ + { + "price_denom": "usei", + "asset_denom": "uatom", + "price_tick_size": "0.0000001", + "quantity_tick_size": "0.0000001" + } + ] + } + ] +} \ No newline at end of file diff --git a/x/dex/example/update-tick-size-tx.json b/x/dex/example/update-tick-size-tx.json new file mode 100644 index 000000000..746e819d2 --- /dev/null +++ b/x/dex/example/update-tick-size-tx.json @@ -0,0 +1,12 @@ +{ + "tick_size_list": [ + { + "pair": { + "price_denom": "uatom", + "asset_denom": "usei" + }, + "tick_size": "1.5", + "contract_addr": "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m" + } + ] +} \ No newline at end of file diff --git a/x/dex/exchange/cancel_order.go b/x/dex/exchange/cancel_order.go new file mode 100644 index 000000000..c50d6be96 --- /dev/null +++ b/x/dex/exchange/cancel_order.go @@ -0,0 +1,53 @@ +package exchange + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func CancelOrders( + ctx sdk.Context, keeper *keeper.Keeper, contract types.ContractAddress, pair types.Pair, + cancels []*types.Cancellation, +) { + for _, cancel := range cancels { + cancelOrder(ctx, keeper, cancel, contract, pair) + } +} + +func cancelOrder(ctx sdk.Context, keeper *keeper.Keeper, cancellation *types.Cancellation, contract types.ContractAddress, pair types.Pair) { + getter, setter, deleter := keeper.GetLongOrderBookEntryByPrice, keeper.SetLongOrderBookEntry, keeper.RemoveLongBookByPrice + if cancellation.PositionDirection == types.PositionDirection_SHORT { + getter, setter, deleter = keeper.GetShortOrderBookEntryByPrice, keeper.SetShortOrderBookEntry, keeper.RemoveShortBookByPrice + } + entry, found := getter(ctx, string(contract), cancellation.Price, pair.PriceDenom, pair.AssetDenom) + if !found { + return + } + newEntry := *entry.GetOrderEntry() + newAllocations := []*types.Allocation{} + newQuantity := sdk.ZeroDec() + for _, allocation := range newEntry.Allocations { + if allocation.OrderId != cancellation.Id { + newAllocations = append(newAllocations, allocation) + newQuantity = newQuantity.Add(allocation.Quantity) + } + } + numAllocationsRemoved := len(newEntry.Allocations) - len(newAllocations) + if numAllocationsRemoved > 0 { + err := keeper.DecreaseOrderCount(ctx, string(contract), pair.PriceDenom, pair.AssetDenom, cancellation.PositionDirection, entry.GetPrice(), uint64(numAllocationsRemoved)) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error decreasing order count: %s", err)) + } + } + if newQuantity.IsZero() { + deleter(ctx, string(contract), entry.GetPrice(), pair.PriceDenom, pair.AssetDenom) + return + } + newEntry.Quantity = newQuantity + newEntry.Allocations = newAllocations + entry.SetEntry(&newEntry) + setter(ctx, string(contract), entry) +} diff --git a/x/dex/exchange/cancel_order_test.go b/x/dex/exchange/cancel_order_test.go new file mode 100644 index 000000000..43701f9f6 --- /dev/null +++ b/x/dex/exchange/cancel_order_test.go @@ -0,0 +1,105 @@ +package exchange_test + +import ( + "testing" + "time" + + 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/assert" + "github.com/stretchr/testify/require" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" +) + +func TestCancelOrder(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(98), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(98), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, s := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", s) + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(101), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(101), + Quantity: sdk.NewDec(12), + Allocations: []*types.Allocation{{ + OrderId: 7, + Account: "abc", + Quantity: sdk.NewDec(5), + }, { + OrderId: 8, + Account: "def", + Quantity: sdk.NewDec(7), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, s := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", s) + } + + // Allocations before cancellation contains id 5 + assert.Equal(t, (*longBook[0].GetOrderEntry()).Allocations, []*types.Allocation{{ + OrderId: 5, + Account: "abc", + Quantity: sdk.NewDec(5), + }}) + + // Cancel Long Id 5 + cancellation := types.Cancellation{ + Id: 5, + Creator: "abc", + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + PositionDirection: types.PositionDirection_LONG, + Price: sdk.NewDec(98), + } + // Cancel short Id 7 + cancellationShort := types.Cancellation{ + Id: 7, + Creator: "abc", + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + PositionDirection: types.PositionDirection_SHORT, + Price: sdk.NewDec(101), + } + cancels := []*types.Cancellation{&cancellation, &cancellationShort} + exchange.CancelOrders(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}, + cancels, + ) + + // No allocations after cancellation + _, found := dexkeeper.GetLongBookByPrice(ctx, "test", sdk.NewDec(98), "USDC", "ATOM") + require.False(t, found) + entry, found := dexkeeper.GetShortBookByPrice(ctx, "test", sdk.NewDec(101), "USDC", "ATOM") + require.True(t, found) + require.Equal(t, sdk.NewDec(7), entry.GetOrderEntry().Quantity) + require.Equal(t, []*types.Allocation{{ + OrderId: 8, + Account: "def", + Quantity: sdk.NewDec(7), + }}, entry.GetOrderEntry().Allocations) +} diff --git a/x/dex/exchange/helpers.go b/x/dex/exchange/helpers.go new file mode 100644 index 000000000..eeb39a8ee --- /dev/null +++ b/x/dex/exchange/helpers.go @@ -0,0 +1,24 @@ +package exchange + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +type ExecutionOutcome struct { + TotalNotional sdk.Dec + TotalQuantity sdk.Dec + Settlements []*types.SettlementEntry + MinPrice sdk.Dec // deprecate? + MaxPrice sdk.Dec // deprecate? +} + +func (o *ExecutionOutcome) Merge(other *ExecutionOutcome) ExecutionOutcome { + return 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/helpers_test.go b/x/dex/exchange/helpers_test.go new file mode 100644 index 000000000..3b271c389 --- /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/limit_order.go b/x/dex/exchange/limit_order.go new file mode 100644 index 000000000..65f249d02 --- /dev/null +++ b/x/dex/exchange/limit_order.go @@ -0,0 +1,103 @@ +package exchange + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func MatchLimitOrders( + ctx sdk.Context, + orderbook *types.OrderBook, +) ExecutionOutcome { + settlements := []*types.SettlementEntry{} + totalExecuted, totalPrice := sdk.ZeroDec(), sdk.ZeroDec() + minPrice, maxPrice := sdk.OneDec().Neg(), sdk.OneDec().Neg() + + for longEntry, shortEntry := orderbook.Longs.Next(ctx), orderbook.Shorts.Next(ctx); longEntry != nil && shortEntry != nil && longEntry.GetPrice().GTE(shortEntry.GetPrice()); longEntry, shortEntry = orderbook.Longs.Next(ctx), orderbook.Shorts.Next(ctx) { + var executed sdk.Dec + if longEntry.GetOrderEntry().Quantity.LT(shortEntry.GetOrderEntry().Quantity) { + executed = longEntry.GetOrderEntry().Quantity + } else { + executed = shortEntry.GetOrderEntry().Quantity + } + totalExecuted = totalExecuted.Add(executed).Add(executed) + totalPrice = totalPrice.Add( + executed.Mul( + longEntry.GetPrice().Add(shortEntry.GetPrice()), + ), + ) + if minPrice.IsNegative() || minPrice.GT(shortEntry.GetPrice()) { + minPrice = shortEntry.GetPrice() + } + maxPrice = sdk.MaxDec(maxPrice, longEntry.GetPrice()) + + newSettlements := SettleFromBook( + ctx, + orderbook, + executed, + longEntry.GetPrice(), + shortEntry.GetPrice(), + ) + settlements = append(settlements, newSettlements...) + } + + orderbook.Longs.Flush(ctx) + orderbook.Shorts.Flush(ctx) + return ExecutionOutcome{ + TotalNotional: totalPrice, + TotalQuantity: totalExecuted, + Settlements: settlements, + MinPrice: minPrice, + MaxPrice: maxPrice, + } +} + +func addOrderToOrderBookEntry( + ctx sdk.Context, keeper *keeper.Keeper, + order *types.Order, +) { + getter, setter := keeper.GetLongOrderBookEntryByPrice, keeper.SetLongOrderBookEntry + if order.PositionDirection == types.PositionDirection_SHORT { + getter, setter = keeper.GetShortOrderBookEntryByPrice, keeper.SetShortOrderBookEntry + } + entry, exist := getter(ctx, order.ContractAddr, order.Price, order.PriceDenom, order.AssetDenom) + orderEntry := entry.GetOrderEntry() + if !exist { + orderEntry = &types.OrderEntry{ + Price: order.Price, + PriceDenom: order.PriceDenom, + AssetDenom: order.AssetDenom, + Quantity: sdk.ZeroDec(), + } + } + orderEntry.Quantity = orderEntry.Quantity.Add(order.Quantity) + orderEntry.Allocations = append(orderEntry.Allocations, &types.Allocation{ + OrderId: order.Id, + Quantity: order.Quantity, + Account: order.Account, + }) + entry.SetPrice(order.Price) + entry.SetEntry(orderEntry) + setter(ctx, order.ContractAddr, entry) + + err := keeper.IncreaseOrderCount(ctx, order.ContractAddr, order.PriceDenom, order.AssetDenom, order.PositionDirection, order.Price, 1) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error increasing order count: %s", err)) + } +} + +func AddOutstandingLimitOrdersToOrderbook( + ctx sdk.Context, keeper *keeper.Keeper, + limitBuys []*types.Order, + limitSells []*types.Order, +) { + for _, order := range limitBuys { + addOrderToOrderBookEntry(ctx, keeper, order) + } + for _, order := range limitSells { + addOrderToOrderBookEntry(ctx, keeper, order) + } +} diff --git a/x/dex/exchange/limit_order_fuzz_test.go b/x/dex/exchange/limit_order_fuzz_test.go new file mode 100644 index 000000000..3e14f3184 --- /dev/null +++ b/x/dex/exchange/limit_order_fuzz_test.go @@ -0,0 +1,55 @@ +package exchange_test + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/testutil/fuzzing" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + keeperutil "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +var TestFuzzLimitCtx = sdk.NewContext(nil, tmproto.Header{}, false, log.NewNopLogger()) +var TestFuzzLimitKeeper keeper.Keeper + +func FuzzMatchLimitOrders(f *testing.F) { + TestFuzzLimitCtx = TestFuzzLimitCtx.WithBlockHeight(1).WithBlockTime(time.Now()) + f.Fuzz(fuzzTargetMatchLimitOrders) +} + +func fuzzTargetMatchLimitOrders( + t *testing.T, + buyPrices []byte, + sellPrices []byte, + buyQuantities []byte, + sellQuantities []byte, + buyEntryWeights []byte, + sellEntryWeights []byte, + buyAccountIndices []byte, + sellAccountIndices []byte, + buyAllocationWeights []byte, + sellAllocationWeights []byte, +) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) + buyEntries := fuzzing.GetOrderBookEntries(true, keepertest.TestPriceDenom, keepertest.TestAssetDenom, buyEntryWeights, buyAccountIndices, buyAllocationWeights) + for _, entry := range buyEntries { + dexkeeper.SetLongOrderBookEntry(ctx, keepertest.TestContract, entry) + } + sellEntries := fuzzing.GetOrderBookEntries(false, keepertest.TestPriceDenom, keepertest.TestAssetDenom, sellEntryWeights, sellAccountIndices, sellAllocationWeights) + for _, entry := range sellEntries { + dexkeeper.SetShortOrderBookEntry(ctx, keepertest.TestContract, entry) + } + buyOrders := fuzzing.GetPlacedOrders(types.PositionDirection_LONG, types.OrderType_LIMIT, keepertest.TestPair, buyPrices, buyQuantities) + sellOrders := fuzzing.GetPlacedOrders(types.PositionDirection_SHORT, types.OrderType_LIMIT, keepertest.TestPair, sellPrices, sellQuantities) + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, buyOrders, sellOrders) + orderBook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress(keepertest.TestContract), types.Pair{PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}) + require.NotPanics(t, func() { exchange.MatchLimitOrders(ctx, orderBook) }) +} diff --git a/x/dex/exchange/limit_order_test.go b/x/dex/exchange/limit_order_test.go new file mode 100644 index 000000000..f904ab91c --- /dev/null +++ b/x/dex/exchange/limit_order_test.go @@ -0,0 +1,1165 @@ +package exchange_test + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + keeperutil "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/assert" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" +) + +func TEST_PAIR() types.Pair { + return types.Pair{ + PriceDenom: "usdc", + AssetDenom: "atom", + } +} + +func TestMatchSingleOrder(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + shortOrders := []*types.Order{ + { + Id: 2, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "def", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + longBook := []types.OrderBookEntry{} + shortBook := []types.OrderBookEntry{} + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, longOrders, shortOrders) + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + outcome := exchange.MatchLimitOrders( + ctx, orderbook, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + assert.Equal(t, totalPrice, sdk.NewDec(1000)) + assert.Equal(t, totalExecuted, sdk.NewDec(10)) + assert.Equal(t, outcome.MaxPrice, sdk.NewDec(100)) + assert.Equal(t, outcome.MinPrice, sdk.NewDec(100)) + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, len(longBook), 0) + assert.Equal(t, len(shortBook), 0) + assert.Equal(t, len(settlements), 2) + assert.Equal(t, *settlements[0], 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, + }) + assert.Equal(t, *settlements[1], 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, + }) +} + +func TestAddOrders(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "def", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + { + Id: 2, + Price: sdk.NewDec(95), + Quantity: sdk.NewDec(3), + Account: "def", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + shortOrders := []*types.Order{ + { + Id: 3, + Price: sdk.NewDec(105), + Quantity: sdk.NewDec(10), + Account: "ghi", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + { + Id: 4, + Price: sdk.NewDec(115), + Quantity: sdk.NewDec(2), + Account: "mno", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(98), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(98), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.LongBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "def", + Quantity: sdk.NewDec(3), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(101), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(101), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 7, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.ShortBook{ + Price: sdk.NewDec(115), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(115), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 8, + Account: "def", + Quantity: sdk.NewDec(3), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, longOrders, shortOrders) + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + outcome := exchange.MatchLimitOrders( + ctx, orderbook, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + assert.Equal(t, totalPrice, sdk.NewDec(0)) + assert.Equal(t, totalExecuted, sdk.NewDec(0)) + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, len(longBook), 3) + assert.Equal(t, longBook[0].GetPrice(), sdk.NewDec(95)) + assert.Equal(t, *longBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(95), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 2, + Account: "def", + Quantity: sdk.NewDec(3), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, longBook[1].GetPrice(), sdk.NewDec(98)) + assert.Equal(t, *longBook[1].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(98), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, longBook[2].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, *longBook[2].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(8), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "def", + Quantity: sdk.NewDec(3), + }, { + OrderId: 1, + Account: "def", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(shortBook), 3) + assert.Equal(t, shortBook[0].GetPrice(), sdk.NewDec(101)) + assert.Equal(t, *shortBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(101), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 7, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, shortBook[1].GetPrice(), sdk.NewDec(105)) + assert.Equal(t, *shortBook[1].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(105), + Quantity: sdk.NewDec(10), + Allocations: []*types.Allocation{{ + OrderId: 3, + Account: "ghi", + Quantity: sdk.NewDec(10), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, shortBook[2].GetPrice(), sdk.NewDec(115)) + assert.Equal(t, *shortBook[2].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(115), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 8, + Account: "def", + Quantity: sdk.NewDec(3), + }, { + OrderId: 4, + Account: "mno", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(settlements), 0) +} + +func TestMatchSingleOrderFromShortBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + shortOrders := []*types.Order{} + longBook := []types.OrderBookEntry{} + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 2, + Account: "def", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, longOrders, shortOrders) + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + outcome := exchange.MatchLimitOrders( + ctx, orderbook, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + assert.Equal(t, totalPrice, sdk.NewDec(1000)) + assert.Equal(t, totalExecuted, sdk.NewDec(10)) + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, len(longBook), 0) + assert.Equal(t, len(shortBook), 0) + assert.Equal(t, len(settlements), 2) + assert.Equal(t, *settlements[0], 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, + }) + assert.Equal(t, *settlements[1], 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, + }) +} + +func TestMatchSingleOrderFromLongBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{} + shortOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "def", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 2, + Account: "abc", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + shortBook := []types.OrderBookEntry{} + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, longOrders, shortOrders) + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + outcome := exchange.MatchLimitOrders( + ctx, orderbook, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + assert.Equal(t, totalPrice, sdk.NewDec(1000)) + assert.Equal(t, totalExecuted, sdk.NewDec(10)) + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, len(longBook), 0) + assert.Equal(t, len(shortBook), 0) + assert.Equal(t, len(settlements), 2) + assert.Equal(t, *settlements[0], 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: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], 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: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) +} + +func TestMatchSingleOrderFromMultipleShortBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + shortOrders := []*types.Order{} + longBook := []types.OrderBookEntry{} + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(90), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(90), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 2, + Account: "def", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(6), + Allocations: []*types.Allocation{{ + OrderId: 3, + Account: "def", + Quantity: sdk.NewDec(4), + }, { + OrderId: 4, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, longOrders, shortOrders) + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + outcome := exchange.MatchLimitOrders( + ctx, orderbook, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + assert.Equal(t, totalPrice, sdk.NewDec(980)) + assert.Equal(t, totalExecuted, sdk.NewDec(10)) + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, len(longBook), 0) + assert.Equal(t, len(shortBook), 1) + assert.Equal(t, shortBook[0].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, *shortBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 3, + Account: "def", + Quantity: sdk.NewDec(1), + }, { + OrderId: 4, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(settlements), 4) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(2), + ExecutionCostOrProceed: sdk.NewDec(95), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(2), + ExecutionCostOrProceed: sdk.NewDec(95), + ExpectedCostOrProceed: sdk.NewDec(90), + Account: "def", + OrderType: "Limit", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[2], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(3), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[3], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(3), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 3, + Timestamp: TestTimestamp, + Height: TestHeight, + }) +} + +func TestMatchSingleOrderFromMultipleLongBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{} + shortOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "def", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(6), + Allocations: []*types.Allocation{{ + OrderId: 2, + Account: "abc", + Quantity: sdk.NewDec(4), + }, { + OrderId: 3, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.LongBook{ + Price: sdk.NewDec(110), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(110), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 4, + Account: "abc", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + shortBook := []types.OrderBookEntry{} + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, longOrders, shortOrders) + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + outcome := exchange.MatchLimitOrders( + ctx, orderbook, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + assert.Equal(t, totalPrice, sdk.NewDec(1020)) + assert.Equal(t, totalExecuted, sdk.NewDec(10)) + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, len(longBook), 1) + assert.Equal(t, longBook[0].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, *longBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 2, + Account: "abc", + Quantity: sdk.NewDec(1), + }, { + OrderId: 3, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(shortBook), 0) + assert.Equal(t, len(settlements), 4) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(2), + ExecutionCostOrProceed: sdk.NewDec(105), + ExpectedCostOrProceed: sdk.NewDec(110), + Account: "abc", + OrderType: "Limit", + OrderId: 4, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(2), + ExecutionCostOrProceed: sdk.NewDec(105), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[2], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(3), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[3], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(3), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) +} + +func TestMatchMultipleOrderFromMultipleShortBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + { + Id: 2, + Price: sdk.NewDec(104), + Quantity: sdk.NewDec(1), + Account: "jkl", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + { + Id: 3, + Price: sdk.NewDec(98), + Quantity: sdk.NewDec(2), + Account: "mno", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + shortOrders := []*types.Order{} + longBook := []types.OrderBookEntry{} + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(90), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(90), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 4, + Account: "def", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(6), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "def", + Quantity: sdk.NewDec(4), + }, { + OrderId: 6, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, longOrders, shortOrders) + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + outcome := exchange.MatchLimitOrders( + ctx, orderbook, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + assert.Equal(t, totalPrice, sdk.NewDec(1184)) + assert.Equal(t, totalExecuted, sdk.NewDec(12)) + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, len(longBook), 1) + assert.Equal(t, longBook[0].GetPrice(), sdk.NewDec(98)) + assert.Equal(t, *longBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(98), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 3, + Account: "mno", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(shortBook), 1) + assert.Equal(t, shortBook[0].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, *shortBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(settlements), 6) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(97), + ExpectedCostOrProceed: sdk.NewDec(104), + Account: "jkl", + OrderType: "Limit", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(97), + ExpectedCostOrProceed: sdk.NewDec(90), + Account: "def", + OrderType: "Limit", + OrderId: 4, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[2], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(95), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[3], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(95), + ExpectedCostOrProceed: sdk.NewDec(90), + Account: "def", + OrderType: "Limit", + OrderId: 4, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[4], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(4), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[5], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(4), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 5, + Timestamp: TestTimestamp, + Height: TestHeight, + }) +} + +func TestMatchMultipleOrderFromMultipleLongBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{} + shortOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + { + Id: 2, + Price: sdk.NewDec(96), + Quantity: sdk.NewDec(1), + Account: "jkl", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + { + Id: 3, + Price: sdk.NewDec(102), + Quantity: sdk.NewDec(2), + Account: "mno", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + }, + } + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(6), + Allocations: []*types.Allocation{{ + OrderId: 4, + Account: "abc", + Quantity: sdk.NewDec(4), + }, { + OrderId: 5, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.LongBook{ + Price: sdk.NewDec(110), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(110), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "abc", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + shortBook := []types.OrderBookEntry{} + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + exchange.AddOutstandingLimitOrdersToOrderbook(ctx, dexkeeper, longOrders, shortOrders) + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + outcome := exchange.MatchLimitOrders( + ctx, orderbook, + ) + 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(96)) + assert.Equal(t, maxPrice, sdk.NewDec(110)) + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, len(longBook), 1) + assert.Equal(t, longBook[0].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, *longBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(shortBook), 1) + assert.Equal(t, shortBook[0].GetPrice(), sdk.NewDec(102)) + assert.Equal(t, *shortBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(102), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 3, + Account: "mno", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(settlements), 6) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(103), + ExpectedCostOrProceed: sdk.NewDec(110), + Account: "abc", + OrderType: "Limit", + OrderId: 6, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(103), + ExpectedCostOrProceed: sdk.NewDec(96), + Account: "jkl", + OrderType: "Limit", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[2], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(105), + ExpectedCostOrProceed: sdk.NewDec(110), + Account: "abc", + OrderType: "Limit", + OrderId: 6, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[3], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(105), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[4], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(4), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 4, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[5], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(4), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) +} diff --git a/x/dex/exchange/market_order.go b/x/dex/exchange/market_order.go new file mode 100644 index 000000000..c557ded25 --- /dev/null +++ b/x/dex/exchange/market_order.go @@ -0,0 +1,273 @@ +package exchange + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + cache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func MatchMarketOrders( + ctx sdk.Context, + marketOrders []*types.Order, + orderBookEntries *types.CachedSortedOrderBookEntries, + direction types.PositionDirection, + blockOrders *cache.BlockOrders, +) ExecutionOutcome { + totalExecuted, totalPrice := sdk.ZeroDec(), sdk.ZeroDec() + minPrice, maxPrice := sdk.OneDec().Neg(), 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, &minPrice, &maxPrice, settlements, allTakerSettlements, blockOrders) + case types.OrderType_FOKMARKET: + settlements, allTakerSettlements = MatchFOKMarketOrder( + ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, &minPrice, &maxPrice, settlements, allTakerSettlements, blockOrders) + default: + settlements, allTakerSettlements = MatchMarketOrder( + ctx, marketOrder, orderBookEntries, direction, &totalExecuted, &totalPrice, &minPrice, &maxPrice, settlements, allTakerSettlements, blockOrders) + } + } + + if totalExecuted.IsPositive() { + clearingPrice := totalPrice.Quo(totalExecuted) + for _, settlement := range allTakerSettlements { + settlement.ExecutionCostOrProceed = clearingPrice + } + minPrice, maxPrice = clearingPrice, clearingPrice + settlements = append(settlements, allTakerSettlements...) + } + return ExecutionOutcome{ + TotalNotional: totalPrice, + TotalQuantity: totalExecuted, + Settlements: settlements, + MinPrice: minPrice, + MaxPrice: maxPrice, + } +} + +func MatchMarketOrder( + ctx sdk.Context, + marketOrder *types.Order, + orderBookEntries *types.CachedSortedOrderBookEntries, + direction types.PositionDirection, + totalExecuted *sdk.Dec, + totalPrice *sdk.Dec, + minPrice *sdk.Dec, + maxPrice *sdk.Dec, + settlements []*types.SettlementEntry, + allTakerSettlements []*types.SettlementEntry, + blockOrders *cache.BlockOrders, +) ([]*types.SettlementEntry, []*types.SettlementEntry) { + remainingQuantity := marketOrder.Quantity + for entry := orderBookEntries.Next(ctx); entry != nil; entry = orderBookEntries.Next(ctx) { + // If price is zero, it means the order sender + // doesn't want to specify a worst price, so + // we don't need to perform price check for such orders + if !marketOrder.Price.IsZero() { + // Check if worst price can be matched against order book + if (direction == types.PositionDirection_LONG && marketOrder.Price.LT(entry.GetPrice())) || + (direction == types.PositionDirection_SHORT && marketOrder.Price.GT(entry.GetPrice())) { + break + } + } + var executed sdk.Dec + if remainingQuantity.LTE(entry.GetOrderEntry().Quantity) { + executed = remainingQuantity + } else { + executed = entry.GetOrderEntry().Quantity + } + remainingQuantity = remainingQuantity.Sub(executed) + *totalExecuted = totalExecuted.Add(executed) + *totalPrice = totalPrice.Add( + executed.Mul(entry.GetPrice()), + ) + if minPrice.IsNegative() || minPrice.GT(entry.GetPrice()) { + *minPrice = entry.GetPrice() + } + *maxPrice = sdk.MaxDec(*maxPrice, entry.GetPrice()) + + takerSettlements, makerSettlements := Settle( + ctx, + marketOrder, + executed, + orderBookEntries, + marketOrder.Price, + entry.GetPrice(), + ) + // update the status of order in the memState + UpdateOrderData(marketOrder, executed, blockOrders) + settlements = append(settlements, makerSettlements...) + // taker settlements' clearing price will need to be adjusted after all market order executions finish + allTakerSettlements = append(allTakerSettlements, takerSettlements...) + if remainingQuantity.IsZero() { + break + } + } + + orderBookEntries.Flush(ctx) + + return settlements, allTakerSettlements +} + +func MatchFOKMarketOrder( + ctx sdk.Context, + marketOrder *types.Order, + orderBookEntries *types.CachedSortedOrderBookEntries, + direction types.PositionDirection, + totalExecuted *sdk.Dec, + totalPrice *sdk.Dec, + minPrice *sdk.Dec, + maxPrice *sdk.Dec, + settlements []*types.SettlementEntry, + allTakerSettlements []*types.SettlementEntry, + blockOrders *cache.BlockOrders, +) ([]*types.SettlementEntry, []*types.SettlementEntry) { + // check if there is enough liquidity for fill-or-kill market order, if not skip them + remainingQuantity := marketOrder.Quantity + newSettlements, newTakerSettlements := []*types.SettlementEntry{}, []*types.SettlementEntry{} + orders, executedQuantities, entryPrices := []*types.Order{}, []sdk.Dec{}, []sdk.Dec{} + for entry := orderBookEntries.Next(ctx); entry != nil; entry = orderBookEntries.Next(ctx) { + if !marketOrder.Price.IsZero() { + if (direction == types.PositionDirection_LONG && marketOrder.Price.LT(entry.GetPrice())) || + (direction == types.PositionDirection_SHORT && marketOrder.Price.GT(entry.GetPrice())) { + break + } + } + + var executed sdk.Dec + if remainingQuantity.LTE(entry.GetOrderEntry().Quantity) { + executed = remainingQuantity + } else { + executed = entry.GetOrderEntry().Quantity + } + remainingQuantity = remainingQuantity.Sub(executed) + + takerSettlements, makerSettlements := Settle( + ctx, + marketOrder, + executed, + orderBookEntries, + marketOrder.Price, + entry.GetPrice(), + ) + newSettlements = append(newSettlements, makerSettlements...) + newTakerSettlements = append(newTakerSettlements, takerSettlements...) + orders = append(orders, marketOrder) + executedQuantities = append(executedQuantities, executed) + entryPrices = append(entryPrices, entry.GetPrice()) + + if remainingQuantity.IsZero() { + break + } + } + + if remainingQuantity.IsZero() { + orderBookEntries.Flush(ctx) + settlements = append(settlements, newSettlements...) + allTakerSettlements = append(allTakerSettlements, newTakerSettlements...) + for i, order := range orders { + UpdateOrderData(order, executedQuantities[i], blockOrders) + *totalExecuted = totalExecuted.Add(executedQuantities[i]) + *totalPrice = totalPrice.Add( + executedQuantities[i].Mul(entryPrices[i]), + ) + if minPrice.IsNegative() || minPrice.GT(entryPrices[i]) { + *minPrice = entryPrices[i] + } + *maxPrice = sdk.MaxDec(*maxPrice, entryPrices[i]) + } + } else { + orderBookEntries.Refresh(ctx) + } + + return settlements, allTakerSettlements +} + +func MatchByValueFOKMarketOrder( + ctx sdk.Context, + marketOrder *types.Order, + orderBookEntries *types.CachedSortedOrderBookEntries, + direction types.PositionDirection, + totalExecuted *sdk.Dec, + totalPrice *sdk.Dec, + minPrice *sdk.Dec, + maxPrice *sdk.Dec, + settlements []*types.SettlementEntry, + allTakerSettlements []*types.SettlementEntry, + blockOrders *cache.BlockOrders, +) ([]*types.SettlementEntry, []*types.SettlementEntry) { + remainingFund := marketOrder.Nominal + remainingQuantity := marketOrder.Quantity + newSettlements, newTakerSettlements := []*types.SettlementEntry{}, []*types.SettlementEntry{} + orders, executedQuantities, entryPrices := []*types.Order{}, []sdk.Dec{}, []sdk.Dec{} + for entry := orderBookEntries.Next(ctx); entry != nil; entry = orderBookEntries.Next(ctx) { + if !marketOrder.Price.IsZero() { + if (direction == types.PositionDirection_LONG && marketOrder.Price.LT(entry.GetPrice())) || + (direction == types.PositionDirection_SHORT && marketOrder.Price.GT(entry.GetPrice())) { + break + } + } + var executed sdk.Dec + if remainingFund.LTE(entry.GetOrderEntry().Quantity.Mul(entry.GetPrice())) { + executed = remainingFund.Quo(entry.GetPrice()) + remainingFund = sdk.ZeroDec() + } else { + executed = entry.GetOrderEntry().Quantity + remainingFund = remainingFund.Sub(executed.Mul(entry.GetPrice())) + } + remainingQuantity = remainingQuantity.Sub(executed) + + takerSettlements, makerSettlements := Settle( + ctx, + marketOrder, + executed, + orderBookEntries, + marketOrder.Price, + entry.GetPrice(), + ) + newSettlements = append(newSettlements, makerSettlements...) + newTakerSettlements = MergeByNominalTakerSettlements(append(newTakerSettlements, takerSettlements...)) + orders = append(orders, marketOrder) + executedQuantities = append(executedQuantities, executed) + entryPrices = append(entryPrices, entry.GetPrice()) + if remainingFund.IsZero() || remainingQuantity.LTE(sdk.ZeroDec()) { + break + } + } + + // settle orders only when all fund are used + if remainingFund.IsZero() && remainingQuantity.GTE(sdk.ZeroDec()) { + orderBookEntries.Flush(ctx) + settlements = append(settlements, newSettlements...) + allTakerSettlements = append(allTakerSettlements, newTakerSettlements...) + for i, order := range orders { + UpdateOrderData(order, executedQuantities[i], blockOrders) + *totalExecuted = totalExecuted.Add(executedQuantities[i]) + *totalPrice = totalPrice.Add( + executedQuantities[i].Mul(entryPrices[i]), + ) + if minPrice.IsNegative() || minPrice.GT(entryPrices[i]) { + *minPrice = entryPrices[i] + } + *maxPrice = sdk.MaxDec(*maxPrice, entryPrices[i]) + } + } else { + orderBookEntries.Refresh(ctx) + } + + return settlements, allTakerSettlements +} + +func MergeByNominalTakerSettlements(settlements []*types.SettlementEntry) []*types.SettlementEntry { + aggregatedSettlement := types.SettlementEntry{Quantity: sdk.ZeroDec()} + for _, settlement := range settlements { + quantity := settlement.Quantity.Add(aggregatedSettlement.Quantity) + aggregatedSettlement = *settlement + aggregatedSettlement.Quantity = quantity + } + + return []*types.SettlementEntry{&aggregatedSettlement} +} diff --git a/x/dex/exchange/market_order_fuzz_test.go b/x/dex/exchange/market_order_fuzz_test.go new file mode 100644 index 000000000..2cc64f446 --- /dev/null +++ b/x/dex/exchange/market_order_fuzz_test.go @@ -0,0 +1,92 @@ +package exchange_test + +import ( + "sort" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/testutil/fuzzing" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + keeperutil "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +var TestFuzzMarketCtx = sdk.NewContext(nil, tmproto.Header{}, false, log.NewNopLogger()) + +func FuzzMatchMarketOrders(f *testing.F) { + f.Fuzz(fuzzTargetMatchMarketOrders) +} + +func fuzzTargetMatchMarketOrders( + t *testing.T, + takerLong bool, + orderSorted bool, + orderbookSorted bool, + prices []byte, + quantities []byte, + entryWeights []byte, + accountIndices []byte, + allocationWeights []byte, +) { + dexkeeper, TestFuzzMarketCtx := keepertest.DexKeeper(t) + TestFuzzMarketCtx = TestFuzzMarketCtx.WithBlockHeight(1).WithBlockTime(time.Now()) + blockOrders := dexutils.GetMemState(TestFuzzMarketCtx.Context()).GetBlockOrders(TestFuzzMarketCtx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := fuzzing.GetOrderBookEntries(!takerLong, keepertest.TestPriceDenom, keepertest.TestAssetDenom, entryWeights, accountIndices, allocationWeights) + for _, entry := range entries { + if takerLong { + dexkeeper.SetShortOrderBookEntry(TestFuzzMarketCtx, keepertest.TestContract, entry) + } else { + dexkeeper.SetLongOrderBookEntry(TestFuzzMarketCtx, keepertest.TestContract, entry) + } + } + var direction types.PositionDirection + if takerLong { + direction = types.PositionDirection_LONG + } else { + direction = types.PositionDirection_SHORT + } + orders := fuzzing.GetPlacedOrders(direction, types.OrderType_MARKET, keepertest.TestPair, prices, quantities) + for _, order := range orders { + blockOrders.Add(order) + } + + if orderSorted { + sort.Slice(orders, func(i, j int) bool { + // a price of 0 indicates that there is no worst price for the order, so it should + // always be ranked at the top. + if orders[i].Price.IsZero() { + return true + } else if orders[j].Price.IsZero() { + return false + } + switch direction { + case types.PositionDirection_LONG: + return orders[i].Price.GT(orders[j].Price) + case types.PositionDirection_SHORT: + return orders[i].Price.LT(orders[j].Price) + default: + panic("Unknown direction") + } + }) + } + if orderbookSorted { + sort.Slice(entries, func(i, j int) bool { + return entries[i].GetPrice().LT(entries[j].GetPrice()) + }) + } + + require.NotPanics(t, func() { + orderbook := keeperutil.PopulateOrderbook(TestFuzzMarketCtx, dexkeeper, types.ContractAddress(keepertest.TestContract), types.Pair{PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}) + book := orderbook.Longs + if takerLong { + book = orderbook.Shorts + } + exchange.MatchMarketOrders(TestFuzzMarketCtx, orders, book, direction, blockOrders) + }) +} diff --git a/x/dex/exchange/market_order_test.go b/x/dex/exchange/market_order_test.go new file mode 100644 index 000000000..86339654b --- /dev/null +++ b/x/dex/exchange/market_order_test.go @@ -0,0 +1,1175 @@ +package exchange_test + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + dex "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + keeperutil "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/assert" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" +) + +const ( + TestTimestamp uint64 = 10000 + TestHeight uint64 = 1 +) + +func TestMatchFoKMarketOrderFromShortBookNotEnoughLiquidity(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_FOKMARKET, + }, + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(4), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "def", + Quantity: sdk.NewDec(4), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(&types.Order{ + Id: 1, + Account: "abc", + ContractAddr: "test", + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_FOKMARKET, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }) + + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Shorts + outcome := exchange.MatchMarketOrders( + ctx, longOrders, entries, types.PositionDirection_LONG, blockOrders, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, totalPrice, sdk.ZeroDec()) + assert.Equal(t, totalExecuted, sdk.ZeroDec()) + assert.Equal(t, len(shortBook), 1) + assert.Equal(t, shortBook[0].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, shortBook[0].GetOrderEntry().Quantity, sdk.NewDec(4)) + assert.Equal(t, len(settlements), 0) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.NewDec(5)) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_PLACED) +} + +func TestMatchFoKMarketOrderFromShortBookHappyPath(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_FOKMARKET, + }, + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "def", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Shorts + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(&types.Order{ + Id: 1, + Account: "abc", + ContractAddr: "test", + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_FOKMARKET, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }) + outcome := exchange.MatchMarketOrders( + ctx, longOrders, entries, types.PositionDirection_LONG, blockOrders, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, totalPrice, sdk.NewDec(500)) + assert.Equal(t, totalExecuted, sdk.NewDec(5)) + assert.Equal(t, len(shortBook), 0) + assert.Equal(t, len(settlements), 2) + assert.Equal(t, *settlements[0], 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: 5, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(5), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Fokmarket", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.ZeroDec()) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_FULFILLED) +} + +func TestMatchByValueFOKMarketOrderFromShortBookNotEnoughLiquidity(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_FOKMARKETBYVALUE, + Nominal: sdk.NewDec(500), + }, + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(90), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(90), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 4, + Account: "def", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.MustNewDecFromStr("0.4"), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "def", + Quantity: sdk.MustNewDecFromStr("0.4"), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(longOrders[0]) + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Shorts + outcome := exchange.MatchMarketOrders( + ctx, longOrders, entries, types.PositionDirection_LONG, &dex.BlockOrders{}, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, totalPrice, sdk.ZeroDec()) + assert.Equal(t, totalExecuted, sdk.ZeroDec()) + assert.Equal(t, len(shortBook), 2) + assert.Equal(t, shortBook[0].GetPrice(), sdk.NewDec(90)) + assert.Equal(t, shortBook[0].GetOrderEntry().Price, sdk.NewDec(90)) + assert.Equal(t, shortBook[0].GetOrderEntry().Quantity, sdk.NewDec(5)) + assert.Equal(t, len(settlements), 0) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.NewDec(5)) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_PLACED) +} + +func TestMatchByValueFOKMarketOrderFromShortBookHappyPath(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(6), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_FOKMARKETBYVALUE, + Nominal: sdk.NewDec(500), + }, + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(90), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(90), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 4, + Account: "def", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.MustNewDecFromStr("0.6"), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "def", + Quantity: sdk.MustNewDecFromStr("0.6"), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(longOrders[0]) + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Shorts + outcome := exchange.MatchMarketOrders( + ctx, longOrders, entries, types.PositionDirection_LONG, blockOrders, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, totalPrice, sdk.NewDec(500)) + assert.Equal(t, totalExecuted, sdk.MustNewDecFromStr("5.5")) + assert.Equal(t, len(shortBook), 1) + assert.Equal(t, len(settlements), 3) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(5), + ExecutionCostOrProceed: sdk.NewDec(90), + ExpectedCostOrProceed: sdk.NewDec(90), + Account: "def", + OrderType: "Limit", + OrderId: 4, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.MustNewDecFromStr("0.5"), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 5, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.MustNewDecFromStr("0.5")) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_FULFILLED) +} + +func TestMatchSingleMarketOrderFromShortBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "def", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(longOrders[0]) + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Shorts + outcome := exchange.MatchMarketOrders( + ctx, longOrders, entries, types.PositionDirection_LONG, blockOrders, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, totalPrice, sdk.NewDec(500)) + assert.Equal(t, totalExecuted, sdk.NewDec(5)) + assert.Equal(t, len(shortBook), 0) + assert.Equal(t, len(settlements), 2) + assert.Equal(t, *settlements[0], 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: 5, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(5), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Market", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.ZeroDec()) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_FULFILLED) +} + +func TestMatchSingleMarketOrderFromLongBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + shortOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + } + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "def", + Quantity: sdk.NewDec(5), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(shortOrders[0]) + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Longs + outcome := exchange.MatchMarketOrders( + ctx, shortOrders, entries, types.PositionDirection_SHORT, blockOrders, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, totalPrice, sdk.NewDec(500)) + assert.Equal(t, totalExecuted, sdk.NewDec(5)) + assert.Equal(t, len(longBook), 0) + assert.Equal(t, len(settlements), 2) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(5), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 5, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(5), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Market", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.ZeroDec()) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_FULFILLED) +} + +func TestMatchSingleMarketOrderFromMultipleShortBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(90), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(90), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "def", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(6), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "def", + Quantity: sdk.NewDec(4), + }, { + OrderId: 7, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(longOrders[0]) + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Shorts + outcome := exchange.MatchMarketOrders( + ctx, longOrders, entries, types.PositionDirection_LONG, blockOrders, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, totalPrice, sdk.NewDec(480)) + assert.Equal(t, totalExecuted, sdk.NewDec(5)) + assert.Equal(t, len(shortBook), 1) + assert.Equal(t, shortBook[0].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, *shortBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "def", + Quantity: sdk.NewDec(1), + }, { + OrderId: 7, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(settlements), 4) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(2), + ExecutionCostOrProceed: sdk.NewDec(90), + ExpectedCostOrProceed: sdk.NewDec(90), + Account: "def", + OrderType: "Limit", + OrderId: 5, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(3), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 6, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[2], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(2), + ExecutionCostOrProceed: sdk.NewDec(96), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Market", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[3], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(3), + ExecutionCostOrProceed: sdk.NewDec(96), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Market", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.ZeroDec()) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_FULFILLED) +} + +func TestMatchSingleMarketOrderFromMultipleLongBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + shortOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "def", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + } + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(6), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "abc", + Quantity: sdk.NewDec(4), + }, { + OrderId: 7, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.LongBook{ + Price: sdk.NewDec(110), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(110), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "abc", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(shortOrders[0]) + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Longs + outcome := exchange.MatchMarketOrders( + ctx, shortOrders, entries, types.PositionDirection_SHORT, blockOrders, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, totalPrice, sdk.NewDec(520)) + assert.Equal(t, totalExecuted, sdk.NewDec(5)) + assert.Equal(t, len(longBook), 1) + assert.Equal(t, longBook[0].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, *longBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(3), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "abc", + Quantity: sdk.NewDec(1), + }, { + OrderId: 7, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(settlements), 4) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(2), + ExecutionCostOrProceed: sdk.NewDec(110), + ExpectedCostOrProceed: sdk.NewDec(110), + Account: "abc", + OrderType: "Limit", + OrderId: 5, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(3), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 6, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[2], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(2), + ExecutionCostOrProceed: sdk.NewDec(104), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Market", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[3], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(3), + ExecutionCostOrProceed: sdk.NewDec(104), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Market", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.ZeroDec()) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_FULFILLED) +} + +func TestMatchMultipleMarketOrderFromMultipleShortBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + longOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(104), + Quantity: sdk.NewDec(1), + Account: "jkl", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + { + Id: 2, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + { + Id: 3, + Price: sdk.NewDec(98), + Quantity: sdk.NewDec(2), + Account: "mno", + PositionDirection: types.PositionDirection_LONG, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + } + shortBook := []types.OrderBookEntry{ + &types.ShortBook{ + Price: sdk.NewDec(90), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(90), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 4, + Account: "def", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.ShortBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(6), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "def", + Quantity: sdk.NewDec(4), + }, { + OrderId: 6, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(longOrders[0]) + blockOrders.Add(longOrders[1]) + blockOrders.Add(longOrders[2]) + for _, e := range shortBook { + dexkeeper.SetShortOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Shorts + outcome := exchange.MatchMarketOrders( + ctx, longOrders, entries, types.PositionDirection_LONG, blockOrders, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + + shortBook = dexkeeper.GetAllShortBookForPair(ctx, "test", "USDC", "ATOM") + assert.Equal(t, totalPrice, sdk.NewDec(580)) + assert.Equal(t, totalExecuted, sdk.NewDec(6)) + assert.Equal(t, len(shortBook), 1) + assert.Equal(t, shortBook[0].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, *shortBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(settlements), 6) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(90), + ExpectedCostOrProceed: sdk.NewDec(90), + Account: "def", + OrderType: "Limit", + OrderId: 4, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(90), + ExpectedCostOrProceed: sdk.NewDec(90), + Account: "def", + OrderType: "Limit", + OrderId: 4, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[2], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(4), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "def", + OrderType: "Limit", + OrderId: 5, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[3], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.MustNewDecFromStr("96.666666666666666667"), + ExpectedCostOrProceed: sdk.NewDec(104), + Account: "jkl", + OrderType: "Market", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[4], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.MustNewDecFromStr("96.666666666666666667"), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Market", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[5], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(4), + ExecutionCostOrProceed: sdk.MustNewDecFromStr("96.666666666666666667"), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Market", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.ZeroDec()) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_FULFILLED) + assert.Equal(t, blockOrders.Get()[1].Quantity, sdk.ZeroDec()) + assert.Equal(t, blockOrders.Get()[1].Status, types.OrderStatus_FULFILLED) + assert.Equal(t, blockOrders.Get()[2].Quantity, sdk.NewDec(2)) + assert.Equal(t, blockOrders.Get()[2].Status, types.OrderStatus_PLACED) +} + +func TestMatchMultipleMarketOrderFromMultipleLongBook(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(int64(TestHeight)).WithBlockTime(time.Unix(int64(TestTimestamp), 0)) + shortOrders := []*types.Order{ + { + Id: 1, + Price: sdk.NewDec(96), + Quantity: sdk.NewDec(1), + Account: "jkl", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + { + Id: 2, + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(5), + Account: "abc", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + { + Id: 3, + Price: sdk.NewDec(102), + Quantity: sdk.NewDec(2), + Account: "mno", + PositionDirection: types.PositionDirection_SHORT, + ContractAddr: "test", + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_MARKET, + }, + } + longBook := []types.OrderBookEntry{ + &types.LongBook{ + Price: sdk.NewDec(100), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(6), + Allocations: []*types.Allocation{{ + OrderId: 5, + Account: "abc", + Quantity: sdk.NewDec(4), + }, { + OrderId: 6, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + &types.LongBook{ + Price: sdk.NewDec(110), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(110), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 4, + Account: "abc", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + } + blockOrders := dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, "testAccount", types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + blockOrders.Add(shortOrders[0]) + blockOrders.Add(shortOrders[1]) + blockOrders.Add(shortOrders[2]) + for _, e := range longBook { + dexkeeper.SetLongOrderBookEntry(ctx, "test", e) + } + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress("test"), types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"}) + entries := orderbook.Longs + outcome := exchange.MatchMarketOrders( + ctx, shortOrders, entries, types.PositionDirection_SHORT, blockOrders, + ) + totalPrice := outcome.TotalNotional + totalExecuted := outcome.TotalQuantity + settlements := outcome.Settlements + minPrice := outcome.MinPrice + maxPrice := outcome.MaxPrice + + longBook = dexkeeper.GetAllLongBookForPair(ctx, "test", "USDC", "ATOM") + 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, len(longBook), 1) + assert.Equal(t, longBook[0].GetPrice(), sdk.NewDec(100)) + assert.Equal(t, *longBook[0].GetOrderEntry(), types.OrderEntry{ + Price: sdk.NewDec(100), + Quantity: sdk.NewDec(2), + Allocations: []*types.Allocation{{ + OrderId: 6, + Account: "ghi", + Quantity: sdk.NewDec(2), + }}, + PriceDenom: "USDC", + AssetDenom: "ATOM", + }) + assert.Equal(t, len(settlements), 6) + assert.Equal(t, *settlements[0], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(110), + ExpectedCostOrProceed: sdk.NewDec(110), + Account: "abc", + OrderType: "Limit", + OrderId: 4, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[1], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.NewDec(110), + ExpectedCostOrProceed: sdk.NewDec(110), + Account: "abc", + OrderType: "Limit", + OrderId: 4, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[2], types.SettlementEntry{ + PositionDirection: "Long", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(4), + ExecutionCostOrProceed: sdk.NewDec(100), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Limit", + OrderId: 5, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[3], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.MustNewDecFromStr("103.333333333333333333"), + ExpectedCostOrProceed: sdk.NewDec(96), + Account: "jkl", + OrderType: "Market", + OrderId: 1, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[4], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(1), + ExecutionCostOrProceed: sdk.MustNewDecFromStr("103.333333333333333333"), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Market", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, *settlements[5], types.SettlementEntry{ + PositionDirection: "Short", + PriceDenom: "USDC", + AssetDenom: "ATOM", + Quantity: sdk.NewDec(4), + ExecutionCostOrProceed: sdk.MustNewDecFromStr("103.333333333333333333"), + ExpectedCostOrProceed: sdk.NewDec(100), + Account: "abc", + OrderType: "Market", + OrderId: 2, + Timestamp: TestTimestamp, + Height: TestHeight, + }) + assert.Equal(t, blockOrders.Get()[0].Quantity, sdk.ZeroDec()) + assert.Equal(t, blockOrders.Get()[0].Status, types.OrderStatus_FULFILLED) + assert.Equal(t, blockOrders.Get()[1].Quantity, sdk.ZeroDec()) + assert.Equal(t, blockOrders.Get()[1].Status, types.OrderStatus_FULFILLED) + assert.Equal(t, blockOrders.Get()[2].Quantity, sdk.NewDec(2)) + assert.Equal(t, blockOrders.Get()[2].Status, types.OrderStatus_PLACED) +} diff --git a/x/dex/exchange/settlement.go b/x/dex/exchange/settlement.go new file mode 100644 index 000000000..fe049808e --- /dev/null +++ b/x/dex/exchange/settlement.go @@ -0,0 +1,129 @@ +package exchange + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + cache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// this function helps to settle market orders +func Settle( + ctx sdk.Context, + takerOrder *types.Order, + quantityTaken sdk.Dec, + orderbook *types.CachedSortedOrderBookEntries, + worstPrice sdk.Dec, + makerPrice sdk.Dec, +) ([]*types.SettlementEntry, []*types.SettlementEntry) { + // settlement of one liquidity taker's order is allocated on a FIFO basis + takerSettlements := []*types.SettlementEntry{} + makerSettlements := []*types.SettlementEntry{} + if quantityTaken.IsZero() { + return takerSettlements, makerSettlements + } + newToSettle, _ := orderbook.SettleQuantity(ctx, quantityTaken) + for _, toSettle := range newToSettle { + takerSettlements = append(takerSettlements, types.NewSettlementEntry( + ctx, + takerOrder.Id, + takerOrder.Account, + takerOrder.PositionDirection, + takerOrder.PriceDenom, + takerOrder.AssetDenom, + toSettle.Amount, + worstPrice, + worstPrice, + takerOrder.OrderType, + )) + makerSettlements = append(makerSettlements, types.NewSettlementEntry( + ctx, + toSettle.OrderID, + toSettle.Account, + types.OppositePositionDirection[takerOrder.PositionDirection], + takerOrder.PriceDenom, + takerOrder.AssetDenom, + toSettle.Amount, + makerPrice, + makerPrice, + types.OrderType_LIMIT, + )) + } + + return takerSettlements, makerSettlements +} + +// this function update the order data in the memState +// to be noted that the order status will only reflect for market orders that are settled +func UpdateOrderData( + takerOrder *types.Order, + quantityTaken sdk.Dec, + blockOrders *cache.BlockOrders, +) { + // update order data in the memstate + orderStored := blockOrders.GetByID(takerOrder.Id) + orderStored.Quantity = orderStored.Quantity.Sub(quantityTaken) + if orderStored.OrderType == types.OrderType_FOKMARKET || orderStored.OrderType == types.OrderType_FOKMARKETBYVALUE || orderStored.Quantity.IsZero() { + orderStored.Status = types.OrderStatus_FULFILLED + } + blockOrders.Add(orderStored) +} + +func SettleFromBook( + ctx sdk.Context, + orderbook *types.OrderBook, + executedQuantity sdk.Dec, + longPrice sdk.Dec, + shortPrice sdk.Dec, +) []*types.SettlementEntry { + // settlement from within the order book is also allocated on a FIFO basis + settlements := []*types.SettlementEntry{} + if executedQuantity.IsZero() { + return settlements + } + newLongToSettle, _ := orderbook.Longs.SettleQuantity(ctx, executedQuantity) + newShortToSettle, _ := orderbook.Shorts.SettleQuantity(ctx, executedQuantity) + avgPrice := longPrice.Add(shortPrice).Quo(sdk.NewDec(2)) + longPtr, shortPtr := 0, 0 + for longPtr < len(newLongToSettle) && shortPtr < len(newShortToSettle) { + longToSettle := newLongToSettle[longPtr] + shortToSettle := newShortToSettle[shortPtr] + var quantity sdk.Dec + if longToSettle.Amount.LT(shortToSettle.Amount) { + quantity = longToSettle.Amount + } else { + quantity = shortToSettle.Amount + } + settlements = append(settlements, types.NewSettlementEntry( + ctx, + longToSettle.OrderID, + longToSettle.Account, + types.PositionDirection_LONG, + orderbook.Pair.PriceDenom, + orderbook.Pair.AssetDenom, + quantity, + avgPrice, + longPrice, + types.OrderType_LIMIT, + ), types.NewSettlementEntry( + ctx, + shortToSettle.OrderID, + shortToSettle.Account, + types.PositionDirection_SHORT, + orderbook.Pair.PriceDenom, + orderbook.Pair.AssetDenom, + quantity, + avgPrice, + shortPrice, + types.OrderType_LIMIT, + )) + newLongToSettle[longPtr] = types.ToSettle{Account: longToSettle.Account, Amount: longToSettle.Amount.Sub(quantity), OrderID: longToSettle.OrderID} + newShortToSettle[shortPtr] = types.ToSettle{Account: shortToSettle.Account, Amount: shortToSettle.Amount.Sub(quantity), OrderID: shortToSettle.OrderID} + if newLongToSettle[longPtr].Amount.IsZero() { + longPtr++ + } + if newShortToSettle[shortPtr].Amount.IsZero() { + shortPtr++ + } + } + return settlements +} diff --git a/x/dex/exchange/settlement_fuzz_test.go b/x/dex/exchange/settlement_fuzz_test.go new file mode 100644 index 000000000..afa1df5fb --- /dev/null +++ b/x/dex/exchange/settlement_fuzz_test.go @@ -0,0 +1,118 @@ +package exchange_test + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/testutil/fuzzing" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + keeperutil "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +var TestFuzzSettleCtx = sdk.NewContext(nil, tmproto.Header{}, false, log.NewNopLogger()) + +func FuzzSettleMarketOrder(f *testing.F) { + TestFuzzSettleCtx = TestFuzzSettleCtx.WithBlockHeight(1).WithBlockTime(time.Now()) + f.Fuzz(fuzzTargetMatchMarketOrders) +} + +func fuzzTargetSettle( + t *testing.T, + long bool, + prices []byte, + quantities []byte, + entryWeights []byte, + accountIndices []byte, + allocationWeights []byte, + priceI int64, + priceIsNil bool, + quantityI int64, + quantityIsNil bool, +) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) + entries := fuzzing.GetOrderBookEntries(!long, keepertest.TestPriceDenom, keepertest.TestAssetDenom, entryWeights, accountIndices, allocationWeights) + for _, entry := range entries { + if long { + dexkeeper.SetShortOrderBookEntry(ctx, keepertest.TestContract, entry) + } else { + dexkeeper.SetLongOrderBookEntry(ctx, keepertest.TestContract, entry) + } + } + var direction types.PositionDirection + if long { + direction = types.PositionDirection_LONG + } else { + direction = types.PositionDirection_SHORT + } + orders := fuzzing.GetPlacedOrders(direction, types.OrderType_MARKET, keepertest.TestPair, prices, quantities) + + price := fuzzing.FuzzDec(priceI, priceIsNil) + quantity := fuzzing.FuzzDec(quantityI, quantityIsNil) + + if len(entries) > len(orders) { + entries = entries[:len(orders)] + } else { + orders = orders[:len(entries)] + } + + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress(keepertest.TestContract), types.Pair{PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}) + book := orderbook.Longs + if long { + book = orderbook.Shorts + } + for i, entry := range entries { + require.NotPanics(t, func() { + exchange.Settle(ctx, orders[i], quantity, book, price, entry.GetPrice()) + }) + } +} + +func FuzzSettleLimitOrder(f *testing.F) { + TestFuzzSettleCtx = TestFuzzSettleCtx.WithBlockHeight(1).WithBlockTime(time.Now()) + f.Fuzz(fuzzTargetMatchMarketOrders) +} + +func fuzzTargetSettleFromBook( + t *testing.T, + buyEntryWeights []byte, + sellEntryWeights []byte, + buyAccountIndices []byte, + sellAccountIndices []byte, + buyAllocationWeights []byte, + sellAllocationWeights []byte, + quantityI int64, + quantityIsNil bool, +) { + dexkeeper, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(1).WithBlockTime(time.Now()) + buyEntries := fuzzing.GetOrderBookEntries(true, keepertest.TestPriceDenom, keepertest.TestAssetDenom, buyEntryWeights, buyAccountIndices, buyAllocationWeights) + for _, entry := range buyEntries { + dexkeeper.SetLongOrderBookEntry(ctx, keepertest.TestContract, entry) + } + sellEntries := fuzzing.GetOrderBookEntries(false, keepertest.TestPriceDenom, keepertest.TestAssetDenom, sellEntryWeights, sellAccountIndices, sellAllocationWeights) + for _, entry := range sellEntries { + dexkeeper.SetShortOrderBookEntry(ctx, keepertest.TestContract, entry) + } + + quantity := fuzzing.FuzzDec(quantityI, quantityIsNil) + + if len(buyEntries) > len(sellEntries) { + buyEntries = buyEntries[:len(sellEntries)] + } else { + sellEntries = sellEntries[:len(buyEntries)] + } + + orderbook := keeperutil.PopulateOrderbook(ctx, dexkeeper, types.ContractAddress(keepertest.TestContract), types.Pair{PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}) + for i, longEntry := range buyEntries { + require.NotPanics(t, func() { + exchange.SettleFromBook(ctx, orderbook, quantity, longEntry.GetPrice(), sellEntries[i].GetPrice()) + }) + } +} diff --git a/x/dex/genesis.go b/x/dex/genesis.go new file mode 100644 index 000000000..d5ef5c729 --- /dev/null +++ b/x/dex/genesis.go @@ -0,0 +1,85 @@ +package dex + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// InitGenesis initializes the dex module's state from a provided genesis +// state. +func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState) { + k.CreateModuleAccount(ctx) + + // Set all the longBook + for _, contractState := range genState.ContractState { + + contractInfo := contractState.ContractInfo + err := k.SetContract(ctx, &contractInfo) + if err != nil { + panic(err) + } + + for _, elem := range contractState.PairList { + k.AddRegisteredPair(ctx, contractState.ContractInfo.ContractAddr, elem) + } + + for _, elem := range contractState.LongBookList { + k.SetLongBook(ctx, contractState.ContractInfo.ContractAddr, elem) + } + + for _, elem := range contractState.ShortBookList { + k.SetShortBook(ctx, contractState.ContractInfo.ContractAddr, elem) + } + + for _, elem := range contractState.PriceList { + for _, priceElem := range elem.Prices { + k.SetPriceState(ctx, *priceElem, contractState.ContractInfo.ContractAddr) + } + } + + k.SetNextOrderID(ctx, contractState.ContractInfo.ContractAddr, contractState.NextOrderId) + + } + + // this line is used by starport scaffolding # genesis/module/init + k.SetParams(ctx, genState.Params) + + k.SetEpoch(ctx, genState.LastEpoch) +} + +// ExportGenesis returns the dex module's exported genesis. +func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState { + genesis := types.DefaultGenesis() + genesis.Params = k.GetParams(ctx) + + allContractInfo := k.GetAllContractInfo(ctx) + contractStates := make([]types.ContractState, len(allContractInfo)) + for i, contractInfo := range allContractInfo { + contractAddr := contractInfo.ContractAddr + registeredPairs := k.GetAllRegisteredPairs(ctx, contractAddr) + // Save all price info for contract, for all its pairs + contractPrices := []types.ContractPairPrices{} + for _, elem := range registeredPairs { + pairPrices := k.GetAllPrices(ctx, contractAddr, elem) + contractPrices = append(contractPrices, types.ContractPairPrices{ + PricePair: elem, + Prices: pairPrices, + }) + } + contractStates[i] = types.ContractState{ + ContractInfo: contractInfo, + LongBookList: k.GetAllLongBook(ctx, contractAddr), + ShortBookList: k.GetAllShortBook(ctx, contractAddr), + PairList: registeredPairs, + PriceList: contractPrices, + NextOrderId: k.GetNextOrderID(ctx, contractAddr), + } + } + genesis.ContractState = contractStates + + _, currentEpoch := k.IsNewEpoch(ctx) + genesis.LastEpoch = currentEpoch + + return genesis +} diff --git a/x/dex/genesis_test.go b/x/dex/genesis_test.go new file mode 100644 index 000000000..4cbf0cf21 --- /dev/null +++ b/x/dex/genesis_test.go @@ -0,0 +1,105 @@ +package dex_test + +import ( + "testing" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func TEST_PAIR() types.Pair { + return types.Pair{ + PriceDenom: "USDC", + AssetDenom: "ATOM", + } +} + +func TestGenesis(t *testing.T) { + contractList := []types.ContractState{} + contractDependencies := []*types.ContractDependencyInfo{ + { + Dependency: "dependency1", + }, + { + Dependency: "dependency2", + }, + } + + contractInfo := types.ContractInfoV2{ + CodeId: uint64(1), + ContractAddr: "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m", + Dependencies: contractDependencies, + } + + pairList := []types.Pair{ + { + PriceDenom: "USDC", + AssetDenom: "SEI", + PriceTicksize: &keepertest.TestTicksize, + QuantityTicksize: &keepertest.TestTicksize, + }, + } + + priceList := []types.ContractPairPrices{ + { + PricePair: pairList[0], + Prices: []*types.Price{ + { + SnapshotTimestampInSeconds: 2, + Pair: &(pairList[0]), + Price: sdk.MustNewDecFromStr("101"), + }, + }, + }, + } + + contractState := types.ContractState{ + LongBookList: []types.LongBook{ + { + Price: sdk.NewDec(1), + Entry: &types.OrderEntry{ + Price: sdk.ZeroDec(), + }, + }, + }, + ShortBookList: []types.ShortBook{ + { + Price: sdk.NewDec(1), + Entry: &types.OrderEntry{ + Price: sdk.ZeroDec(), + }, + }, + }, + ContractInfo: contractInfo, + PairList: pairList, + PriceList: priceList, + NextOrderId: 10, + } + contractList = append(contractList, contractState) + + genesisState := types.GenesisState{ + Params: types.DefaultParams(), + // this line is used by starport scaffolding # genesis/test/state + ContractState: contractList, + } + + k, ctx := keepertest.DexKeeper(t) + k.SetContract(ctx, &contractInfo) + dex.InitGenesis(ctx, *k, genesisState) + got := dex.ExportGenesis(ctx, *k) + require.NotNil(t, got) + + require.ElementsMatch(t, genesisState.ContractState[0].LongBookList, got.ContractState[0].LongBookList) + require.ElementsMatch(t, genesisState.ContractState[0].ShortBookList, got.ContractState[0].ShortBookList) + require.ElementsMatch(t, genesisState.ContractState[0].PairList, got.ContractState[0].PairList) + require.Equal(t, genesisState.ContractState[0].ContractInfo.CodeId, got.ContractState[0].ContractInfo.CodeId) + require.Equal(t, genesisState.ContractState[0].ContractInfo.ContractAddr, got.ContractState[0].ContractInfo.ContractAddr) + require.ElementsMatch(t, genesisState.ContractState[0].ContractInfo.Dependencies, got.ContractState[0].ContractInfo.Dependencies) + require.ElementsMatch(t, genesisState.ContractState[0].PriceList, got.ContractState[0].PriceList) + require.Equal(t, genesisState.ContractState[0].NextOrderId, got.ContractState[0].NextOrderId) + // this line is used by starport scaffolding # genesis/test/assert +} diff --git a/x/dex/gov.go b/x/dex/gov.go new file mode 100644 index 000000000..62fd39283 --- /dev/null +++ b/x/dex/gov.go @@ -0,0 +1,14 @@ +package dex + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func HandleAddAssetMetadataProposal(ctx sdk.Context, k *keeper.Keeper, p *types.AddAssetMetadataProposal) error { + for _, asset := range p.AssetList { + k.SetAssetMetadata(ctx, asset) + } + return nil +} diff --git a/x/dex/handler.go b/x/dex/handler.go new file mode 100644 index 000000000..623062b50 --- /dev/null +++ b/x/dex/handler.go @@ -0,0 +1,67 @@ +package dex + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" + + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// NewHandler ... +func NewHandler(k keeper.Keeper) sdk.Handler { + msgServer := msgserver.NewMsgServerImpl(k) + + return func(ctx sdk.Context, msg sdk.Msg) (*sdk.Result, error) { + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + switch msg := msg.(type) { + case *types.MsgPlaceOrders: + res, err := msgServer.PlaceOrders(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgCancelOrders: + res, err := msgServer.CancelOrders(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgRegisterContract: + res, err := msgServer.RegisterContract(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgRegisterPairs: + res, err := msgServer.RegisterPairs(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgUpdatePriceTickSize: + res, err := msgServer.UpdatePriceTickSize(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgUpdateQuantityTickSize: + res, err := msgServer.UpdateQuantityTickSize(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgUnregisterContract: + res, err := msgServer.UnregisterContract(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgContractDepositRent: + res, err := msgServer.ContractDepositRent(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + case *types.MsgUnsuspendContract: + res, err := msgServer.UnsuspendContract(sdk.WrapSDKContext(ctx), msg) + return sdk.WrapServiceResult(ctx, res, err) + // this line is used by starport scaffolding # 1 + default: + errMsg := fmt.Sprintf("unrecognized %s message type: %T", types.ModuleName, msg) + return nil, sdkerrors.Wrap(sdkerrors.ErrUnknownRequest, errMsg) + } + } +} + +func NewProposalHandler(k keeper.Keeper) govtypes.Handler { + return func(ctx sdk.Context, content govtypes.Content) error { + switch c := content.(type) { + case *types.AddAssetMetadataProposal: + return HandleAddAssetMetadataProposal(ctx, &k, c) + default: + return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized dex proposal content type: %T", c) + } + } +} diff --git a/x/dex/keeper/abci/end_block_cancel_orders.go b/x/dex/keeper/abci/end_block_cancel_orders.go new file mode 100644 index 000000000..8c471124c --- /dev/null +++ b/x/dex/keeper/abci/end_block_cancel_orders.go @@ -0,0 +1,45 @@ +package abci + +import ( + "context" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "go.opentelemetry.io/otel/attribute" + otrace "go.opentelemetry.io/otel/trace" +) + +func (w KeeperWrapper) HandleEBCancelOrders(ctx context.Context, sdkCtx sdk.Context, tracer *otrace.Tracer, contractAddr string, registeredPairs []types.Pair) error { + _, span := (*tracer).Start(ctx, "SudoCancelOrders") + span.SetAttributes(attribute.String("contractAddr", contractAddr)) + + typedContractAddr := types.ContractAddress(contractAddr) + msg := w.getCancelSudoMsg(sdkCtx, typedContractAddr, registeredPairs) + if len(msg.OrderCancellations.IdsToCancel) == 0 { + return nil + } + userProvidedGas := w.GetParams(sdkCtx).DefaultGasPerCancel * uint64(len(msg.OrderCancellations.IdsToCancel)) + if _, err := utils.CallContractSudo(sdkCtx, w.Keeper, contractAddr, msg, userProvidedGas); err != nil { + sdkCtx.Logger().Error(fmt.Sprintf("Error during cancellation: %s", err.Error())) + return err + } + span.End() + return nil +} + +func (w KeeperWrapper) getCancelSudoMsg(sdkCtx sdk.Context, typedContractAddr types.ContractAddress, registeredPairs []types.Pair) types.SudoOrderCancellationMsg { + idsToCancel := []uint64{} + for _, pair := range registeredPairs { + for _, cancel := range dexutils.GetMemState(sdkCtx.Context()).GetBlockCancels(sdkCtx, typedContractAddr, pair).Get() { + idsToCancel = append(idsToCancel, cancel.Id) + } + } + return types.SudoOrderCancellationMsg{ + OrderCancellations: types.OrderCancellationMsgDetails{ + IdsToCancel: idsToCancel, + }, + } +} diff --git a/x/dex/keeper/abci/end_block_deposit.go b/x/dex/keeper/abci/end_block_deposit.go new file mode 100644 index 000000000..c0216e482 --- /dev/null +++ b/x/dex/keeper/abci/end_block_deposit.go @@ -0,0 +1,58 @@ +package abci + +import ( + "context" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + seiutils "github.com/sei-protocol/sei-chain/utils" + "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "go.opentelemetry.io/otel/attribute" + otrace "go.opentelemetry.io/otel/trace" +) + +func (w KeeperWrapper) HandleEBDeposit(ctx context.Context, sdkCtx sdk.Context, tracer *otrace.Tracer, contractAddr string) error { + _, span := (*tracer).Start(ctx, "SudoDeposit") + span.SetAttributes(attribute.String("contractAddr", contractAddr)) + defer span.End() + + typedContractAddr := types.ContractAddress(contractAddr) + msg := w.GetDepositSudoMsg(sdkCtx, typedContractAddr) + if msg.IsEmpty() { + return nil + } + _, err := utils.CallContractSudo(sdkCtx, w.Keeper, contractAddr, msg, 0) // deposit + if err != nil { + sdkCtx.Logger().Error(fmt.Sprintf("Error during deposit: %s", err.Error())) + return err + } + + return nil +} + +func (w KeeperWrapper) GetDepositSudoMsg(ctx sdk.Context, typedContractAddr types.ContractAddress) types.SudoOrderPlacementMsg { + depositMemState := dexutils.GetMemState(ctx.Context()).GetDepositInfo(ctx, typedContractAddr).Get() + contractDepositInfo := seiutils.Map( + depositMemState, + func(d *types.DepositInfoEntry) types.ContractDepositInfo { return d.ToContractDepositInfo() }, + ) + escrowed := sdk.NewCoins() + for _, deposit := range depositMemState { + escrowed = escrowed.Add(sdk.NewCoin(deposit.Denom, deposit.Amount.TruncateInt())) + } + contractAddr, err := sdk.AccAddressFromBech32(string(typedContractAddr)) + if err != nil { + panic(err) + } + if err := w.BankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, contractAddr, escrowed); err != nil { + panic(err) + } + return types.SudoOrderPlacementMsg{ + OrderPlacements: types.OrderPlacementMsgDetails{ + Orders: []types.Order{}, + Deposits: contractDepositInfo, + }, + } +} diff --git a/x/dex/keeper/abci/end_block_place_orders.go b/x/dex/keeper/abci/end_block_place_orders.go new file mode 100644 index 000000000..8ab95c6e3 --- /dev/null +++ b/x/dex/keeper/abci/end_block_place_orders.go @@ -0,0 +1,83 @@ +package abci + +import ( + "context" + "encoding/json" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "go.opentelemetry.io/otel/attribute" + otrace "go.opentelemetry.io/otel/trace" +) + +// There is a limit on how many bytes can be passed to wasm VM in a single call, +// so we shouldn't bump this number unless there is an upgrade to wasm VM +const MaxOrdersPerSudoCall = 50000 + +func (w KeeperWrapper) HandleEBPlaceOrders(ctx context.Context, sdkCtx sdk.Context, tracer *otrace.Tracer, contractAddr string, registeredPairs []types.Pair) error { + _, span := (*tracer).Start(ctx, "SudoPlaceOrders") + span.SetAttributes(attribute.String("contractAddr", contractAddr)) + defer span.End() + + typedContractAddr := types.ContractAddress(contractAddr) + msgs := w.GetPlaceSudoMsg(sdkCtx, typedContractAddr, registeredPairs) + + responses := []types.SudoOrderPlacementResponse{} + + for _, msg := range msgs { + if msg.IsEmpty() { + continue + } + userProvidedGas := w.GetParams(sdkCtx).DefaultGasPerOrder * uint64(len(msg.OrderPlacements.Orders)) + data, err := utils.CallContractSudo(sdkCtx, w.Keeper, contractAddr, msg, userProvidedGas) + if err != nil { + sdkCtx.Logger().Error(fmt.Sprintf("Error during order placement: %s", err.Error())) + return err + } + response := types.SudoOrderPlacementResponse{} + if err := json.Unmarshal(data, &response); err != nil { + sdkCtx.Logger().Error("Failed to parse order placement response") + return err + } + if len(response.UnsuccessfulOrders) > 0 { + sdkCtx.Logger().Info(fmt.Sprintf("%s has %d unsuccessful order placements", contractAddr, len(response.UnsuccessfulOrders))) + } + responses = append(responses, response) + } + + for _, pair := range registeredPairs { + for _, response := range responses { + dexutils.GetMemState(sdkCtx.Context()).GetBlockOrders(sdkCtx, typedContractAddr, pair).MarkFailedToPlace(response.UnsuccessfulOrders) + } + } + return nil +} + +func (w KeeperWrapper) GetPlaceSudoMsg(ctx sdk.Context, typedContractAddr types.ContractAddress, registeredPairs []types.Pair) []types.SudoOrderPlacementMsg { + msgs := []types.SudoOrderPlacementMsg{} + contractOrderPlacements := []types.Order{} + for _, pair := range registeredPairs { + for _, order := range dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, typedContractAddr, pair).Get() { + contractOrderPlacements = append(contractOrderPlacements, *order) + if len(contractOrderPlacements) == MaxOrdersPerSudoCall { + msgs = append(msgs, types.SudoOrderPlacementMsg{ + OrderPlacements: types.OrderPlacementMsgDetails{ + Orders: contractOrderPlacements, + Deposits: []types.ContractDepositInfo{}, + }, + }) + contractOrderPlacements = []types.Order{} + } + } + } + msgs = append(msgs, types.SudoOrderPlacementMsg{ + OrderPlacements: types.OrderPlacementMsgDetails{ + Orders: contractOrderPlacements, + Deposits: []types.ContractDepositInfo{}, + }, + }) + return msgs +} diff --git a/x/dex/keeper/abci/end_block_place_orders_test.go b/x/dex/keeper/abci/end_block_place_orders_test.go new file mode 100644 index 000000000..556c3119c --- /dev/null +++ b/x/dex/keeper/abci/end_block_place_orders_test.go @@ -0,0 +1,67 @@ +package abci_test + +import ( + "context" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/keeper/abci" + "github.com/sei-protocol/sei-chain/x/dex/types" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + minttypes "github.com/sei-protocol/sei-chain/x/mint/types" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestGetPlaceSudoMsg(t *testing.T) { + pair := types.Pair{PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom} + keeper, ctx := keepertest.DexKeeper(t) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, keepertest.TestContract, pair).Add( + &types.Order{ + Id: 1, + Price: sdk.OneDec(), + Quantity: sdk.OneDec(), + PriceDenom: "USDC", + AssetDenom: "ATOM", + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"OPEN\",\"leverage\":\"1\"}", + }, + ) + wrapper := abci.KeeperWrapper{Keeper: keeper} + msgs := wrapper.GetPlaceSudoMsg(ctx, keepertest.TestContract, []types.Pair{pair}) + require.Equal(t, 1, len(msgs)) +} + +func TestGetDepositSudoMsg(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(1000000))) + bankkeeper := testApp.BankKeeper + bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts) + err := bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts) + require.Nil(t, err) + // this send would happen in msg server + err = bankkeeper.SendCoinsFromAccountToModule(ctx, testAccount, dextypes.ModuleName, amounts) + require.Nil(t, err) + keeper := testApp.DexKeeper + dexutils.GetMemState(ctx.Context()).GetDepositInfo(ctx, keepertest.TestContract).Add( + &types.DepositInfoEntry{ + Creator: testAccount.String(), + Denom: amounts[0].Denom, + Amount: sdk.NewDec(amounts[0].Amount.Int64()), + }, + ) + wrapper := abci.KeeperWrapper{Keeper: &keeper} + msgs := wrapper.GetDepositSudoMsg(ctx, keepertest.TestContract) + require.Equal(t, 1, len(msgs.OrderPlacements.Deposits)) + + contractAddr, _ := sdk.AccAddressFromBech32(keepertest.TestContract) + contractBalance := testApp.BankKeeper.GetBalance(ctx, contractAddr, "usei") + require.Equal(t, contractBalance.Amount.Int64(), int64(1000000)) +} diff --git a/x/dex/keeper/abci/keeper_wrapper.go b/x/dex/keeper/abci/keeper_wrapper.go new file mode 100644 index 000000000..ee20698ad --- /dev/null +++ b/x/dex/keeper/abci/keeper_wrapper.go @@ -0,0 +1,9 @@ +package abci + +import ( + "github.com/sei-protocol/sei-chain/x/dex/keeper" +) + +type KeeperWrapper struct { + *keeper.Keeper +} diff --git a/x/dex/keeper/asset_list.go b/x/dex/keeper/asset_list.go new file mode 100644 index 000000000..d62b39ed0 --- /dev/null +++ b/x/dex/keeper/asset_list.go @@ -0,0 +1,43 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k Keeper) SetAssetMetadata(ctx sdk.Context, assetMetadata types.AssetMetadata) { + store := ctx.KVStore(k.storeKey) + // Have one base denom for a canonical “display”. + // Even if asset exists already, overwrite the store with new metadata + // Asset list is decided through governance + b := k.Cdc.MustMarshal(&assetMetadata) + + store.Set(types.AssetListPrefix(assetMetadata.Metadata.Display), b) +} + +func (k Keeper) GetAssetMetadataByDenom(ctx sdk.Context, assetDenom string) (val types.AssetMetadata, found bool) { + store := ctx.KVStore(k.storeKey) + b := store.Get(types.AssetListPrefix(assetDenom)) + if b == nil { + return types.AssetMetadata{}, false + } + metadata := types.AssetMetadata{} + k.Cdc.MustUnmarshal(b, &metadata) + return metadata, true +} + +func (k Keeper) GetAllAssetMetadata(ctx sdk.Context) []types.AssetMetadata { + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, types.KeyPrefix(types.AssetListKey)) + + list := []types.AssetMetadata{} + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.AssetMetadata + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return list +} diff --git a/x/dex/keeper/asset_list_test.go b/x/dex/keeper/asset_list_test.go new file mode 100644 index 000000000..70348e6f3 --- /dev/null +++ b/x/dex/keeper/asset_list_test.go @@ -0,0 +1,35 @@ +package keeper_test + +import ( + "testing" + + 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 TestAssetListGet(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + item := keepertest.CreateAssetMetadata(keeper, ctx) + + var expected_asset_list []types.AssetMetadata + expected_asset_list = append(expected_asset_list, item) + + asset_list := keeper.GetAllAssetMetadata(ctx) + + // First test get all asset list + require.ElementsMatch(t, + nullify.Fill(expected_asset_list), + nullify.Fill(asset_list), + ) + + // Test not found asset Denom + _, found := keeper.GetAssetMetadataByDenom(ctx, "denomNotInAssetList123") + require.False(t, found) + + // Test get specific Denom + val, found := keeper.GetAssetMetadataByDenom(ctx, "axlusdc") + require.True(t, found) + require.Equal(t, item, val) +} diff --git a/x/dex/keeper/common.go b/x/dex/keeper/common.go new file mode 100644 index 000000000..f5ba9b961 --- /dev/null +++ b/x/dex/keeper/common.go @@ -0,0 +1,22 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (k Keeper) removeAllForPrefix(ctx sdk.Context, prefix []byte) { + store := ctx.KVStore(k.storeKey) + for _, key := range k.getAllKeysForPrefix(store, prefix) { + store.Delete(key) + } +} + +func (k Keeper) getAllKeysForPrefix(store sdk.KVStore, prefix []byte) [][]byte { + keys := [][]byte{} + iter := sdk.KVStorePrefixIterator(store, prefix) + defer iter.Close() + for ; iter.Valid(); iter.Next() { + keys = append(keys, iter.Key()) + } + return keys +} diff --git a/x/dex/keeper/contract.go b/x/dex/keeper/contract.go new file mode 100644 index 000000000..dd2596254 --- /dev/null +++ b/x/dex/keeper/contract.go @@ -0,0 +1,244 @@ +package keeper + +import ( + "errors" + "math" + "math/big" + "time" + + "github.com/cosmos/cosmos-sdk/store/prefix" + "github.com/cosmos/cosmos-sdk/telemetry" + sdk "github.com/cosmos/cosmos-sdk/types" + appparams "github.com/sei-protocol/sei-chain/app/params" + "github.com/sei-protocol/sei-chain/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +const ContractPrefixKey = "x-wasm-contract" + +func (k Keeper) SetContract(ctx sdk.Context, contract *types.ContractInfoV2) error { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + []byte(ContractPrefixKey), + ) + bz, err := contract.Marshal() + if err != nil { + return errors.New("failed to marshal contract info") + } + store.Set(types.ContractKey(contract.ContractAddr), bz) + return nil +} + +func (k Keeper) DeleteContract(ctx sdk.Context, contractAddr string) { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + []byte(ContractPrefixKey), + ) + key := types.ContractKey(contractAddr) + store.Delete(key) +} + +func (k Keeper) GetContract(ctx sdk.Context, contractAddr string) (types.ContractInfoV2, error) { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + []byte(ContractPrefixKey), + ) + key := types.ContractKey(contractAddr) + res := types.ContractInfoV2{} + if !store.Has(key) { + return res, types.ErrContractNotExists + } + if err := res.Unmarshal(store.Get(key)); err != nil { + return res, types.ErrParsingContractInfo + } + return res, nil +} + +func (k Keeper) GetContractWithoutGasCharge(ctx sdk.Context, contractAddr string) (types.ContractInfoV2, error) { + return k.GetContract(ctx.WithGasMeter(sdk.NewInfiniteGasMeterWithMultiplier(ctx)), contractAddr) +} + +func (k Keeper) GetContractGasLimit(ctx sdk.Context, contractAddr sdk.AccAddress) (uint64, error) { + bech32ContractAddr := contractAddr.String() + contract, err := k.GetContract(ctx, bech32ContractAddr) + if err != nil { + return 0, err + } + rentBalance := contract.RentBalance + gasPrice := k.GetParams(ctx).SudoCallGasPrice + if gasPrice.LTE(sdk.ZeroDec()) { + return 0, errors.New("invalid gas price: must be positive") + } + gasDec := sdk.NewDecFromBigInt(new(big.Int).SetUint64(rentBalance)).Quo(gasPrice) + if gasDec.GT(sdk.NewDecFromBigInt(new(big.Int).SetUint64(math.MaxUint64))) { + return math.MaxUint64, nil + } + return gasDec.TruncateInt().Uint64(), nil // round down +} + +func (k Keeper) GetAllContractInfo(ctx sdk.Context) []types.ContractInfoV2 { + store := prefix.NewStore(ctx.KVStore(k.storeKey), []byte(ContractPrefixKey)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + list := []types.ContractInfoV2{} + for ; iterator.Valid(); iterator.Next() { + contract := types.ContractInfoV2{} + if err := contract.Unmarshal(iterator.Value()); err == nil { + list = append(list, contract) + } + } + + return list +} + +// Reduce `RentBalance` of a contract if `userProvidedGas` cannot cover `gasUsed` +func (k Keeper) ChargeRentForGas(ctx sdk.Context, contractAddr string, gasUsed uint64, gasAllowance uint64) error { + if gasUsed <= gasAllowance { + // Allowance can fully cover the consumed gas. Doing nothing + return nil + } + gasUsed -= gasAllowance + contract, err := k.GetContract(ctx, contractAddr) + if err != nil { + return err + } + params := k.GetParams(ctx) + gasFeeDec := sdk.NewDecFromBigInt(new(big.Int).SetUint64(gasUsed)).Mul(params.SudoCallGasPrice) + if gasFeeDec.GT(sdk.NewDecFromBigInt(new(big.Int).SetUint64(math.MaxUint64))) { + gasFeeDec = sdk.NewDecFromBigInt(new(big.Int).SetUint64(math.MaxUint64)) + } + gasFee := gasFeeDec.RoundInt().Uint64() + if gasFee > contract.RentBalance { + contract.RentBalance = 0 + if err := k.SetContract(ctx, &contract); err != nil { + return err + } + return types.ErrInsufficientRent + } + contract.RentBalance -= gasFee + return k.SetContract(ctx, &contract) +} + +func (k Keeper) GetRentsForContracts(ctx sdk.Context, contractAddrs []string) map[string]uint64 { + res := map[string]uint64{} + for _, contractAddr := range contractAddrs { + if contract, err := k.GetContract(ctx, contractAddr); err == nil { + res[contractAddr] = contract.RentBalance + } + } + return res +} + +// Unregistrate and refund the creator +func (k Keeper) DoUnregisterContractWithRefund(ctx sdk.Context, contract types.ContractInfoV2) error { + k.DoUnregisterContract(ctx, contract) + creatorAddr, _ := sdk.AccAddressFromBech32(contract.Creator) + return k.BankKeeper.SendCoins(ctx, k.AccountKeeper.GetModuleAddress(types.ModuleName), creatorAddr, sdk.NewCoins(sdk.NewCoin(appparams.BaseCoinUnit, sdk.NewIntFromBigInt(new(big.Int).SetUint64(contract.RentBalance))))) +} + +// Contract unregistration will remove all orderbook data stored for the contract +func (k Keeper) DoUnregisterContract(ctx sdk.Context, contract types.ContractInfoV2) { + k.DeleteContract(ctx, contract.ContractAddr) + k.ClearDependenciesForContract(ctx, contract) + k.RemoveAllLongBooksForContract(ctx, contract.ContractAddr) + k.RemoveAllShortBooksForContract(ctx, contract.ContractAddr) + k.RemoveAllPricesForContract(ctx, contract.ContractAddr) + k.DeleteMatchResultState(ctx, contract.ContractAddr) + k.DeleteNextOrderID(ctx, contract.ContractAddr) + k.DeleteAllRegisteredPairsForContract(ctx, contract.ContractAddr) +} + +func (k Keeper) SuspendContract(ctx sdk.Context, contractAddress string, reason string) error { + contract, err := k.GetContract(ctx, contractAddress) + if err != nil { + return err + } + contract.Suspended = true + contract.SuspensionReason = reason + return k.SetContract(ctx, &contract) +} + +func (k Keeper) ClearDependenciesForContract(ctx sdk.Context, removedContract types.ContractInfoV2) { + // handle upstreams + allContracts := k.GetAllContractInfo(ctx) + for _, c := range allContracts { + contract := c + dependsOnRemovedContract := false + for _, dep := range contract.Dependencies { + if dep.Dependency == removedContract.ContractAddr { + dependsOnRemovedContract = true + break + } + } + if !dependsOnRemovedContract { + continue + } + contract.Dependencies = utils.Filter(contract.Dependencies, func(dep *types.ContractDependencyInfo) bool { return dep.Dependency != removedContract.ContractAddr }) + _ = k.SetContract(ctx, &contract) + } + + // handle downstreams + allContractsMap := map[string]types.ContractInfoV2{} + for _, contract := range allContracts { + allContractsMap[contract.ContractAddr] = contract + } + for _, dep := range removedContract.Dependencies { + if dependedContract, ok := allContractsMap[dep.Dependency]; ok { + dependedContract.NumIncomingDependencies-- + _ = k.SetContract(ctx, &dependedContract) + } + + if dep.ImmediateElderSibling != "" { + if immediateElderSibling, ok := allContractsMap[dep.ImmediateElderSibling]; ok { + newDependencies := []*types.ContractDependencyInfo{} + for _, elderSiblingDep := range immediateElderSibling.Dependencies { + if elderSiblingDep.Dependency != dep.Dependency { + newDependencies = append(newDependencies, elderSiblingDep) + } else { + newDependencies = append(newDependencies, &types.ContractDependencyInfo{ + Dependency: elderSiblingDep.Dependency, + ImmediateElderSibling: elderSiblingDep.ImmediateElderSibling, + ImmediateYoungerSibling: dep.ImmediateYoungerSibling, + }) + } + } + immediateElderSibling.Dependencies = newDependencies + _ = k.SetContract(ctx, &immediateElderSibling) + } + } + + if dep.ImmediateYoungerSibling != "" { + if immediateYoungerSibling, ok := allContractsMap[dep.ImmediateYoungerSibling]; ok { + newDependencies := []*types.ContractDependencyInfo{} + for _, youngerSiblingDep := range immediateYoungerSibling.Dependencies { + if youngerSiblingDep.Dependency != dep.Dependency { + newDependencies = append(newDependencies, youngerSiblingDep) + } else { + newDependencies = append(newDependencies, &types.ContractDependencyInfo{ + Dependency: youngerSiblingDep.Dependency, + ImmediateElderSibling: dep.ImmediateElderSibling, + ImmediateYoungerSibling: youngerSiblingDep.ImmediateYoungerSibling, + }) + } + } + immediateYoungerSibling.Dependencies = newDependencies + _ = k.SetContract(ctx, &immediateYoungerSibling) + } + } + } +} + +func (k Keeper) GetAllProcessableContractInfo(ctx sdk.Context) []types.ContractInfoV2 { + // Do not process any contract that has zero rent balance, suspended, or not require matching + defer telemetry.MeasureSince(time.Now(), types.ModuleName, "get_all_contract_info") + allRegisteredContracts := k.GetAllContractInfo(ctx) + validContracts := utils.Filter(allRegisteredContracts, func(c types.ContractInfoV2) bool { + return c.NeedOrderMatching && !c.Suspended && c.RentBalance > k.GetMinProcessableRent(ctx) + }) + telemetry.SetGauge(float32(len(allRegisteredContracts)), types.ModuleName, "num_of_registered_contracts") + telemetry.SetGauge(float32(len(validContracts)), types.ModuleName, "num_of_valid_contracts") + telemetry.SetGauge(float32(len(allRegisteredContracts)-len(validContracts)), types.ModuleName, "num_of_zero_balance_contracts") + return validContracts +} diff --git a/x/dex/keeper/contract_test.go b/x/dex/keeper/contract_test.go new file mode 100644 index 000000000..8dae31c24 --- /dev/null +++ b/x/dex/keeper/contract_test.go @@ -0,0 +1,368 @@ +package keeper_test + +import ( + "math" + "testing" + + "github.com/cosmos/cosmos-sdk/store/prefix" + + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestChargeRentForGas(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keeper.SetParams(ctx, types.Params{SudoCallGasPrice: sdk.NewDecWithPrec(1, 1), PriceSnapshotRetention: 1}) + err := keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + CodeId: 1, + RentBalance: 1000000, + }) + require.Nil(t, err) + err = keeper.ChargeRentForGas(ctx, keepertest.TestContract, 5000000, 0) + require.Nil(t, err) + contract, err := keeper.GetContract(ctx, keepertest.TestContract) + require.Nil(t, err) + require.Equal(t, uint64(500000), contract.RentBalance) + err = keeper.ChargeRentForGas(ctx, keepertest.TestContract, 6000000, 0) + require.NotNil(t, err) + contract, err = keeper.GetContract(ctx, keepertest.TestContract) + require.Nil(t, err) + require.Equal(t, uint64(0), contract.RentBalance) + err = keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + CodeId: 1, + RentBalance: 1000000, + }) + require.Nil(t, err) + err = keeper.ChargeRentForGas(ctx, keepertest.TestContract, 5000000, 4000000) + require.Nil(t, err) + contract, err = keeper.GetContract(ctx, keepertest.TestContract) + require.Nil(t, err) + require.Equal(t, uint64(900000), contract.RentBalance) + err = keeper.ChargeRentForGas(ctx, keepertest.TestContract, 5000000, 6000000) + require.Nil(t, err) + contract, err = keeper.GetContract(ctx, keepertest.TestContract) + require.Nil(t, err) + require.Equal(t, uint64(900000), contract.RentBalance) + + // delete contract + keeper.DeleteContract(ctx, keepertest.TestContract) + _, err = keeper.GetContract(ctx, keepertest.TestContract) + require.NotNil(t, err) +} + +func TestGetContractInfo(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keeper.SetParams(ctx, types.Params{SudoCallGasPrice: sdk.NewDecWithPrec(1, 1), PriceSnapshotRetention: 1}) + keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + CodeId: 1, + RentBalance: 1000000, + }) + // Successfully get a contract + contract, err := keeper.GetContract(ctx, keepertest.TestContract) + require.Equal(t, uint64(1000000), contract.RentBalance) + require.Equal(t, uint64(1), contract.CodeId) + require.Equal(t, keepertest.TestAccount, contract.Creator) + + // Getting a non exist contract should throw error for contract not exist + _, err = keeper.GetContract(ctx, keepertest.TestContract2) + require.Error(t, err) + require.Equal(t, err, types.ErrContractNotExists) + + // Getting a corrupted record should throw error for unable to parse + store := prefix.NewStore( + ctx.KVStore(keeper.GetStoreKey()), + []byte("x-wasm-contract"), + ) + bz := []byte("bad_contract") + store.Set(types.ContractKey(keepertest.TestContract), bz) + _, err = keeper.GetContract(ctx, keepertest.TestContract) + require.Error(t, err) + require.Equal(t, err, types.ErrParsingContractInfo) +} + +func TestGetAllContractInfo(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keeper.SetParams(ctx, types.Params{SudoCallGasPrice: sdk.NewDecWithPrec(1, 1), PriceSnapshotRetention: 1}) + keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + CodeId: 1, + RentBalance: 1000000, + }) + keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount2, + ContractAddr: keepertest.TestContract2, + CodeId: 2, + RentBalance: 1000000, + }) + contracts := keeper.GetAllContractInfo(ctx) + require.Equal(t, uint64(1000000), contracts[0].RentBalance) + require.Equal(t, uint64(1000000), contracts[1].RentBalance) + require.Equal(t, uint64(1), contracts[0].CodeId) + require.Equal(t, uint64(2), contracts[1].CodeId) + require.Equal(t, keepertest.TestAccount, contracts[0].Creator) + require.Equal(t, keepertest.TestContract, contracts[0].ContractAddr) + require.Equal(t, keepertest.TestAccount2, contracts[1].Creator) + require.Equal(t, keepertest.TestContract2, contracts[1].ContractAddr) +} + +func TestGetContractGasLimit(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + contractAddr := sdk.MustAccAddressFromBech32("sei1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsgshtdj") + keeper.SetParams(ctx, types.Params{SudoCallGasPrice: sdk.NewDecWithPrec(1, 1), PriceSnapshotRetention: 1}) + keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: "sei1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsgshtdj", + CodeId: 1, + RentBalance: 1000000, + }) + gasLimit, err := keeper.GetContractGasLimit(ctx, contractAddr) + require.Nil(t, err) + require.Equal(t, uint64(10000000), gasLimit) + + params := keeper.GetParams(ctx) + params.SudoCallGasPrice = sdk.NewDecWithPrec(1, 1) // 0.1 + keeper.SetParams(ctx, params) + keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: "sei1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsgshtdj", + CodeId: 1, + RentBalance: math.MaxUint64, + }) + gasLimit, err = keeper.GetContractGasLimit(ctx, contractAddr) + require.Nil(t, err) + // max uint64 / 0.1 would cause overflow so we cap it at max + require.Equal(t, uint64(math.MaxUint64), gasLimit) +} + +func TestGetRentsForContracts(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + addr := "sei1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsgshtdj" + require.Equal(t, 0, len(keeper.GetRentsForContracts(ctx, []string{addr}))) + + keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: addr, + CodeId: 1, + RentBalance: 100, + }) + require.Equal(t, map[string]uint64{addr: uint64(100)}, keeper.GetRentsForContracts(ctx, []string{addr})) +} + +func TestClearDependenciesForContract(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + + // no dependency whatsoever + contract := types.ContractInfoV2{ + ContractAddr: keepertest.TestContract, + } + keeper.SetContract(ctx, &contract) + require.NotPanics(t, func() { keeper.ClearDependenciesForContract(ctx, contract) }) + + // has upstreams + contract = types.ContractInfoV2{ + ContractAddr: keepertest.TestContract, + NumIncomingDependencies: 2, + } + keptContract := types.ContractInfoV2{ + ContractAddr: "sei1yum4v0v5l92jkxn8xpn9mjg7wuldk784ctg424ue8gqvdp88qzlqt6zc4h", + NumIncomingDependencies: 2, + } + upA := types.ContractInfoV2{ + ContractAddr: "sei105y5ssrsr8p8erkteagrguea6wcdgehlaamfup4lhrlm0y6eyhdsckcxdh", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: keepertest.TestContract, + ImmediateYoungerSibling: "sei1y8ghk8q8d2rswrf3gv7hv2lfsewu8tvp6ysnlkzspu7k0aqkthdqwdqvk0", + }, + { + Dependency: "sei1yum4v0v5l92jkxn8xpn9mjg7wuldk784ctg424ue8gqvdp88qzlqt6zc4h", + ImmediateYoungerSibling: "sei193dzcmy7lwuj4eda3zpwwt9ejal00xva0vawcvhgsyyp5cfh6jyqj2vsuv", + }, + }, + } + upB := types.ContractInfoV2{ + ContractAddr: "sei1y8ghk8q8d2rswrf3gv7hv2lfsewu8tvp6ysnlkzspu7k0aqkthdqwdqvk0", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: keepertest.TestContract, + ImmediateElderSibling: "sei105y5ssrsr8p8erkteagrguea6wcdgehlaamfup4lhrlm0y6eyhdsckcxdh", + }, + }, + } + upC := types.ContractInfoV2{ + ContractAddr: "sei193dzcmy7lwuj4eda3zpwwt9ejal00xva0vawcvhgsyyp5cfh6jyqj2vsuv", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei1yum4v0v5l92jkxn8xpn9mjg7wuldk784ctg424ue8gqvdp88qzlqt6zc4h", + ImmediateElderSibling: "sei105y5ssrsr8p8erkteagrguea6wcdgehlaamfup4lhrlm0y6eyhdsckcxdh", + }, + }, + } + keeper.SetContract(ctx, &contract) + keeper.SetContract(ctx, &keptContract) + keeper.SetContract(ctx, &upA) + keeper.SetContract(ctx, &upB) + keeper.SetContract(ctx, &upC) + require.NotPanics(t, func() { keeper.ClearDependenciesForContract(ctx, contract) }) + upA, err := keeper.GetContract(ctx, upA.ContractAddr) + require.Nil(t, err) + require.Equal(t, 1, len(upA.Dependencies)) + upB, err = keeper.GetContract(ctx, upB.ContractAddr) + require.Nil(t, err) + require.Equal(t, 0, len(upB.Dependencies)) + upC, err = keeper.GetContract(ctx, upC.ContractAddr) + require.Nil(t, err) + require.Equal(t, 1, len(upC.Dependencies)) + + // has downstreams + contract = types.ContractInfoV2{ + ContractAddr: keepertest.TestContract, + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei1ehyucudueas79h0zwufcnxtv7s2sfmwc6rt0v0hzczdgvyr3p56qhprg6n", + ImmediateElderSibling: "sei1uyprmp0lu8w8z8kwxp7mxanrtrgn4lp7j557pxe4v8sczzdzl7ysk832hh", + ImmediateYoungerSibling: "sei1yum4v0v5l92jkxn8xpn9mjg7wuldk784ctg424ue8gqvdp88qzlqt6zc4h", + }, { + Dependency: "sei1n23ymwg2y7m55x5vwf2qk0als9cr592q4uc5de08c6qmaeryet4qye4w77", + }, + }, + } + keptContractA := types.ContractInfoV2{ + ContractAddr: "sei1yum4v0v5l92jkxn8xpn9mjg7wuldk784ctg424ue8gqvdp88qzlqt6zc4h", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei1ehyucudueas79h0zwufcnxtv7s2sfmwc6rt0v0hzczdgvyr3p56qhprg6n", + ImmediateElderSibling: keepertest.TestContract, + }, + }, + } + keptContractB := types.ContractInfoV2{ + ContractAddr: "sei1uyprmp0lu8w8z8kwxp7mxanrtrgn4lp7j557pxe4v8sczzdzl7ysk832hh", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei1ehyucudueas79h0zwufcnxtv7s2sfmwc6rt0v0hzczdgvyr3p56qhprg6n", + ImmediateYoungerSibling: keepertest.TestContract, + }, + }, + } + downA := types.ContractInfoV2{ + ContractAddr: "sei1ehyucudueas79h0zwufcnxtv7s2sfmwc6rt0v0hzczdgvyr3p56qhprg6n", + NumIncomingDependencies: 3, + } + downB := types.ContractInfoV2{ + ContractAddr: "sei1n23ymwg2y7m55x5vwf2qk0als9cr592q4uc5de08c6qmaeryet4qye4w77", + NumIncomingDependencies: 1, + } + keeper.SetContract(ctx, &contract) + keeper.SetContract(ctx, &keptContractA) + keeper.SetContract(ctx, &keptContractB) + keeper.SetContract(ctx, &downA) + keeper.SetContract(ctx, &downB) + + require.NotPanics(t, func() { keeper.ClearDependenciesForContract(ctx, contract) }) + keptContractA, err = keeper.GetContract(ctx, keptContractA.ContractAddr) + require.Nil(t, err) + require.Equal(t, types.ContractInfoV2{ + ContractAddr: "sei1yum4v0v5l92jkxn8xpn9mjg7wuldk784ctg424ue8gqvdp88qzlqt6zc4h", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei1ehyucudueas79h0zwufcnxtv7s2sfmwc6rt0v0hzczdgvyr3p56qhprg6n", + ImmediateElderSibling: "sei1uyprmp0lu8w8z8kwxp7mxanrtrgn4lp7j557pxe4v8sczzdzl7ysk832hh", + }, + }, + }, keptContractA) + keptContractB, err = keeper.GetContract(ctx, keptContractB.ContractAddr) + require.Nil(t, err) + require.Equal(t, types.ContractInfoV2{ + ContractAddr: "sei1uyprmp0lu8w8z8kwxp7mxanrtrgn4lp7j557pxe4v8sczzdzl7ysk832hh", + Dependencies: []*types.ContractDependencyInfo{ + { + Dependency: "sei1ehyucudueas79h0zwufcnxtv7s2sfmwc6rt0v0hzczdgvyr3p56qhprg6n", + ImmediateYoungerSibling: "sei1yum4v0v5l92jkxn8xpn9mjg7wuldk784ctg424ue8gqvdp88qzlqt6zc4h", + }, + }, + }, keptContractB) + downA, err = keeper.GetContract(ctx, downA.ContractAddr) + require.Nil(t, err) + require.Equal(t, int64(2), downA.NumIncomingDependencies) + downB, err = keeper.GetContract(ctx, downB.ContractAddr) + require.Nil(t, err) + require.Equal(t, int64(0), downB.NumIncomingDependencies) +} + +func TestGetContractWithoutGasCharge(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + _ = keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + CodeId: 1, + RentBalance: 1000000, + }) + // regular gas meter case + ctx = ctx.WithGasMeter(sdk.NewGasMeterWithMultiplier(ctx, 10000)) + contract, err := keeper.GetContractWithoutGasCharge(ctx, keepertest.TestContract) + require.Nil(t, err) + require.Equal(t, keepertest.TestContract, contract.ContractAddr) + require.Equal(t, uint64(0), ctx.GasMeter().GasConsumed()) + require.Equal(t, uint64(10000), ctx.GasMeter().Limit()) + + // regular gas meter out of gas case + ctx = ctx.WithGasMeter(sdk.NewGasMeterWithMultiplier(ctx, 1)) + contract, err = keeper.GetContractWithoutGasCharge(ctx, keepertest.TestContract) + require.Nil(t, err) + require.Equal(t, keepertest.TestContract, contract.ContractAddr) + require.Equal(t, uint64(0), ctx.GasMeter().GasConsumed()) + require.Equal(t, uint64(1), ctx.GasMeter().Limit()) + + // infinite gas meter case + ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeterWithMultiplier(ctx)) + contract, err = keeper.GetContractWithoutGasCharge(ctx, keepertest.TestContract) + require.Nil(t, err) + require.Equal(t, keepertest.TestContract, contract.ContractAddr) + require.Equal(t, uint64(0), ctx.GasMeter().GasConsumed()) + require.Equal(t, uint64(0), ctx.GasMeter().Limit()) +} + +func TestGetAllProcessableContractInfo(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + require.Greater(t, keeper.GetMinProcessableRent(ctx), uint64(0)) + + goodContract := types.ContractInfoV2{ + ContractAddr: "sei1avny5w9rcj7lmqmse8kukg2edvq4adqk8vlf58", + NeedOrderMatching: true, + RentBalance: keeper.GetMinProcessableRent(ctx) + 1, + } + noMatchingContract := types.ContractInfoV2{ + ContractAddr: "sei1fww2a30qc4sh25crhugcclaq2supxkpxeyz9lr", + NeedOrderMatching: false, + RentBalance: keeper.GetMinProcessableRent(ctx) + 1, + } + suspendedContract := types.ContractInfoV2{ + ContractAddr: "sei1hh95z3a5vk560khjnnkd3en8r0hu063mw64jzd", + NeedOrderMatching: true, + RentBalance: keeper.GetMinProcessableRent(ctx) + 1, + Suspended: true, + } + outOfRentContract := types.ContractInfoV2{ + ContractAddr: "sei1v2ye9tnmzwx5983emm00j0c7tyxqu855ktxw5l", + NeedOrderMatching: true, + RentBalance: keeper.GetMinProcessableRent(ctx) - 1, + } + require.NoError(t, keeper.SetContract(ctx, &goodContract)) + require.NoError(t, keeper.SetContract(ctx, &noMatchingContract)) + require.NoError(t, keeper.SetContract(ctx, &suspendedContract)) + require.NoError(t, keeper.SetContract(ctx, &outOfRentContract)) + + processableContracts := keeper.GetAllProcessableContractInfo(ctx) + require.Equal(t, 1, len(processableContracts)) + require.Equal(t, "sei1avny5w9rcj7lmqmse8kukg2edvq4adqk8vlf58", processableContracts[0].ContractAddr) +} diff --git a/x/dex/keeper/epoch.go b/x/dex/keeper/epoch.go new file mode 100644 index 000000000..33f8012af --- /dev/null +++ b/x/dex/keeper/epoch.go @@ -0,0 +1,26 @@ +package keeper + +import ( + "encoding/binary" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const EpochKey = "epoch" + +func (k Keeper) SetEpoch(ctx sdk.Context, epoch uint64) { + store := ctx.KVStore(k.storeKey) + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, epoch) + store.Set([]byte(EpochKey), bz) + ctx.Logger().Info(fmt.Sprintf("Current epoch %d", epoch)) +} + +func (k Keeper) IsNewEpoch(ctx sdk.Context) (bool, uint64) { + store := ctx.KVStore(k.storeKey) + b := store.Get([]byte(EpochKey)) + lastEpoch := binary.BigEndian.Uint64(b) + currentEpoch := k.EpochKeeper.GetEpoch(ctx).CurrentEpoch + return currentEpoch > lastEpoch, currentEpoch +} diff --git a/x/dex/keeper/keeper.go b/x/dex/keeper/keeper.go new file mode 100644 index 000000000..f89bf7ded --- /dev/null +++ b/x/dex/keeper/keeper.go @@ -0,0 +1,78 @@ +package keeper + +import ( + "fmt" + + "github.com/tendermint/tendermint/libs/log" + + "github.com/CosmWasm/wasmd/x/wasm" + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" + epochkeeper "github.com/sei-protocol/sei-chain/x/epoch/keeper" +) + +type ( + Keeper struct { + Cdc codec.BinaryCodec + storeKey sdk.StoreKey + memKey sdk.StoreKey + Paramstore paramtypes.Subspace + AccountKeeper authkeeper.AccountKeeper + EpochKeeper epochkeeper.Keeper + BankKeeper bankkeeper.Keeper + WasmKeeper wasm.Keeper + MemState *dexcache.MemState + } +) + +func NewKeeper( + cdc codec.BinaryCodec, + storeKey, + memKey sdk.StoreKey, + ps paramtypes.Subspace, + epochKeeper epochkeeper.Keeper, + bankKeeper bankkeeper.Keeper, + accountKeeper authkeeper.AccountKeeper, +) *Keeper { + // set KeyTable if it has not already been set + if !ps.HasKeyTable() { + ps = ps.WithKeyTable(types.ParamKeyTable()) + } + return &Keeper{ + Cdc: cdc, + storeKey: storeKey, + memKey: memKey, + Paramstore: ps, + EpochKeeper: epochKeeper, + BankKeeper: bankKeeper, + AccountKeeper: accountKeeper, + MemState: dexcache.NewMemState(memKey), + } +} + +func (k Keeper) Logger(ctx sdk.Context) log.Logger { + return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName)) +} + +func (k Keeper) GetStoreKey() sdk.StoreKey { + return k.storeKey +} + +func (k Keeper) GetMemStoreKey() sdk.StoreKey { + return k.memKey +} + +func (k *Keeper) SetWasmKeeper(wasmKeeper *wasm.Keeper) { + k.WasmKeeper = *wasmKeeper +} + +func (k Keeper) CreateModuleAccount(ctx sdk.Context) { + moduleAcc := authtypes.NewEmptyModuleAccount(types.ModuleName, authtypes.Burner) + k.AccountKeeper.SetModuleAccount(ctx, moduleAcc) +} diff --git a/x/dex/keeper/long_book.go b/x/dex/keeper/long_book.go new file mode 100644 index 000000000..d8f7e8c2f --- /dev/null +++ b/x/dex/keeper/long_book.go @@ -0,0 +1,184 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" +) + +// SetLongBook set a specific longBook in the store +func (k Keeper) SetLongBook(ctx sdk.Context, contractAddr string, longBook types.LongBook) { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + types.OrderBookPrefix( + true, contractAddr, longBook.Entry.PriceDenom, longBook.Entry.AssetDenom, + ), + ) + b := k.Cdc.MustMarshal(&longBook) + store.Set(GetKeyForLongBook(longBook), b) +} + +func (k Keeper) SetLongOrderBookEntry(ctx sdk.Context, contractAddr string, longBook types.OrderBookEntry) { + k.SetLongBook(ctx, contractAddr, *longBook.(*types.LongBook)) +} + +func (k Keeper) GetLongBookByPrice(ctx sdk.Context, contractAddr string, price sdk.Dec, priceDenom string, assetDenom string) (val types.LongBook, found bool) { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + types.OrderBookPrefix( + true, contractAddr, priceDenom, assetDenom, + ), + ) + b := store.Get(GetKeyForPrice(price)) + if b == nil { + return val, false + } + k.Cdc.MustUnmarshal(b, &val) + return val, true +} + +func (k Keeper) GetLongOrderBookEntryByPrice(ctx sdk.Context, contractAddr string, price sdk.Dec, priceDenom string, assetDenom string) (types.OrderBookEntry, bool) { + entry, found := k.GetLongBookByPrice(ctx, contractAddr, price, priceDenom, assetDenom) + return &entry, found +} + +func (k Keeper) RemoveLongBookByPrice(ctx sdk.Context, contractAddr string, price sdk.Dec, priceDenom string, assetDenom string) { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + types.OrderBookPrefix( + true, contractAddr, priceDenom, assetDenom, + ), + ) + store.Delete(GetKeyForPrice(price)) +} + +// GetAllLongBook returns all longBook +func (k Keeper) GetAllLongBook(ctx sdk.Context, contractAddr string) (list []types.LongBook) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ContractKeyPrefix(types.LongBookKey, contractAddr)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.LongBook + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return +} + +func (k Keeper) GetAllLongBookForPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string) (list []types.OrderBookEntry) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(true, contractAddr, priceDenom, assetDenom)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.LongBook + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, &val) + } + + return +} + +func (k Keeper) GetTopNLongBooksForPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, n int) (list []types.OrderBookEntry) { + if n == 0 { + return + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(true, contractAddr, priceDenom, assetDenom)) + iterator := sdk.KVStoreReversePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.LongBook + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, &val) + if len(list) == n { + break + } + } + + return +} + +// Load the first (up to) N long book entries whose price are smaller than the specified limit +// in reverse sorted order. +// Parameters: +// +// n: the largest number of entries to load +// startExclusive: the price limit +func (k Keeper) GetTopNLongBooksForPairStarting(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, n int, startExclusive sdk.Dec) (list []types.OrderBookEntry) { + if n == 0 { + return + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(true, contractAddr, priceDenom, assetDenom)) + iterator := sdk.KVStoreReversePrefixIterator(store, []byte{}) + + defer iterator.Close() + + // Fast-forward + // TODO: add iterator interface that allows starting at a certain subkey under prefix + for ; iterator.Valid(); iterator.Next() { + key := dexutils.BytesToDec(iterator.Key()) + if key.LT(startExclusive) { + break + } + } + + for ; iterator.Valid(); iterator.Next() { + var val types.LongBook + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, &val) + if len(list) == n { + break + } + } + + return +} + +func (k Keeper) GetAllLongBookForPairPaginated(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, page *query.PageRequest) (list []types.LongBook, pageRes *query.PageResponse, err error) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(true, contractAddr, priceDenom, assetDenom)) + + pageRes, err = query.Paginate(store, page, func(key []byte, value []byte) error { + var longBook types.LongBook + if err := k.Cdc.Unmarshal(value, &longBook); err != nil { + return err + } + + list = append(list, longBook) + return nil + }) + + return +} + +func (k Keeper) GetLongAllocationForOrderID(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, price sdk.Dec, orderID uint64) (*types.Allocation, bool) { + orderBook, found := k.GetLongBookByPrice(ctx, contractAddr, price, priceDenom, assetDenom) + if !found { + return nil, false + } + for _, allocation := range orderBook.Entry.Allocations { + if allocation.OrderId == orderID { + return allocation, true + } + } + return nil, false +} + +func (k Keeper) RemoveAllLongBooksForContract(ctx sdk.Context, contractAddr string) { + k.removeAllForPrefix(ctx, types.OrderBookContractPrefix(true, contractAddr)) +} + +func GetKeyForLongBook(longBook types.LongBook) []byte { + return GetKeyForPrice(longBook.Entry.Price) +} + +func GetKeyForPrice(price sdk.Dec) []byte { + return dexutils.DecToBigEndian(price) +} diff --git a/x/dex/keeper/long_book_test.go b/x/dex/keeper/long_book_test.go new file mode 100644 index 000000000..a515cf0b4 --- /dev/null +++ b/x/dex/keeper/long_book_test.go @@ -0,0 +1,92 @@ +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/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestLongBookGet(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + items := keepertest.CreateNLongBook(keeper, ctx, 10) + for i, item := range items { + got, found := keeper.GetLongBookByPrice(ctx, keepertest.TestContract, sdk.NewDec(int64(i)), keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, + nullify.Fill(&item), + nullify.Fill(&got), + ) + } +} + +func TestLongBookRemove(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + items := keepertest.CreateNLongBook(keeper, ctx, 10) + for i := range items { + keeper.RemoveLongBookByPrice(ctx, keepertest.TestContract, sdk.NewDec(int64(i)), keepertest.TestPriceDenom, keepertest.TestAssetDenom) + _, found := keeper.GetLongBookByPrice(ctx, keepertest.TestContract, sdk.NewDec(int64(i)), keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.False(t, found) + } +} + +func TestLongBookGetAll(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + items := keepertest.CreateNLongBook(keeper, ctx, 10) + require.ElementsMatch(t, + nullify.Fill(items), + nullify.Fill(keeper.GetAllLongBook(ctx, keepertest.TestContract)), + ) +} + +func TestGetTopNLongBooksForPair(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + prices := []string{"9.99", "0.001", "90.0", "10", "10.01", "9.9", "9.0", "1"} + for _, price := range prices { + keeper.SetLongBook(ctx, keepertest.TestContract, types.LongBook{ + Price: sdk.MustNewDecFromStr(price), + Entry: &types.OrderEntry{ + Price: sdk.MustNewDecFromStr(price), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + }) + } + expected := []sdk.Dec{ + sdk.MustNewDecFromStr("90.0"), + sdk.MustNewDecFromStr("10.01"), + sdk.MustNewDecFromStr("10"), + sdk.MustNewDecFromStr("9.99"), + sdk.MustNewDecFromStr("9.9"), + sdk.MustNewDecFromStr("9.0"), + sdk.MustNewDecFromStr("1"), + sdk.MustNewDecFromStr("0.001"), + } + loaded := keeper.GetTopNLongBooksForPair(ctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom, 10) + require.Equal(t, expected, utils.Map(loaded, func(b types.OrderBookEntry) sdk.Dec { return b.GetPrice() })) +} + +func TestGetTopNLongBooksForPairStarting(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + prices := []string{"9.99", "0.001", "90.0", "10", "10.01", "9.9", "9.0", "1"} + for _, price := range prices { + keeper.SetLongBook(ctx, keepertest.TestContract, types.LongBook{ + Price: sdk.MustNewDecFromStr(price), + Entry: &types.OrderEntry{ + Price: sdk.MustNewDecFromStr(price), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + }) + } + expected := []sdk.Dec{ + sdk.MustNewDecFromStr("9.99"), + sdk.MustNewDecFromStr("9.9"), + } + loaded := keeper.GetTopNLongBooksForPairStarting(ctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom, 2, sdk.MustNewDecFromStr("9.999")) + require.Equal(t, expected, utils.Map(loaded, func(b types.OrderBookEntry) sdk.Dec { return b.GetPrice() })) +} diff --git a/x/dex/keeper/match_result.go b/x/dex/keeper/match_result.go new file mode 100644 index 000000000..09424196c --- /dev/null +++ b/x/dex/keeper/match_result.go @@ -0,0 +1,45 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +const MatchResultKey = "match-result" + +func (k Keeper) SetMatchResult(ctx sdk.Context, contractAddr string, result *types.MatchResult) { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + types.MatchResultPrefix(contractAddr), + ) + height := ctx.BlockHeight() + result.Height = height + result.ContractAddr = contractAddr + bz, err := result.Marshal() + if err != nil { + panic(err) + } + store.Set([]byte(MatchResultKey), bz) +} + +func (k Keeper) GetMatchResultState(ctx sdk.Context, contractAddr string) (*types.MatchResult, bool) { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + types.MatchResultPrefix(contractAddr), + ) + bz := store.Get([]byte(MatchResultKey)) + result := types.MatchResult{} + if err := result.Unmarshal(bz); err != nil { + panic(err) + } + return &result, true +} + +func (k Keeper) DeleteMatchResultState(ctx sdk.Context, contractAddr string) { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + types.MatchResultPrefix(contractAddr), + ) + store.Delete([]byte(MatchResultKey)) +} diff --git a/x/dex/keeper/msgserver/msg_server.go b/x/dex/keeper/msgserver/msg_server.go new file mode 100644 index 000000000..8d459eeb0 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server.go @@ -0,0 +1,18 @@ +package msgserver + +import ( + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +type msgServer struct { + keeper.Keeper +} + +// NewMsgServerImpl returns an implementation of the MsgServer interface +// for the provided Keeper. +func NewMsgServerImpl(keeper keeper.Keeper) types.MsgServer { + return &msgServer{Keeper: keeper} +} + +var _ types.MsgServer = msgServer{} diff --git a/x/dex/keeper/msgserver/msg_server_cancel_orders.go b/x/dex/keeper/msgserver/msg_server_cancel_orders.go new file mode 100644 index 000000000..8ca3a4a1d --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_cancel_orders.go @@ -0,0 +1,12 @@ +package msgserver + +import ( + "context" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k msgServer) CancelOrders(goCtx context.Context, msg *types.MsgCancelOrders) (*types.MsgCancelOrdersResponse, error) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated") +} diff --git a/x/dex/keeper/msgserver/msg_server_cancel_orders_test.go b/x/dex/keeper/msgserver/msg_server_cancel_orders_test.go new file mode 100644 index 000000000..88f88473c --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_cancel_orders_test.go @@ -0,0 +1,36 @@ +package msgserver_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestCancelOrder(t *testing.T) { + // store a long limit order to the orderbook + keeper, ctx := keepertest.DexKeeper(t) + + // cancel order + msg := &types.MsgCancelOrders{ + Creator: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + Cancellations: []*types.Cancellation{ + { + Price: sdk.OneDec(), + PositionDirection: types.PositionDirection_LONG, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Id: 1, + }, + }, + } + wctx := sdk.WrapSDKContext(ctx) + server := msgserver.NewMsgServerImpl(*keeper) + _, err := server.CancelOrders(wctx, msg) + require.EqualError(t, err, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated").Error()) +} diff --git a/x/dex/keeper/msgserver/msg_server_contract_deposit_rent.go b/x/dex/keeper/msgserver/msg_server_contract_deposit_rent.go new file mode 100644 index 000000000..d1a4cf329 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_contract_deposit_rent.go @@ -0,0 +1,12 @@ +package msgserver + +import ( + "context" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k msgServer) ContractDepositRent(goCtx context.Context, msg *types.MsgContractDepositRent) (*types.MsgContractDepositRentResponse, error) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated") +} diff --git a/x/dex/keeper/msgserver/msg_server_contract_deposit_rent_test.go b/x/dex/keeper/msgserver/msg_server_contract_deposit_rent_test.go new file mode 100644 index 000000000..894ba170e --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_contract_deposit_rent_test.go @@ -0,0 +1,34 @@ +package msgserver_test + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestDepositRent(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + dexkeeper := testApp.DexKeeper + + depositAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + + handler := dex.NewHandler(dexkeeper) + _, err := handler(ctx, &types.MsgContractDepositRent{ + Sender: depositAccount.String(), + ContractAddr: TestContractA, + Amount: types.DefaultParams().MinRentDeposit, + }) + require.EqualError(t, err, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated").Error()) +} diff --git a/x/dex/keeper/msgserver/msg_server_place_orders.go b/x/dex/keeper/msgserver/msg_server_place_orders.go new file mode 100644 index 000000000..ae7a70700 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_place_orders.go @@ -0,0 +1,12 @@ +package msgserver + +import ( + "context" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k msgServer) PlaceOrders(goCtx context.Context, msg *types.MsgPlaceOrders) (*types.MsgPlaceOrdersResponse, error) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated") +} diff --git a/x/dex/keeper/msgserver/msg_server_place_orders_fuzz_test.go b/x/dex/keeper/msgserver/msg_server_place_orders_fuzz_test.go new file mode 100644 index 000000000..ec88e75db --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_place_orders_fuzz_test.go @@ -0,0 +1,65 @@ +package msgserver_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + fuzzutils "github.com/sei-protocol/sei-chain/testutil/fuzzing" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func FuzzPlaceOrders(f *testing.F) { + f.Add(uint64(0), int32(0), 2, 2, int64(10), false, int64(2), false, keepertest.TestPriceDenom, keepertest.TestAssetDenom, int32(0), int32(0), "", "", false, int64(20)) + f.Fuzz(fuzzTargetPlaceOrders) +} + +func fuzzTargetPlaceOrders( + t *testing.T, + id uint64, + status int32, + accountIdx int, + contractIdx int, + priceI int64, + priceIsNil bool, + quantityI int64, + quantityIsNil bool, + priceDenom string, + assetDenom string, + orderType int32, + positionDirection int32, + data string, + statusDescription string, + fundIsNil bool, + fundAmount int64, +) { + keeper, ctx := keepertest.DexKeeper(t) + contract := fuzzutils.GetContract(contractIdx) + keeper.AddRegisteredPair(ctx, contract, keepertest.TestPair) + keeper.SetPriceTickSizeForPair(ctx, TestContract, keepertest.TestPair, *keepertest.TestPair.PriceTicksize) + keeper.SetQuantityTickSizeForPair(ctx, TestContract, keepertest.TestPair, *keepertest.TestPair.QuantityTicksize) + wctx := sdk.WrapSDKContext(ctx) + msg := &types.MsgPlaceOrders{ + Creator: fuzzutils.GetAccount(accountIdx), + ContractAddr: contract, + Orders: []*types.Order{ + { + Id: id, + Status: types.OrderStatus(status), + Price: fuzzutils.FuzzDec(priceI, priceIsNil), + Quantity: fuzzutils.FuzzDec(quantityI, quantityIsNil), + Data: data, + StatusDescription: statusDescription, + PositionDirection: types.PositionDirection(positionDirection), + OrderType: types.OrderType(orderType), + PriceDenom: priceDenom, + AssetDenom: assetDenom, + }, + }, + Funds: []sdk.Coin{fuzzutils.FuzzCoin(priceDenom, fundIsNil, fundAmount)}, + } + server := msgserver.NewMsgServerImpl(*keeper) + require.NotPanics(t, func() { server.PlaceOrders(wctx, msg) }) +} diff --git a/x/dex/keeper/msgserver/msg_server_place_orders_test.go b/x/dex/keeper/msgserver/msg_server_place_orders_test.go new file mode 100644 index 000000000..d14e3e532 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_place_orders_test.go @@ -0,0 +1,49 @@ +package msgserver_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +const ( + TestCreator = "sei1ewxvf5a9wq9zk5nurtl6m9yfxpnhyp7s7uk5sl" + TestContract = "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m" +) + +func TestPlaceOrder(t *testing.T) { + msg := &types.MsgPlaceOrders{ + Creator: TestCreator, + ContractAddr: TestContract, + Orders: []*types.Order{ + { + Price: sdk.MustNewDecFromStr("10"), + Quantity: sdk.MustNewDecFromStr("10"), + Data: "", + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_LIMIT, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + { + Price: sdk.MustNewDecFromStr("20"), + Quantity: sdk.MustNewDecFromStr("5"), + Data: "", + PositionDirection: types.PositionDirection_SHORT, + OrderType: types.OrderType_MARKET, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + }, + } + keeper, ctx := keepertest.DexKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + server := msgserver.NewMsgServerImpl(*keeper) + _, err := server.PlaceOrders(wctx, msg) + require.EqualError(t, err, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated").Error()) +} diff --git a/x/dex/keeper/msgserver/msg_server_register_contract.go b/x/dex/keeper/msgserver/msg_server_register_contract.go new file mode 100644 index 000000000..77bec2bd4 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_register_contract.go @@ -0,0 +1,12 @@ +package msgserver + +import ( + "context" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k msgServer) RegisterContract(goCtx context.Context, msg *types.MsgRegisterContract) (*types.MsgRegisterContractResponse, error) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated") +} diff --git a/x/dex/keeper/msgserver/msg_server_register_contract_test.go b/x/dex/keeper/msgserver/msg_server_register_contract_test.go new file mode 100644 index 000000000..c4bcc6e1c --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_register_contract_test.go @@ -0,0 +1,34 @@ +package msgserver_test + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +const ( + TestContractA = "sei1hrpna9v7vs3stzyd4z3xf00676kf78zpe2u5ksvljswn2vnjp3yslucc3n" +) + +func TestRegisterContract(t *testing.T) { + // Instantiate and get contract address + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + wctx := sdk.WrapSDKContext(ctx) + keeper := testApp.DexKeeper + + server := msgserver.NewMsgServerImpl(keeper) + _, err := server.RegisterContract(wctx, &types.MsgRegisterContract{}) + require.EqualError(t, err, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated").Error()) +} diff --git a/x/dex/keeper/msgserver/msg_server_register_pairs.go b/x/dex/keeper/msgserver/msg_server_register_pairs.go new file mode 100644 index 000000000..582521dd5 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_register_pairs.go @@ -0,0 +1,12 @@ +package msgserver + +import ( + "context" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k msgServer) RegisterPairs(goCtx context.Context, msg *types.MsgRegisterPairs) (*types.MsgRegisterPairsResponse, error) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated") +} diff --git a/x/dex/keeper/msgserver/msg_server_register_pairs_test.go b/x/dex/keeper/msgserver/msg_server_register_pairs_test.go new file mode 100644 index 000000000..bc4dc9198 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_register_pairs_test.go @@ -0,0 +1,38 @@ +package msgserver_test + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestRegisterPairs(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + wctx := sdk.WrapSDKContext(ctx) + keeper := testApp.DexKeeper + + server := msgserver.NewMsgServerImpl(keeper) + + batchContractPairs := []types.BatchContractPair{} + batchContractPairs = append(batchContractPairs, types.BatchContractPair{ + ContractAddr: TestContractA, + Pairs: []*types.Pair{&keepertest.TestPair}, + }) + _, err := server.RegisterPairs(wctx, &types.MsgRegisterPairs{ + Creator: keepertest.TestAccount, + Batchcontractpair: batchContractPairs, + }) + require.EqualError(t, err, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated").Error()) +} diff --git a/x/dex/keeper/msgserver/msg_server_unregister_contract.go b/x/dex/keeper/msgserver/msg_server_unregister_contract.go new file mode 100644 index 000000000..c12650b85 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_unregister_contract.go @@ -0,0 +1,12 @@ +package msgserver + +import ( + "context" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k msgServer) UnregisterContract(goCtx context.Context, msg *types.MsgUnregisterContract) (*types.MsgUnregisterContractResponse, error) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated") +} diff --git a/x/dex/keeper/msgserver/msg_server_unregister_contract_test.go b/x/dex/keeper/msgserver/msg_server_unregister_contract_test.go new file mode 100644 index 000000000..2d91979a7 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_unregister_contract_test.go @@ -0,0 +1,34 @@ +package msgserver_test + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestUnregisterContractSetSiblings(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + keeper := testApp.DexKeeper + + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + + handler := dex.NewHandler(keeper) + + _, err := handler(ctx, &types.MsgUnregisterContract{ + Creator: testAccount.String(), + ContractAddr: TestContractA, + }) + require.EqualError(t, err, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated").Error()) +} diff --git a/x/dex/keeper/msgserver/msg_server_unsuspend_contract.go b/x/dex/keeper/msgserver/msg_server_unsuspend_contract.go new file mode 100644 index 000000000..d1da8c2c5 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_unsuspend_contract.go @@ -0,0 +1,12 @@ +package msgserver + +import ( + "context" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k msgServer) UnsuspendContract(goCtx context.Context, msg *types.MsgUnsuspendContract) (*types.MsgUnsuspendContractResponse, error) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated") +} diff --git a/x/dex/keeper/msgserver/msg_server_unsuspend_contract_test.go b/x/dex/keeper/msgserver/msg_server_unsuspend_contract_test.go new file mode 100644 index 000000000..a2ac0f3ac --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_unsuspend_contract_test.go @@ -0,0 +1,23 @@ +package msgserver_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestUnsuspendContract(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + server := msgserver.NewMsgServerImpl(*keeper) + _, err := server.UnsuspendContract(wctx, &types.MsgUnsuspendContract{ + Creator: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + }) + require.EqualError(t, err, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated").Error()) +} diff --git a/x/dex/keeper/msgserver/msg_server_update_price_tick_size.go b/x/dex/keeper/msgserver/msg_server_update_price_tick_size.go new file mode 100644 index 000000000..6a09e1dc7 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_update_price_tick_size.go @@ -0,0 +1,12 @@ +package msgserver + +import ( + "context" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k msgServer) UpdatePriceTickSize(goCtx context.Context, msg *types.MsgUpdatePriceTickSize) (*types.MsgUpdateTickSizeResponse, error) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated") +} diff --git a/x/dex/keeper/msgserver/msg_server_update_price_tick_size_test.go b/x/dex/keeper/msgserver/msg_server_update_price_tick_size_test.go new file mode 100644 index 000000000..77ab54fae --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_update_price_tick_size_test.go @@ -0,0 +1,40 @@ +package msgserver_test + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestUpdatePriceTickSize(t *testing.T) { + // Instantiate and get contract address + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + wctx := sdk.WrapSDKContext(ctx) + keeper := testApp.DexKeeper + server := msgserver.NewMsgServerImpl(keeper) + + // Test updated tick size + tickUpdates := []types.TickSize{} + tickUpdates = append(tickUpdates, types.TickSize{ + ContractAddr: TestContractA, + Pair: &keepertest.TestPair, + Ticksize: sdk.MustNewDecFromStr("0.1"), + }) + _, err := server.UpdatePriceTickSize(wctx, &types.MsgUpdatePriceTickSize{ + Creator: keepertest.TestAccount, + TickSizeList: tickUpdates, + }) + require.EqualError(t, err, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated").Error()) +} diff --git a/x/dex/keeper/msgserver/msg_server_update_quantity_tick_size.go b/x/dex/keeper/msgserver/msg_server_update_quantity_tick_size.go new file mode 100644 index 000000000..f4e948a54 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_update_quantity_tick_size.go @@ -0,0 +1,12 @@ +package msgserver + +import ( + "context" + + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k msgServer) UpdateQuantityTickSize(goCtx context.Context, msg *types.MsgUpdateQuantityTickSize) (*types.MsgUpdateTickSizeResponse, error) { + return nil, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated") +} diff --git a/x/dex/keeper/msgserver/msg_server_update_quantity_tick_size_test.go b/x/dex/keeper/msgserver/msg_server_update_quantity_tick_size_test.go new file mode 100644 index 000000000..eccbf9e45 --- /dev/null +++ b/x/dex/keeper/msgserver/msg_server_update_quantity_tick_size_test.go @@ -0,0 +1,41 @@ +package msgserver_test + +import ( + "context" + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/require" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" +) + +func TestUpdateQuantityTickSize(t *testing.T) { + // Instantiate and get contract address + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + wctx := sdk.WrapSDKContext(ctx) + keeper := testApp.DexKeeper + + server := msgserver.NewMsgServerImpl(keeper) + + // Test updated tick size + tickUpdates := []types.TickSize{} + tickUpdates = append(tickUpdates, types.TickSize{ + ContractAddr: TestContractA, + Pair: &keepertest.TestPair, + Ticksize: sdk.MustNewDecFromStr("0.1"), + }) + _, err := server.UpdateQuantityTickSize(wctx, &types.MsgUpdateQuantityTickSize{ + Creator: keepertest.TestAccount, + TickSizeList: tickUpdates, + }) + require.EqualError(t, err, sdkerrors.Wrapf(sdkerrors.ErrNotSupported, "deprecated").Error()) +} diff --git a/x/dex/keeper/msgserver/testdata/hackatom.wasm b/x/dex/keeper/msgserver/testdata/hackatom.wasm new file mode 100644 index 000000000..183eef304 Binary files /dev/null and b/x/dex/keeper/msgserver/testdata/hackatom.wasm differ diff --git a/x/dex/keeper/msgserver/validations.go b/x/dex/keeper/msgserver/validations.go new file mode 100644 index 000000000..cdbbb0647 --- /dev/null +++ b/x/dex/keeper/msgserver/validations.go @@ -0,0 +1,40 @@ +package msgserver + +import ( + "fmt" + "math" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// Since cosmwasm would amplify gas limit by a multiplier for its internal gas metering, +// we want to make sure the amplified result doesn't exceed uint64 limit. +func (k msgServer) ValidateRentBalance(ctx sdk.Context, rentBalance uint64) error { + maxAllowedRent := k.maxAllowedRentBalance() + minAllowedRent := k.minAllowedRentBalance(ctx) + if rentBalance > maxAllowedRent || rentBalance < minAllowedRent { + return fmt.Errorf("rent balance %d is either bigger than the maximum allowed rent balance %d, or smaller than the minimal allowed balance %d", + rentBalance, maxAllowedRent, minAllowedRent) + } + return nil +} + +func (k msgServer) ValidateSuspension(ctx sdk.Context, contractAddress string) error { + contract, err := k.GetContract(ctx, contractAddress) + if err == nil && contract.Suspended { + return types.ErrContractSuspended + } + return nil +} + +func (k msgServer) maxAllowedRentBalance() uint64 { + // TODO: replace with a wasm keeper query once its gas registry is made public + return uint64(math.MaxUint64) / wasmkeeper.DefaultGasMultiplier +} + +func (k msgServer) minAllowedRentBalance(ctx sdk.Context) uint64 { + params := k.GetParams(ctx) + return params.MinRentDeposit +} diff --git a/x/dex/keeper/order_count.go b/x/dex/keeper/order_count.go new file mode 100644 index 000000000..5b72366cb --- /dev/null +++ b/x/dex/keeper/order_count.go @@ -0,0 +1,56 @@ +package keeper + +import ( + "encoding/binary" + "fmt" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k Keeper) SetOrderCount(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, direction types.PositionDirection, price sdk.Dec, count uint64) error { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + types.OrderCountPrefix(contractAddr, priceDenom, assetDenom, direction == types.PositionDirection_LONG), + ) + key, err := price.Marshal() + if err != nil { + return err + } + value := make([]byte, 8) + binary.BigEndian.PutUint64(value, count) + store.Set(key, value) + return nil +} + +func (k Keeper) GetOrderCountState(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, direction types.PositionDirection, price sdk.Dec) uint64 { + store := prefix.NewStore( + ctx.KVStore(k.storeKey), + types.OrderCountPrefix(contractAddr, priceDenom, assetDenom, direction == types.PositionDirection_LONG), + ) + key, err := price.Marshal() + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error marshal provided price %s due to %s", price.String(), err)) + return 0 + } + value := store.Get(key) + if value == nil { + return 0 + } + return binary.BigEndian.Uint64(value) +} + +func (k Keeper) DecreaseOrderCount(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, direction types.PositionDirection, price sdk.Dec, count uint64) error { + oldCount := k.GetOrderCountState(ctx, contractAddr, priceDenom, assetDenom, direction, price) + newCount := uint64(0) + if oldCount > count { + newCount = oldCount - count + } + return k.SetOrderCount(ctx, contractAddr, priceDenom, assetDenom, direction, price, newCount) +} + +func (k Keeper) IncreaseOrderCount(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, direction types.PositionDirection, price sdk.Dec, count uint64) error { + oldCount := k.GetOrderCountState(ctx, contractAddr, priceDenom, assetDenom, direction, price) + return k.SetOrderCount(ctx, contractAddr, priceDenom, assetDenom, direction, price, oldCount+count) +} diff --git a/x/dex/keeper/order_count_test.go b/x/dex/keeper/order_count_test.go new file mode 100644 index 000000000..1fe604933 --- /dev/null +++ b/x/dex/keeper/order_count_test.go @@ -0,0 +1,35 @@ +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/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGetSetOrderCount(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + for _, direction := range []types.PositionDirection{ + types.PositionDirection_LONG, + types.PositionDirection_SHORT, + } { + require.Equal(t, uint64(0), keeper.GetOrderCountState(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, direction, sdk.NewDec(1))) + require.Nil(t, keeper.SetOrderCount(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, direction, sdk.NewDec(1), 5)) + require.Equal(t, uint64(5), keeper.GetOrderCountState(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, direction, sdk.NewDec(1))) + } +} + +func TestIncreaseOrderCount(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keeper.IncreaseOrderCount(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(1), 10) + require.Equal(t, uint64(10), keeper.GetOrderCountState(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(1))) +} + +func TestDecreaseOrderCount(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + require.Nil(t, keeper.SetOrderCount(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(1), 10)) + keeper.DecreaseOrderCount(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(1), 5) + require.Equal(t, uint64(5), keeper.GetOrderCountState(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(1))) +} diff --git a/x/dex/keeper/order_placement.go b/x/dex/keeper/order_placement.go new file mode 100644 index 000000000..b6d5fcec6 --- /dev/null +++ b/x/dex/keeper/order_placement.go @@ -0,0 +1,33 @@ +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" +) + +func (k Keeper) GetNextOrderID(ctx sdk.Context, contractAddr string) uint64 { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.NextOrderIDPrefix(contractAddr)) + byteKey := types.KeyPrefix(types.NextOrderIDKey) + bz := store.Get(byteKey) + if bz == nil { + return 0 + } + return binary.BigEndian.Uint64(bz) +} + +func (k Keeper) SetNextOrderID(ctx sdk.Context, contractAddr string, nextID uint64) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.NextOrderIDPrefix(contractAddr)) + byteKey := types.KeyPrefix(types.NextOrderIDKey) + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, nextID) + store.Set(byteKey, bz) +} + +func (k Keeper) DeleteNextOrderID(ctx sdk.Context, contractAddr string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.NextOrderIDPrefix(contractAddr)) + byteKey := types.KeyPrefix(types.NextOrderIDKey) + store.Delete(byteKey) +} diff --git a/x/dex/keeper/pair.go b/x/dex/keeper/pair.go new file mode 100644 index 000000000..914131cc9 --- /dev/null +++ b/x/dex/keeper/pair.go @@ -0,0 +1,56 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k Keeper) AddRegisteredPair(ctx sdk.Context, contractAddr string, pair types.Pair) bool { + // only add pairs that haven't been added before + if k.HasRegisteredPair(ctx, contractAddr, pair.PriceDenom, pair.AssetDenom) { + return false + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.RegisteredPairPrefix(contractAddr)) + store.Set(types.PairPrefix(pair.PriceDenom, pair.AssetDenom), k.Cdc.MustMarshal(&pair)) + return true +} + +func (k Keeper) HasRegisteredPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string) bool { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.RegisteredPairPrefix(contractAddr)) + return store.Has(types.PairPrefix(priceDenom, assetDenom)) +} + +func (k Keeper) GetRegisteredPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string) (types.Pair, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.RegisteredPairPrefix(contractAddr)) + b := store.Get(types.PairPrefix(priceDenom, assetDenom)) + res := types.Pair{} + if b == nil { + return res, false + } + err := res.Unmarshal(b) + if err != nil { + panic(err) + } + return res, true +} + +func (k Keeper) GetAllRegisteredPairs(ctx sdk.Context, contractAddr string) []types.Pair { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.RegisteredPairPrefix(contractAddr)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + list := []types.Pair{} + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Pair + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return list +} + +func (k Keeper) DeleteAllRegisteredPairsForContract(ctx sdk.Context, contractAddr string) { + k.removeAllForPrefix(ctx, types.RegisteredPairPrefix(contractAddr)) +} diff --git a/x/dex/keeper/pair_test.go b/x/dex/keeper/pair_test.go new file mode 100644 index 000000000..8dcbe65d2 --- /dev/null +++ b/x/dex/keeper/pair_test.go @@ -0,0 +1,41 @@ +package keeper_test + +import ( + "testing" + + 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 TestAddGetPair(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keeper.AddRegisteredPair(ctx, keepertest.TestContract, types.Pair{ + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + PriceTicksize: &keepertest.TestTicksize, + QuantityTicksize: &keepertest.TestTicksize, + }) + require.ElementsMatch(t, + nullify.Fill([]types.Pair{{ + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + PriceTicksize: &keepertest.TestTicksize, + QuantityTicksize: &keepertest.TestTicksize, + }}), + nullify.Fill(keeper.GetAllRegisteredPairs(ctx, keepertest.TestContract)), + ) + + pair, found := keeper.GetRegisteredPair(ctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, types.Pair{ + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + PriceTicksize: &keepertest.TestTicksize, + QuantityTicksize: &keepertest.TestTicksize, + }, pair) + hasPair := keeper.HasRegisteredPair(ctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, hasPair) + +} diff --git a/x/dex/keeper/params.go b/x/dex/keeper/params.go new file mode 100644 index 000000000..2e4c77c02 --- /dev/null +++ b/x/dex/keeper/params.go @@ -0,0 +1,42 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// GetParams get all parameters as types.Params +func (k Keeper) GetParams(ctx sdk.Context) types.Params { + params := types.Params{} + k.Paramstore.GetParamSet(ctx, ¶ms) + return params +} + +func (k Keeper) GetSettlementGasAllowance(ctx sdk.Context, numSettlements int) uint64 { + return k.GetParams(ctx).GasAllowancePerSettlement * uint64(numSettlements) +} + +func (k Keeper) GetMinProcessableRent(ctx sdk.Context) uint64 { + return k.GetParams(ctx).MinProcessableRent +} + +func (k Keeper) GetOrderBookEntriesPerLoad(ctx sdk.Context) uint64 { + return k.GetParams(ctx).OrderBookEntriesPerLoad +} + +func (k Keeper) GetContractUnsuspendCost(ctx sdk.Context) uint64 { + return k.GetParams(ctx).ContractUnsuspendCost +} + +func (k Keeper) GetMaxOrderPerPrice(ctx sdk.Context) uint64 { + return k.GetParams(ctx).MaxOrderPerPrice +} + +func (k Keeper) GetMaxPairsPerContract(ctx sdk.Context) uint64 { + return k.GetParams(ctx).MaxPairsPerContract +} + +// SetParams set the params +func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { + k.Paramstore.SetParamSet(ctx, ¶ms) +} diff --git a/x/dex/keeper/params_test.go b/x/dex/keeper/params_test.go new file mode 100644 index 000000000..1bbab914e --- /dev/null +++ b/x/dex/keeper/params_test.go @@ -0,0 +1,24 @@ +package keeper_test + +import ( + "testing" + + testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGetParams(t *testing.T) { + k, ctx := testkeeper.DexKeeper(t) + params := types.DefaultParams() + + k.SetParams(ctx, params) + + require.EqualValues(t, params, k.GetParams(ctx)) +} + +func TestGetSettlementGasAllowance(t *testing.T) { + k, ctx := testkeeper.DexKeeper(t) + gasAllowance := k.GetSettlementGasAllowance(ctx, 10) + require.Equal(t, uint64(10)*types.DefaultGasAllowancePerSettlement, gasAllowance) +} diff --git a/x/dex/keeper/price.go b/x/dex/keeper/price.go new file mode 100644 index 000000000..d18cc1ce0 --- /dev/null +++ b/x/dex/keeper/price.go @@ -0,0 +1,98 @@ +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" +) + +func (k Keeper) SetPriceState(ctx sdk.Context, price types.Price, contractAddr string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.PricePrefix(contractAddr, price.Pair.PriceDenom, price.Pair.AssetDenom)) + b := k.Cdc.MustMarshal(&price) + store.Set(GetKeyForTs(price.SnapshotTimestampInSeconds), b) +} + +func (k Keeper) DeletePriceStateBefore(ctx sdk.Context, contractAddr string, timestamp uint64, pair types.Pair) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.PricePrefix(contractAddr, pair.PriceDenom, pair.AssetDenom)) + for _, key := range k.GetPriceKeysToDelete(store, timestamp) { + store.Delete(key) + } +} + +func (k Keeper) GetPriceKeysToDelete(store sdk.KVStore, timestamp uint64) [][]byte { + keys := [][]byte{} + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + defer iterator.Close() + + // Since timestamp is encoded in big endian, the first price being iterated has the smallest timestamp. + for ; iterator.Valid(); iterator.Next() { + priceKey := iterator.Key() + priceTs := binary.BigEndian.Uint64(priceKey) + if priceTs < timestamp { + keys = append(keys, priceKey) + } else { + break + } + } + return keys +} + +func (k Keeper) GetPriceState(ctx sdk.Context, contractAddr string, timestamp uint64, pair types.Pair) (types.Price, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.PricePrefix(contractAddr, pair.PriceDenom, pair.AssetDenom)) + res := types.Price{} + key := GetKeyForTs(timestamp) + if !store.Has(key) { + res.Pair = &pair + return res, false + } + b := store.Get(key) + k.Cdc.MustUnmarshal(b, &res) + return res, true +} + +func (k Keeper) GetAllPrices(ctx sdk.Context, contractAddr string, pair types.Pair) (list []*types.Price) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.PricePrefix(contractAddr, pair.PriceDenom, pair.AssetDenom)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.Price + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, &val) + } + + return +} + +func (k Keeper) GetPricesForTwap(ctx sdk.Context, contractAddr string, pair types.Pair, lookback uint64) (list []*types.Price) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.PricePrefix(contractAddr, pair.PriceDenom, pair.AssetDenom)) + iterator := sdk.KVStoreReversePrefixIterator(store, []byte{}) + + defer iterator.Close() + + cutoff := uint64(ctx.BlockTime().Unix()) - lookback + for ; iterator.Valid(); iterator.Next() { + var val types.Price + k.Cdc.MustUnmarshal(iterator.Value(), &val) + // add to list before breaking since we want to include one older price if there is any + list = append(list, &val) + if val.SnapshotTimestampInSeconds < cutoff { + break + } + } + + return +} + +func (k Keeper) RemoveAllPricesForContract(ctx sdk.Context, contractAddr string) { + k.removeAllForPrefix(ctx, types.PriceContractPrefix(contractAddr)) +} + +func GetKeyForTs(ts uint64) []byte { + tsKey := make([]byte, 8) + binary.BigEndian.PutUint64(tsKey, ts) + return tsKey +} diff --git a/x/dex/keeper/price_test.go b/x/dex/keeper/price_test.go new file mode 100644 index 000000000..fa519d47c --- /dev/null +++ b/x/dex/keeper/price_test.go @@ -0,0 +1,20 @@ +package keeper_test + +import ( + "testing" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/stretchr/testify/require" +) + +func TestDeletePriceStateBefore(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keepertest.SeedPriceSnapshot(ctx, keeper, "100", 1) + keepertest.SeedPriceSnapshot(ctx, keeper, "101", 2) + keepertest.SeedPriceSnapshot(ctx, keeper, "99", 3) + keeper.DeletePriceStateBefore(ctx, keepertest.TestContract, 2, keepertest.TestPair) + prices := keeper.GetAllPrices(ctx, keepertest.TestContract, keepertest.TestPair) + require.Equal(t, 2, len(prices)) + require.Equal(t, uint64(2), prices[0].SnapshotTimestampInSeconds) + require.Equal(t, uint64(3), prices[1].SnapshotTimestampInSeconds) +} diff --git a/x/dex/keeper/query/grpc_query.go b/x/dex/keeper/query/grpc_query.go new file mode 100644 index 000000000..2cc5e787e --- /dev/null +++ b/x/dex/keeper/query/grpc_query.go @@ -0,0 +1,7 @@ +package query + +import ( + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +var _ types.QueryServer = KeeperWrapper{} diff --git a/x/dex/keeper/query/grpc_query_asset_list.go b/x/dex/keeper/query/grpc_query_asset_list.go new file mode 100644 index 000000000..fc7748be9 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_asset_list.go @@ -0,0 +1,36 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) AssetList(c context.Context, req *types.QueryAssetListRequest) (*types.QueryAssetListResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + + allAssetMetadata := k.GetAllAssetMetadata(ctx) + + return &types.QueryAssetListResponse{AssetList: allAssetMetadata}, nil +} + +func (k KeeperWrapper) AssetMetadata(c context.Context, req *types.QueryAssetMetadataRequest) (*types.QueryAssetMetadataResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + + assetMetadata, found := k.GetAssetMetadataByDenom(ctx, req.Denom) + if !found { + return nil, sdkerrors.ErrKeyNotFound + } + + return &types.QueryAssetMetadataResponse{Metadata: &assetMetadata}, nil +} diff --git a/x/dex/keeper/query/grpc_query_asset_list_test.go b/x/dex/keeper/query/grpc_query_asset_list_test.go new file mode 100644 index 000000000..b2bd8a4a9 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_asset_list_test.go @@ -0,0 +1,50 @@ +package query_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/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestAssetListQuery(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + item := keepertest.CreateAssetMetadata(keeper, ctx) + + var expectedAssetList []types.AssetMetadata + expectedAssetList = append(expectedAssetList, item) + + request := types.QueryAssetListRequest{} + expectedResponse := types.QueryAssetListResponse{ + AssetList: expectedAssetList, + } + wrapper := query.KeeperWrapper{Keeper: keeper} + t.Run("Asset list query", func(t *testing.T) { + response, err := wrapper.AssetList(wctx, &request) + require.NoError(t, err) + require.Equal(t, expectedResponse, *response) + }) +} + +func TestAssetMetadataQuery(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wctx := sdk.WrapSDKContext(ctx) + expectedMetadata := keepertest.CreateAssetMetadata(keeper, ctx) + + request := types.QueryAssetMetadataRequest{ + Denom: "axlusdc", + } + expectedResponse := types.QueryAssetMetadataResponse{ + Metadata: &expectedMetadata, + } + wrapper := query.KeeperWrapper{Keeper: keeper} + t.Run("Asset metadata query", func(t *testing.T) { + response, err := wrapper.AssetMetadata(wctx, &request) + require.NoError(t, err) + require.Equal(t, expectedResponse, *response) + }) +} diff --git a/x/dex/keeper/query/grpc_query_get_historical_prices.go b/x/dex/keeper/query/grpc_query_get_historical_prices.go new file mode 100644 index 000000000..9e6dc434f --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_historical_prices.go @@ -0,0 +1,119 @@ +package query + +import ( + "context" + "sort" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +var ZeroPrice = sdk.ZeroDec() + +func (k KeeperWrapper) GetHistoricalPrices(goCtx context.Context, req *types.QueryGetHistoricalPricesRequest) (*types.QueryGetHistoricalPricesResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + prices := k.GetAllPrices(ctx, req.ContractAddr, types.Pair{PriceDenom: req.PriceDenom, AssetDenom: req.AssetDenom}) + currentTimeStamp := uint64(ctx.BlockTime().Unix()) + beginTimestamp := currentTimeStamp - req.NumOfPeriods*req.PeriodLengthInSeconds + // sort descending + sort.Slice(prices, func(i, j int) bool { + return prices[i].SnapshotTimestampInSeconds > prices[j].SnapshotTimestampInSeconds + }) + validPrices := []*types.Price{} + for _, price := range prices { + // append early so that we include the latest price before beginTimestamp, since + // we need it to set the open price of the first period. + if price.SnapshotTimestampInSeconds < currentTimeStamp { + validPrices = append(validPrices, price) + } + if price.SnapshotTimestampInSeconds < beginTimestamp { + break + } + } + + candlesticks := make([]*types.PriceCandlestick, req.NumOfPeriods) + + // set timestamp + for i := range candlesticks { + candlesticks[i] = &types.PriceCandlestick{} + candlesticks[i].EndTimestamp = currentTimeStamp - uint64(i)*req.PeriodLengthInSeconds + candlesticks[i].BeginTimestamp = candlesticks[i].EndTimestamp - req.PeriodLengthInSeconds + } + + // set open + pricePtr := 0 + for i := range candlesticks { + for pricePtr < len(validPrices) && validPrices[pricePtr].SnapshotTimestampInSeconds > candlesticks[i].BeginTimestamp { + pricePtr++ + } + if pricePtr < len(validPrices) { + candlesticks[i].Open = &validPrices[pricePtr].Price + } else { + // this would happen if the earliest price point available is after the begin timestamp + candlesticks[i].Open = &ZeroPrice + } + } + + // set close + pricePtr = 0 + for i := range candlesticks { + for pricePtr < len(validPrices) && validPrices[pricePtr].SnapshotTimestampInSeconds >= candlesticks[i].EndTimestamp { + pricePtr++ + } + if pricePtr < len(validPrices) { + candlesticks[i].Close = &validPrices[pricePtr].Price + } else { + // this would happen if the earliest price point available is after the first end timestamp + candlesticks[i].Close = &ZeroPrice + } + } + + // set high + pricePtr = 0 + for i := range candlesticks { + // initialize to the open price + candlesticks[i].High = candlesticks[i].Open + set := false + for pricePtr < len(validPrices) { + price := validPrices[pricePtr] + if price.SnapshotTimestampInSeconds < candlesticks[i].BeginTimestamp || price.SnapshotTimestampInSeconds >= candlesticks[i].EndTimestamp { + break + } + if !set || price.Price.GT(*candlesticks[i].High) { + set = true + candlesticks[i].High = &price.Price + } + pricePtr++ + } + } + + // set low + pricePtr = 0 + for i := range candlesticks { + // initialize to the open price + candlesticks[i].Low = candlesticks[i].Open + set := false + for pricePtr < len(validPrices) { + price := validPrices[pricePtr] + if price.SnapshotTimestampInSeconds < candlesticks[i].BeginTimestamp || price.SnapshotTimestampInSeconds >= candlesticks[i].EndTimestamp { + break + } + if !set || price.Price.LT(*candlesticks[i].Low) { + set = true + candlesticks[i].Low = &price.Price + } + pricePtr++ + } + } + + return &types.QueryGetHistoricalPricesResponse{ + Prices: candlesticks, + }, nil +} diff --git a/x/dex/keeper/query/grpc_query_get_historical_prices_test.go b/x/dex/keeper/query/grpc_query_get_historical_prices_test.go new file mode 100644 index 000000000..29b62f942 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_historical_prices_test.go @@ -0,0 +1,185 @@ +package query_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/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestEachPeriodOneDataPoint(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keepertest.SeedPriceSnapshot(ctx, keeper, "100", 1) + keepertest.SeedPriceSnapshot(ctx, keeper, "101", 2) + keepertest.SeedPriceSnapshot(ctx, keeper, "99", 3) // should not be included since end is exclusive + + ctx = ctx.WithBlockTime(time.Unix(3, 0)) + wctx := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: keeper} + resp, err := wrapper.GetHistoricalPrices(wctx, &types.QueryGetHistoricalPricesRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + PeriodLengthInSeconds: 1, + NumOfPeriods: 2, + }) + require.Nil(t, err) + require.Equal(t, 2, len(resp.Prices)) + require.Equal(t, uint64(2), resp.Prices[0].BeginTimestamp) + require.Equal(t, uint64(3), resp.Prices[0].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("101"), *resp.Prices[0].Open) + require.Equal(t, sdk.MustNewDecFromStr("101"), *resp.Prices[0].High) + require.Equal(t, sdk.MustNewDecFromStr("101"), *resp.Prices[0].Low) + require.Equal(t, sdk.MustNewDecFromStr("101"), *resp.Prices[0].Close) + require.Equal(t, uint64(1), resp.Prices[1].BeginTimestamp) + require.Equal(t, uint64(2), resp.Prices[1].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[1].Open) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[1].High) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[1].Low) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[1].Close) +} + +func TestEachPeriodMultipleDataPoints(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keepertest.SeedPriceSnapshot(ctx, keeper, "100", 1) + keepertest.SeedPriceSnapshot(ctx, keeper, "101", 2) + keepertest.SeedPriceSnapshot(ctx, keeper, "102", 3) + keepertest.SeedPriceSnapshot(ctx, keeper, "99", 4) + keepertest.SeedPriceSnapshot(ctx, keeper, "98", 5) // should not be included since end is exclusive + + ctx = ctx.WithBlockTime(time.Unix(5, 0)) + wctx := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: keeper} + resp, err := wrapper.GetHistoricalPrices(wctx, &types.QueryGetHistoricalPricesRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + PeriodLengthInSeconds: 2, + NumOfPeriods: 2, + }) + require.Nil(t, err) + require.Equal(t, 2, len(resp.Prices)) + require.Equal(t, uint64(3), resp.Prices[0].BeginTimestamp) + require.Equal(t, uint64(5), resp.Prices[0].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].Open) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].High) + require.Equal(t, sdk.MustNewDecFromStr("99"), *resp.Prices[0].Low) + require.Equal(t, sdk.MustNewDecFromStr("99"), *resp.Prices[0].Close) + require.Equal(t, uint64(1), resp.Prices[1].BeginTimestamp) + require.Equal(t, uint64(3), resp.Prices[1].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[1].Open) + require.Equal(t, sdk.MustNewDecFromStr("101"), *resp.Prices[1].High) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[1].Low) + require.Equal(t, sdk.MustNewDecFromStr("101"), *resp.Prices[1].Close) +} + +func TestMissingDataPoints(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keepertest.SeedPriceSnapshot(ctx, keeper, "100", 1) + keepertest.SeedPriceSnapshot(ctx, keeper, "102", 3) + keepertest.SeedPriceSnapshot(ctx, keeper, "98", 5) // should not be included since end is exclusive + + ctx = ctx.WithBlockTime(time.Unix(5, 0)) + wctx := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: keeper} + resp, err := wrapper.GetHistoricalPrices(wctx, &types.QueryGetHistoricalPricesRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + PeriodLengthInSeconds: 1, + NumOfPeriods: 4, + }) + require.Nil(t, err) + require.Equal(t, 4, len(resp.Prices)) + require.Equal(t, uint64(4), resp.Prices[0].BeginTimestamp) + require.Equal(t, uint64(5), resp.Prices[0].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].Open) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].High) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].Low) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].Close) + require.Equal(t, uint64(3), resp.Prices[1].BeginTimestamp) + require.Equal(t, uint64(4), resp.Prices[1].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[1].Open) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[1].High) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[1].Low) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[1].Close) + require.Equal(t, uint64(2), resp.Prices[2].BeginTimestamp) + require.Equal(t, uint64(3), resp.Prices[2].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[2].Open) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[2].High) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[2].Low) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[2].Close) + require.Equal(t, uint64(1), resp.Prices[3].BeginTimestamp) + require.Equal(t, uint64(2), resp.Prices[3].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[3].Open) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[3].High) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[3].Low) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[3].Close) +} + +func TestDataPointsNotEarlyEnoughFullBar(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keepertest.SeedPriceSnapshot(ctx, keeper, "100", 2) + keepertest.SeedPriceSnapshot(ctx, keeper, "102", 3) // should not be included since end is exclusive + + ctx = ctx.WithBlockTime(time.Unix(3, 0)) + wctx := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: keeper} + resp, err := wrapper.GetHistoricalPrices(wctx, &types.QueryGetHistoricalPricesRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + PeriodLengthInSeconds: 1, + NumOfPeriods: 2, + }) + require.Nil(t, err) + require.Equal(t, 2, len(resp.Prices)) + require.Equal(t, uint64(2), resp.Prices[0].BeginTimestamp) + require.Equal(t, uint64(3), resp.Prices[0].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[0].Open) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[0].High) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[0].Low) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[0].Close) + require.Equal(t, uint64(1), resp.Prices[1].BeginTimestamp) + require.Equal(t, uint64(2), resp.Prices[1].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("0"), *resp.Prices[1].Open) + require.Equal(t, sdk.MustNewDecFromStr("0"), *resp.Prices[1].High) + require.Equal(t, sdk.MustNewDecFromStr("0"), *resp.Prices[1].Low) + require.Equal(t, sdk.MustNewDecFromStr("0"), *resp.Prices[1].Close) +} + +func TestDataPointsNotEarlyEnoughPartialBar(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keepertest.SeedPriceSnapshot(ctx, keeper, "100", 2) + keepertest.SeedPriceSnapshot(ctx, keeper, "102", 3) + keepertest.SeedPriceSnapshot(ctx, keeper, "98", 5) // should not be included since end is exclusive + + ctx = ctx.WithBlockTime(time.Unix(5, 0)) + wctx := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: keeper} + resp, err := wrapper.GetHistoricalPrices(wctx, &types.QueryGetHistoricalPricesRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + PeriodLengthInSeconds: 2, + NumOfPeriods: 2, + }) + require.Nil(t, err) + require.Equal(t, 2, len(resp.Prices)) + require.Equal(t, uint64(3), resp.Prices[0].BeginTimestamp) + require.Equal(t, uint64(5), resp.Prices[0].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].Open) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].High) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].Low) + require.Equal(t, sdk.MustNewDecFromStr("102"), *resp.Prices[0].Close) + require.Equal(t, uint64(1), resp.Prices[1].BeginTimestamp) + require.Equal(t, uint64(3), resp.Prices[1].EndTimestamp) + require.Equal(t, sdk.MustNewDecFromStr("0"), *resp.Prices[1].Open) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[1].High) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[1].Low) + require.Equal(t, sdk.MustNewDecFromStr("100"), *resp.Prices[1].Close) +} diff --git a/x/dex/keeper/query/grpc_query_get_latest_price.go b/x/dex/keeper/query/grpc_query_get_latest_price.go new file mode 100644 index 000000000..18fa7b5c1 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_latest_price.go @@ -0,0 +1,37 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) GetLatestPrice(goCtx context.Context, req *types.QueryGetLatestPriceRequest) (*types.QueryGetLatestPriceResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + prices := k.GetAllPrices(ctx, req.ContractAddr, types.Pair{PriceDenom: req.PriceDenom, AssetDenom: req.AssetDenom}) + + if len(prices) == 0 { + return &types.QueryGetLatestPriceResponse{ + Price: &types.Price{}, + }, nil + } + + latestPrice := prices[0] + + for _, price := range prices { + if price.SnapshotTimestampInSeconds > latestPrice.SnapshotTimestampInSeconds { + latestPrice = price + } + } + + return &types.QueryGetLatestPriceResponse{ + Price: latestPrice, + }, nil +} diff --git a/x/dex/keeper/query/grpc_query_get_latest_price_test.go b/x/dex/keeper/query/grpc_query_get_latest_price_test.go new file mode 100644 index 000000000..731ca6354 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_latest_price_test.go @@ -0,0 +1,30 @@ +package query_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/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGetLatestPrice(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keepertest.SeedPriceSnapshot(ctx, keeper, "100", 1) + keepertest.SeedPriceSnapshot(ctx, keeper, "101", 2) + keepertest.SeedPriceSnapshot(ctx, keeper, "99", 3) + + ctx = ctx.WithBlockTime(time.Unix(4, 0)) + wctx := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: keeper} + resp, err := wrapper.GetLatestPrice(wctx, &types.QueryGetLatestPriceRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + }) + require.Nil(t, err) + require.Equal(t, sdk.MustNewDecFromStr("99"), resp.Price.Price) +} diff --git a/x/dex/keeper/query/grpc_query_get_market_summary.go b/x/dex/keeper/query/grpc_query_get_market_summary.go new file mode 100644 index 000000000..9d869207f --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_market_summary.go @@ -0,0 +1,49 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) GetMarketSummary(goCtx context.Context, req *types.QueryGetMarketSummaryRequest) (*types.QueryGetMarketSummaryResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + prices := k.GetAllPrices(ctx, req.ContractAddr, types.Pair{PriceDenom: req.PriceDenom, AssetDenom: req.AssetDenom}) + cutoff := ctx.BlockTime().Unix() - int64(req.LookbackInSeconds) + maxPrice := sdk.ZeroDec() + minPrice := sdk.ZeroDec() + latestTimestamp := 0 + lastPrice := sdk.ZeroDec() + for _, price := range prices { + if price.SnapshotTimestampInSeconds < uint64(cutoff) { + continue + } + if maxPrice.IsZero() || price.Price.GT(maxPrice) { + maxPrice = price.Price + } + if minPrice.IsZero() || price.Price.LT(minPrice) { + minPrice = price.Price + } + if price.SnapshotTimestampInSeconds > uint64(latestTimestamp) { + latestTimestamp = int(price.SnapshotTimestampInSeconds) + lastPrice = price.Price + } + } + + zero := sdk.ZeroDec() + return &types.QueryGetMarketSummaryResponse{ + TotalVolume: &zero, // TODO: replace once we start tracking volume + TotalVolumeNotional: &zero, // TODO: replace once we start tracking volume + HighPrice: &maxPrice, + LowPrice: &minPrice, + LastPrice: &lastPrice, + }, nil +} diff --git a/x/dex/keeper/query/grpc_query_get_market_summary_test.go b/x/dex/keeper/query/grpc_query_get_market_summary_test.go new file mode 100644 index 000000000..e5f77b40a --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_market_summary_test.go @@ -0,0 +1,33 @@ +package query_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/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGetMarketSummary(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keepertest.SeedPriceSnapshot(ctx, keeper, "100", 1) + keepertest.SeedPriceSnapshot(ctx, keeper, "101", 2) + keepertest.SeedPriceSnapshot(ctx, keeper, "99", 3) + + ctx = ctx.WithBlockTime(time.Unix(4, 0)) + wctx := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: keeper} + resp, err := wrapper.GetMarketSummary(wctx, &types.QueryGetMarketSummaryRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + LookbackInSeconds: 4, + }) + require.Nil(t, err) + require.Equal(t, sdk.MustNewDecFromStr("99"), *resp.LowPrice) + require.Equal(t, sdk.MustNewDecFromStr("99"), *resp.LastPrice) + require.Equal(t, sdk.MustNewDecFromStr("101"), *resp.HighPrice) +} diff --git a/x/dex/keeper/query/grpc_query_get_order_count.go b/x/dex/keeper/query/grpc_query_get_order_count.go new file mode 100644 index 000000000..3a70cb0fe --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_order_count.go @@ -0,0 +1,19 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) GetOrderCount(c context.Context, req *types.QueryGetOrderCountRequest) (*types.QueryGetOrderCountResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + + return &types.QueryGetOrderCountResponse{Count: k.GetOrderCountState(ctx, req.ContractAddr, req.PriceDenom, req.AssetDenom, req.PositionDirection, *req.Price)}, nil +} diff --git a/x/dex/keeper/query/grpc_query_get_order_count_test.go b/x/dex/keeper/query/grpc_query_get_order_count_test.go new file mode 100644 index 000000000..30fa1baf7 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_order_count_test.go @@ -0,0 +1,29 @@ +package query_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/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGetOrderCount(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := query.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + keeper.SetOrderCount(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(1), 5) + price := sdk.NewDec(1) + query := types.QueryGetOrderCountRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + PositionDirection: types.PositionDirection_LONG, + Price: &price, + } + resp, err := wrapper.GetOrderCount(wctx, &query) + require.Nil(t, err) + require.Equal(t, uint64(5), resp.Count) +} diff --git a/x/dex/keeper/query/grpc_query_get_price.go b/x/dex/keeper/query/grpc_query_get_price.go new file mode 100644 index 000000000..f58d38645 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_price.go @@ -0,0 +1,25 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) GetPrice(goCtx context.Context, req *types.QueryGetPriceRequest) (*types.QueryGetPriceResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + price, found := k.GetPriceState(ctx, req.ContractAddr, req.Timestamp, types.Pair{PriceDenom: req.PriceDenom, AssetDenom: req.AssetDenom}) + + return &types.QueryGetPriceResponse{ + Price: &price, + Found: found, + }, nil +} diff --git a/x/dex/keeper/query/grpc_query_get_price_test.go b/x/dex/keeper/query/grpc_query_get_price_test.go new file mode 100644 index 000000000..c46d15f7e --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_price_test.go @@ -0,0 +1,32 @@ +package query_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/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGetPrice(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keepertest.SeedPriceSnapshot(ctx, keeper, "100", 1) + keepertest.SeedPriceSnapshot(ctx, keeper, "101", 2) + keepertest.SeedPriceSnapshot(ctx, keeper, "99", 3) + + ctx = ctx.WithBlockTime(time.Unix(4, 0)) + wctx := sdk.WrapSDKContext(ctx) + wrapper := query.KeeperWrapper{Keeper: keeper} + resp, err := wrapper.GetPrice(wctx, &types.QueryGetPriceRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + Timestamp: 2, + }) + require.Nil(t, err) + require.Equal(t, true, resp.Found) + require.Equal(t, sdk.MustNewDecFromStr("101"), resp.Price.Price) +} diff --git a/x/dex/keeper/query/grpc_query_get_prices.go b/x/dex/keeper/query/grpc_query_get_prices.go new file mode 100644 index 000000000..d4b8c619e --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_prices.go @@ -0,0 +1,24 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) GetPrices(goCtx context.Context, req *types.QueryGetPricesRequest) (*types.QueryGetPricesResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(goCtx) + + prices := k.GetAllPrices(ctx, req.ContractAddr, types.Pair{PriceDenom: req.PriceDenom, AssetDenom: req.AssetDenom}) + + return &types.QueryGetPricesResponse{ + Prices: prices, + }, nil +} diff --git a/x/dex/keeper/query/grpc_query_get_twaps.go b/x/dex/keeper/query/grpc_query_get_twaps.go new file mode 100644 index 000000000..b16667285 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_twaps.go @@ -0,0 +1,57 @@ +package query + +import ( + "context" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func (k KeeperWrapper) GetTwaps(goCtx context.Context, req *types.QueryGetTwapsRequest) (*types.QueryGetTwapsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(goCtx) + allRegisteredPairs := k.GetAllRegisteredPairs(ctx, req.ContractAddr) + twaps := []*types.Twap{} + for _, pair := range allRegisteredPairs { + prices := k.GetPricesForTwap(ctx, req.ContractAddr, pair, req.LookbackSeconds) + twaps = append(twaps, &types.Twap{ + Pair: &pair, //nolint:gosec,exportloopref // USING THE POINTER HERE COULD BE BAD, LET'S CHECK IT. + Twap: calculateTwap(ctx, prices, req.LookbackSeconds), + LookbackSeconds: req.LookbackSeconds, + }) + } + + return &types.QueryGetTwapsResponse{ + Twaps: twaps, + }, nil +} + +func calculateTwap(ctx sdk.Context, prices []*types.Price, lookback uint64) sdk.Dec { + if len(prices) == 0 { + return sdk.ZeroDec() + } + weightedPriceSum := sdk.ZeroDec() + lastTimestamp := ctx.BlockTime().Unix() + for _, price := range prices { + if uint64(ctx.BlockTime().Unix())-price.SnapshotTimestampInSeconds > lookback { + weight := lastTimestamp - ctx.BlockTime().Unix() + int64(lookback) + weightedPriceSum = weightedPriceSum.Add(price.Price.MulInt64(weight)) + break + } + weightedPriceSum = weightedPriceSum.Add( + price.Price.MulInt64(lastTimestamp - int64(price.SnapshotTimestampInSeconds)), + ) + lastTimestamp = int64(price.SnapshotTimestampInSeconds) + } + // not possible for division by 0 here since prices have unique timestamps + totalTimeSpan := ctx.BlockTime().Unix() - int64(prices[len(prices)-1].SnapshotTimestampInSeconds) + if totalTimeSpan > int64(lookback) { + totalTimeSpan = int64(lookback) + } + return weightedPriceSum.QuoInt64(totalTimeSpan) +} diff --git a/x/dex/keeper/query/grpc_query_get_twaps_test.go b/x/dex/keeper/query/grpc_query_get_twaps_test.go new file mode 100644 index 000000000..a03944205 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_get_twaps_test.go @@ -0,0 +1,143 @@ +package query_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/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +const GENESIS_TIME uint64 = 3600 + +func TestGetTwapsNoPriceSnapshot(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keeper.AddRegisteredPair(ctx, keepertest.TestContract, keepertest.TestPair) + wctx := sdk.WrapSDKContext(ctx) + var lookback uint64 = 10 + request := types.QueryGetTwapsRequest{ + ContractAddr: keepertest.TestContract, + LookbackSeconds: lookback, + } + expectedResponse := types.QueryGetTwapsResponse{ + Twaps: []*types.Twap{ + { + Pair: &keepertest.TestPair, + Twap: sdk.ZeroDec(), + LookbackSeconds: lookback, + }, + }, + } + wrapper := query.KeeperWrapper{Keeper: keeper} + t.Run("No snapshot", func(t *testing.T) { + response, err := wrapper.GetTwaps(wctx, &request) + require.NoError(t, err) + require.Equal(t, expectedResponse, *response) + }) +} + +func TestGetTwapsOnePriceSnapshot(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keeper.AddRegisteredPair(ctx, keepertest.TestContract, keepertest.TestPair) + ctx = ctx.WithBlockTime(time.Unix(int64(GENESIS_TIME)+5, 0)) + wctx := sdk.WrapSDKContext(ctx) + + snapshotPrice := sdk.MustNewDecFromStr("100.00") + keeper.SetPriceState(ctx, types.Price{ + SnapshotTimestampInSeconds: GENESIS_TIME, + Price: snapshotPrice, + Pair: &keepertest.TestPair, + }, keepertest.TestContract) + + var lookback uint64 = 10 + request := types.QueryGetTwapsRequest{ + ContractAddr: keepertest.TestContract, + LookbackSeconds: lookback, + } + expectedResponse := types.QueryGetTwapsResponse{ + Twaps: []*types.Twap{ + { + Pair: &keepertest.TestPair, + Twap: snapshotPrice, + LookbackSeconds: lookback, + }, + }, + } + wrapper := query.KeeperWrapper{Keeper: keeper} + t.Run("One snapshot", func(t *testing.T) { + response, err := wrapper.GetTwaps(wctx, &request) + require.NoError(t, err) + require.Equal(t, expectedResponse, *response) + }) + + lookback = 4 + request = types.QueryGetTwapsRequest{ + ContractAddr: keepertest.TestContract, + LookbackSeconds: lookback, + } + expectedResponse = types.QueryGetTwapsResponse{ + Twaps: []*types.Twap{ + { + Pair: &keepertest.TestPair, + Twap: snapshotPrice, + LookbackSeconds: lookback, + }, + }, + } + t.Run("One old snapshot", func(t *testing.T) { + response, err := wrapper.GetTwaps(wctx, &request) + require.NoError(t, err) + require.Equal(t, expectedResponse, *response) + }) +} + +func TestGetTwapsMultipleSnapshots(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + keeper.AddRegisteredPair(ctx, keepertest.TestContract, keepertest.TestPair) + ctx = ctx.WithBlockTime(time.Unix(int64(GENESIS_TIME)+20, 0)) + wctx := sdk.WrapSDKContext(ctx) + + snapshotPrices := []sdk.Dec{ + sdk.MustNewDecFromStr("100.00"), + sdk.MustNewDecFromStr("98.50"), + sdk.MustNewDecFromStr("101.00"), + } + timestampDeltas := []uint64{0, 10, 15} + for i := range snapshotPrices { + keeper.SetPriceState(ctx, types.Price{ + SnapshotTimestampInSeconds: GENESIS_TIME + timestampDeltas[i], + Price: snapshotPrices[i], + Pair: &keepertest.TestPair, + }, keepertest.TestContract) + } + + var lookback uint64 = 20 + request := types.QueryGetTwapsRequest{ + ContractAddr: keepertest.TestContract, + LookbackSeconds: lookback, + } + expectedTwap := snapshotPrices[0].MulInt64(10).Add( + snapshotPrices[1].MulInt64(15 - 10), + ).Add( + snapshotPrices[2].MulInt64(20 - 15), + ).QuoInt64(20) + require.Equal(t, sdk.MustNewDecFromStr("99.875"), expectedTwap) + expectedResponse := types.QueryGetTwapsResponse{ + Twaps: []*types.Twap{ + { + Pair: &keepertest.TestPair, + Twap: expectedTwap, + LookbackSeconds: lookback, + }, + }, + } + wrapper := query.KeeperWrapper{Keeper: keeper} + t.Run("Multiple snapshots", func(t *testing.T) { + response, err := wrapper.GetTwaps(wctx, &request) + require.NoError(t, err) + require.Equal(t, expectedResponse, *response) + }) +} diff --git a/x/dex/keeper/query/grpc_query_long_book.go b/x/dex/keeper/query/grpc_query_long_book.go new file mode 100644 index 000000000..d855059f2 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_long_book.go @@ -0,0 +1,50 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) LongBookAll(c context.Context, req *types.QueryAllLongBookRequest) (*types.QueryAllLongBookResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + + longBooks, pageRes, err := k.GetAllLongBookForPairPaginated( + ctx, + req.ContractAddr, + req.PriceDenom, + req.AssetDenom, + req.Pagination, + ) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types.QueryAllLongBookResponse{LongBook: longBooks, Pagination: pageRes}, nil +} + +func (k KeeperWrapper) LongBook(c context.Context, req *types.QueryGetLongBookRequest) (*types.QueryGetLongBookResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + price, err := sdk.NewDecFromStr(req.Price) + if err != nil { + return nil, err + } + longBook, found := k.GetLongBookByPrice(ctx, req.ContractAddr, price, req.PriceDenom, req.AssetDenom) + if !found { + return nil, sdkerrors.ErrKeyNotFound + } + + return &types.QueryGetLongBookResponse{LongBook: longBook}, nil +} diff --git a/x/dex/keeper/query/grpc_query_long_book_test.go b/x/dex/keeper/query/grpc_query_long_book_test.go new file mode 100644 index 000000000..ac29f3991 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_long_book_test.go @@ -0,0 +1,123 @@ +package query_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/testutil/nullify" + keeperquery "github.com/sei-protocol/sei-chain/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func TestLongBookQuerySingle(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := keeperquery.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + msgs := keepertest.CreateNLongBook(keeper, ctx, 2) + for _, tc := range []struct { + desc string + request *types.QueryGetLongBookRequest + response *types.QueryGetLongBookResponse + err error + }{ + { + desc: "First", + request: &types.QueryGetLongBookRequest{Price: msgs[0].Price.String(), ContractAddr: keepertest.TestContract, PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}, + response: &types.QueryGetLongBookResponse{LongBook: msgs[0]}, + }, + { + desc: "Second", + request: &types.QueryGetLongBookRequest{Price: msgs[1].Price.String(), ContractAddr: keepertest.TestContract, PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}, + response: &types.QueryGetLongBookResponse{LongBook: msgs[1]}, + }, + { + desc: "KeyNotFound", + request: &types.QueryGetLongBookRequest{Price: "100000", ContractAddr: keepertest.TestContract, PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}, + err: sdkerrors.ErrKeyNotFound, + }, + { + desc: "InvalidRequest", + err: status.Error(codes.InvalidArgument, "invalid request"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + response, err := wrapper.LongBook(wctx, tc.request) + if tc.err != nil { + require.ErrorIs(t, err, tc.err) + } else { + require.NoError(t, err) + require.Equal(t, + nullify.Fill(tc.response), + nullify.Fill(response), + ) + } + }) + } +} + +func TestLongBookQueryPaginated(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := keeperquery.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + msgs := keepertest.CreateNLongBook(keeper, ctx, 5) + + request := func(next []byte, offset, limit uint64, total bool) *types.QueryAllLongBookRequest { + return &types.QueryAllLongBookRequest{ + Pagination: &query.PageRequest{ + Key: next, + Offset: offset, + Limit: limit, + CountTotal: total, + }, + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + } + } + t.Run("ByOffset", func(t *testing.T) { + step := 2 + for i := 0; i < len(msgs); i += step { + resp, err := wrapper.LongBookAll(wctx, request(nil, uint64(i), uint64(step), false)) + require.NoError(t, err) + require.LessOrEqual(t, len(resp.LongBook), step) + require.Subset(t, + nullify.Fill(msgs), + nullify.Fill(resp.LongBook), + ) + } + }) + t.Run("ByKey", func(t *testing.T) { + step := 2 + var next []byte + for i := 0; i < len(msgs); i += step { + resp, err := wrapper.LongBookAll(wctx, request(next, 0, uint64(step), false)) + require.NoError(t, err) + require.LessOrEqual(t, len(resp.LongBook), step) + require.Subset(t, + nullify.Fill(msgs), + nullify.Fill(resp.LongBook), + ) + next = resp.Pagination.NextKey + } + }) + t.Run("Total", func(t *testing.T) { + resp, err := wrapper.LongBookAll(wctx, request(nil, 0, 0, true)) + require.NoError(t, err) + require.Equal(t, len(msgs), int(resp.Pagination.Total)) + require.ElementsMatch(t, + nullify.Fill(msgs), + nullify.Fill(resp.LongBook), + ) + }) + t.Run("InvalidRequest", func(t *testing.T) { + _, err := wrapper.LongBookAll(wctx, nil) + require.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request")) + }) +} diff --git a/x/dex/keeper/query/grpc_query_match_result.go b/x/dex/keeper/query/grpc_query_match_result.go new file mode 100644 index 000000000..95226904e --- /dev/null +++ b/x/dex/keeper/query/grpc_query_match_result.go @@ -0,0 +1,24 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) GetMatchResult(c context.Context, req *types.QueryGetMatchResultRequest) (*types.QueryGetMatchResultResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + + result, found := k.GetMatchResultState(ctx, req.ContractAddr) + if !found { + return nil, status.Error(codes.NotFound, "result not found") + } + + return &types.QueryGetMatchResultResponse{Result: result}, nil +} diff --git a/x/dex/keeper/query/grpc_query_order.go b/x/dex/keeper/query/grpc_query_order.go new file mode 100644 index 000000000..556c640a6 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_order.go @@ -0,0 +1,112 @@ +package query + +import ( + "context" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// To be deprecated once offchain query is built +func (k KeeperWrapper) GetOrder(c context.Context, req *types.QueryGetOrderByIDRequest) (*types.QueryGetOrderByIDResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + longBooks := k.GetAllLongBook(ctx, req.ContractAddr) + for _, longBook := range longBooks { + for _, allocation := range longBook.Entry.Allocations { + if allocation.OrderId == req.Id { + return &types.QueryGetOrderByIDResponse{ + Order: &types.Order{ + Id: req.Id, + Price: longBook.Price, + Quantity: allocation.Quantity, + PriceDenom: longBook.Entry.PriceDenom, + AssetDenom: longBook.Entry.AssetDenom, + OrderType: types.OrderType_LIMIT, + Status: types.OrderStatus_PLACED, + ContractAddr: req.ContractAddr, + PositionDirection: types.PositionDirection_LONG, + Account: allocation.Account, + }, + }, nil + } + } + } + shortBooks := k.GetAllShortBook(ctx, req.ContractAddr) + for _, shortBook := range shortBooks { + for _, allocation := range shortBook.Entry.Allocations { + if allocation.OrderId == req.Id { + return &types.QueryGetOrderByIDResponse{ + Order: &types.Order{ + Id: req.Id, + Price: shortBook.Price, + Quantity: allocation.Quantity, + PriceDenom: shortBook.Entry.PriceDenom, + AssetDenom: shortBook.Entry.AssetDenom, + OrderType: types.OrderType_LIMIT, + Status: types.OrderStatus_PLACED, + ContractAddr: req.ContractAddr, + PositionDirection: types.PositionDirection_SHORT, + Account: allocation.Account, + }, + }, nil + } + } + } + + return &types.QueryGetOrderByIDResponse{}, types.ErrInvalidOrderID +} + +// To be deprecated once offchain query is built +func (k KeeperWrapper) GetOrders(c context.Context, req *types.QueryGetOrdersRequest) (*types.QueryGetOrdersResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + orders := []*types.Order{} + longBooks := k.GetAllLongBook(ctx, req.ContractAddr) + for _, longBook := range longBooks { + for _, allocation := range longBook.Entry.Allocations { + if allocation.Account == req.Account { + orders = append(orders, &types.Order{ + Id: allocation.OrderId, + Price: longBook.Price, + Quantity: allocation.Quantity, + PriceDenom: longBook.Entry.PriceDenom, + AssetDenom: longBook.Entry.AssetDenom, + OrderType: types.OrderType_LIMIT, + Status: types.OrderStatus_PLACED, + ContractAddr: req.ContractAddr, + PositionDirection: types.PositionDirection_LONG, + Account: allocation.Account, + }) + } + } + } + shortBooks := k.GetAllShortBook(ctx, req.ContractAddr) + for _, shortBook := range shortBooks { + for _, allocation := range shortBook.Entry.Allocations { + if allocation.Account == req.Account { + orders = append(orders, &types.Order{ + Id: allocation.OrderId, + Price: shortBook.Price, + Quantity: allocation.Quantity, + PriceDenom: shortBook.Entry.PriceDenom, + AssetDenom: shortBook.Entry.AssetDenom, + OrderType: types.OrderType_LIMIT, + Status: types.OrderStatus_PLACED, + ContractAddr: req.ContractAddr, + PositionDirection: types.PositionDirection_SHORT, + Account: allocation.Account, + }) + } + } + } + + return &types.QueryGetOrdersResponse{Orders: orders}, nil +} diff --git a/x/dex/keeper/query/grpc_query_order_simulation.go b/x/dex/keeper/query/grpc_query_order_simulation.go new file mode 100644 index 000000000..e16308c95 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_order_simulation.go @@ -0,0 +1,120 @@ +package query + +import ( + "context" + "sort" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" +) + +type priceQuantity struct { + price sdk.Dec + quantity sdk.Dec +} + +// Note that this simulation is only accurate if it's called as part of the main Sei process (e.g. in Begin/EndBlock, transaction handler +// or contract querier), because it needs to access dex's in-memory state. +func (k KeeperWrapper) GetOrderSimulation(c context.Context, req *types.QueryOrderSimulationRequest) (*types.QueryOrderSimulationResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + matchedPriceQuantities := k.getMatchedPriceQuantities(ctx, req) + executedQuantity := sdk.ZeroDec() + for _, pq := range matchedPriceQuantities { + if executedQuantity.Add(pq.quantity).GTE(req.Order.Quantity) { + executedQuantity = req.Order.Quantity + break + } + executedQuantity = executedQuantity.Add(pq.quantity) + } + return &types.QueryOrderSimulationResponse{ + ExecutedQuantity: &executedQuantity, + }, nil +} + +func (k KeeperWrapper) getMatchedPriceQuantities(ctx sdk.Context, req *types.QueryOrderSimulationRequest) []priceQuantity { + orderDirection := req.Order.PositionDirection + // get existing liquidity + eligibleOrderBookPriceToQuantity := map[string]sdk.Dec{} + if orderDirection == types.PositionDirection_SHORT { + for _, lb := range k.GetAllLongBookForPair(ctx, req.ContractAddr, req.Order.PriceDenom, req.Order.AssetDenom) { + if req.Order.Price.IsZero() || req.Order.Price.LTE(lb.GetPrice()) { + eligibleOrderBookPriceToQuantity[lb.GetPrice().String()] = lb.GetOrderEntry().Quantity + } + } + } else { + for _, sb := range k.GetAllShortBookForPair(ctx, req.ContractAddr, req.Order.PriceDenom, req.Order.AssetDenom) { + if req.Order.Price.IsZero() || req.Order.Price.GTE(sb.GetPrice()) { + eligibleOrderBookPriceToQuantity[sb.GetPrice().String()] = sb.GetOrderEntry().Quantity + } + } + } + + // exclude liquidity to be cancelled + pair := types.Pair{PriceDenom: req.Order.PriceDenom, AssetDenom: req.Order.AssetDenom} + for _, cancel := range dexutils.GetMemState(ctx.Context()).GetBlockCancels(ctx, types.ContractAddress(req.ContractAddr), pair).Get() { + var cancelledAllocation *types.Allocation + var found bool + if cancel.PositionDirection == types.PositionDirection_LONG { + cancelledAllocation, found = k.GetLongAllocationForOrderID(ctx, req.ContractAddr, cancel.PriceDenom, cancel.AssetDenom, cancel.Price, cancel.Id) + } else { + cancelledAllocation, found = k.GetShortAllocationForOrderID(ctx, req.ContractAddr, cancel.PriceDenom, cancel.AssetDenom, cancel.Price, cancel.Id) + } + if !found { + continue + } + if q, ok := eligibleOrderBookPriceToQuantity[cancel.Price.String()]; ok { + eligibleOrderBookPriceToQuantity[cancel.Price.String()] = q.Sub(cancelledAllocation.Quantity) + } + } + + priceQuantities := []priceQuantity{} + for price, quantity := range eligibleOrderBookPriceToQuantity { + if quantity.IsPositive() { + priceQuantities = append(priceQuantities, priceQuantity{price: sdk.MustNewDecFromStr(price), quantity: quantity}) + } + } + sort.Slice(priceQuantities, func(i int, j int) bool { + if orderDirection == types.PositionDirection_SHORT { + // short order corresponds to long book which needs to be in descending order + return priceQuantities[i].price.GT(priceQuantities[j].price) + } + // long order corresponds to long book which needs to be in ascending order + return priceQuantities[i].price.LT(priceQuantities[j].price) + }) + + // exclude liquidity to be taken + ptr := 0 + for _, order := range dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(req.ContractAddr), pair).GetSortedMarketOrders(orderDirection) { + // If existing market order has price zero, it means it doesn't specify a worst price and will always have precedence over the simulated + // order + if !order.Price.IsZero() { + // If the simulated order doesn't specify a worst price, no existing order with a worst price will take liquidity from it + if req.Order.Price.IsZero() { + break + } + if orderDirection == types.PositionDirection_LONG && order.Price.LT(req.Order.Price) { + break + } + if orderDirection == types.PositionDirection_SHORT && order.Price.GT(req.Order.Price) { + break + } + } + remainingQuantity := order.Quantity + for ptr < len(priceQuantities) { + if remainingQuantity.LTE(priceQuantities[ptr].quantity) { + priceQuantities[ptr].quantity = priceQuantities[ptr].quantity.Sub(remainingQuantity) + break + } + remainingQuantity = remainingQuantity.Sub(priceQuantities[ptr].quantity) + ptr++ + } + } + return priceQuantities[ptr:] +} diff --git a/x/dex/keeper/query/grpc_query_order_simulation_test.go b/x/dex/keeper/query/grpc_query_order_simulation_test.go new file mode 100644 index 000000000..07bfb2ccb --- /dev/null +++ b/x/dex/keeper/query/grpc_query_order_simulation_test.go @@ -0,0 +1,101 @@ +package query_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/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/require" +) + +func TestGetOrderSimulation(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := query.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + + testOrder := types.Order{ + Account: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Price: sdk.MustNewDecFromStr("10"), + Quantity: sdk.MustNewDecFromStr("5"), + PositionDirection: types.PositionDirection_LONG, + } + + // no liquidity + res, err := wrapper.GetOrderSimulation(wctx, &types.QueryOrderSimulationRequest{Order: &testOrder, ContractAddr: keepertest.TestContract}) + require.Nil(t, err) + require.Equal(t, sdk.ZeroDec(), *res.ExecutedQuantity) + + // partial liquidity on orderbook + keeper.SetShortBook(ctx, keepertest.TestContract, types.ShortBook{ + Price: sdk.MustNewDecFromStr("9"), + Entry: &types.OrderEntry{ + Price: sdk.MustNewDecFromStr("9"), + Quantity: sdk.MustNewDecFromStr("2"), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + }) + res, err = wrapper.GetOrderSimulation(wctx, &types.QueryOrderSimulationRequest{Order: &testOrder, ContractAddr: keepertest.TestContract}) + require.Nil(t, err) + require.Equal(t, sdk.MustNewDecFromStr("2"), *res.ExecutedQuantity) + + // full liquidity on orderbook + keeper.SetShortBook(ctx, keepertest.TestContract, types.ShortBook{ + Price: sdk.MustNewDecFromStr("8"), + Entry: &types.OrderEntry{ + Price: sdk.MustNewDecFromStr("8"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + }) + res, err = wrapper.GetOrderSimulation(wctx, &types.QueryOrderSimulationRequest{Order: &testOrder, ContractAddr: keepertest.TestContract}) + require.Nil(t, err) + require.Equal(t, sdk.MustNewDecFromStr("3"), *res.ExecutedQuantity) + + // liquidity taken by cancel + keeper.SetShortBook(ctx, keepertest.TestContract, types.ShortBook{ + Price: sdk.MustNewDecFromStr("9"), + Entry: &types.OrderEntry{ + Price: sdk.MustNewDecFromStr("9"), + Quantity: sdk.MustNewDecFromStr("2"), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Allocations: []*types.Allocation{ + { + Account: keepertest.TestAccount, + Quantity: sdk.MustNewDecFromStr("2"), + OrderId: 1, + }, + }, + }, + }) + dexutils.GetMemState(ctx.Context()).GetBlockCancels(ctx, types.ContractAddress(keepertest.TestContract), keepertest.TestPair).Add( + &types.Cancellation{Id: 1, Price: sdk.MustNewDecFromStr("9"), PositionDirection: types.PositionDirection_SHORT, PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}, + ) + res, err = wrapper.GetOrderSimulation(wctx, &types.QueryOrderSimulationRequest{Order: &testOrder, ContractAddr: keepertest.TestContract}) + require.Nil(t, err) + require.Equal(t, sdk.OneDec(), *res.ExecutedQuantity) + + // liquidity taken by earlier market orders + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(keepertest.TestContract), keepertest.TestPair).Add( + &types.Order{ + Account: keepertest.TestAccount, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Price: sdk.MustNewDecFromStr("11"), + Quantity: sdk.MustNewDecFromStr("2"), + PositionDirection: types.PositionDirection_LONG, + OrderType: types.OrderType_MARKET, + }, + ) + res, err = wrapper.GetOrderSimulation(wctx, &types.QueryOrderSimulationRequest{Order: &testOrder, ContractAddr: keepertest.TestContract}) + require.Nil(t, err) + require.Equal(t, sdk.ZeroDec(), *res.ExecutedQuantity) +} diff --git a/x/dex/keeper/query/grpc_query_order_test.go b/x/dex/keeper/query/grpc_query_order_test.go new file mode 100644 index 000000000..32025934a --- /dev/null +++ b/x/dex/keeper/query/grpc_query_order_test.go @@ -0,0 +1,75 @@ +package query_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/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGetOrderById(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"), + }, + }, + }, + }) + query := types.QueryGetOrderByIDRequest{ + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Id: 1, + } + resp, err := wrapper.GetOrder(wctx, &query) + require.Nil(t, err) + require.Equal(t, uint64(1), resp.Order.Id) + require.Equal(t, types.OrderStatus_PLACED, resp.Order.Status) +} + +func TestGetOrders(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"), + }, + }, + }, + }) + + 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)) +} diff --git a/x/dex/keeper/query/grpc_query_params.go b/x/dex/keeper/query/grpc_query_params.go new file mode 100644 index 000000000..2b7772ef2 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_params.go @@ -0,0 +1,19 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) Params(c context.Context, req *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + + return &types.QueryParamsResponse{Params: k.GetParams(ctx)}, nil +} diff --git a/x/dex/keeper/query/grpc_query_params_test.go b/x/dex/keeper/query/grpc_query_params_test.go new file mode 100644 index 000000000..ff1eecdbe --- /dev/null +++ b/x/dex/keeper/query/grpc_query_params_test.go @@ -0,0 +1,23 @@ +package query_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestParamsQuery(t *testing.T) { + keeper, ctx := testkeeper.DexKeeper(t) + wrapper := query.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + params := types.DefaultParams() + keeper.SetParams(ctx, params) + + response, err := wrapper.Params(wctx, &types.QueryParamsRequest{}) + require.NoError(t, err) + require.Equal(t, &types.QueryParamsResponse{Params: params}, response) +} diff --git a/x/dex/keeper/query/grpc_query_registered_contract.go b/x/dex/keeper/query/grpc_query_registered_contract.go new file mode 100644 index 000000000..63e870e86 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_registered_contract.go @@ -0,0 +1,24 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) GetRegisteredContract(c context.Context, req *types.QueryRegisteredContractRequest) (*types.QueryRegisteredContractResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + + contractInfo, err := k.GetContract(ctx, req.ContractAddr) + if err != nil { + return nil, err + } + + return &types.QueryRegisteredContractResponse{ContractInfo: &contractInfo}, nil +} diff --git a/x/dex/keeper/query/grpc_query_registered_contract_test.go b/x/dex/keeper/query/grpc_query_registered_contract_test.go new file mode 100644 index 000000000..15a6f751a --- /dev/null +++ b/x/dex/keeper/query/grpc_query_registered_contract_test.go @@ -0,0 +1,42 @@ +package query_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/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestRegisteredContractQuery(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := query.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + expectedContractInfo := types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + CodeId: 1, + RentBalance: 1000000, + } + err := keeper.SetContract(ctx, &types.ContractInfoV2{ + Creator: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + CodeId: 1, + RentBalance: 1000000, + }) + require.NoError(t, err) + + request := types.QueryRegisteredContractRequest{ + ContractAddr: keepertest.TestContract, + } + expectedResponse := types.QueryRegisteredContractResponse{ + ContractInfo: &expectedContractInfo, + } + t.Run("Registered Contract query", func(t *testing.T) { + response, err := wrapper.GetRegisteredContract(wctx, &request) + require.NoError(t, err) + require.Equal(t, expectedResponse, *response) + }) +} diff --git a/x/dex/keeper/query/grpc_query_registered_pairs.go b/x/dex/keeper/query/grpc_query_registered_pairs.go new file mode 100644 index 000000000..e32f68163 --- /dev/null +++ b/x/dex/keeper/query/grpc_query_registered_pairs.go @@ -0,0 +1,21 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) GetRegisteredPairs(c context.Context, req *types.QueryRegisteredPairsRequest) (*types.QueryRegisteredPairsResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + ctx := sdk.UnwrapSDKContext(c) + + registeredPairs := k.GetAllRegisteredPairs(ctx, req.ContractAddr) + + return &types.QueryRegisteredPairsResponse{Pairs: registeredPairs}, nil +} diff --git a/x/dex/keeper/query/grpc_query_registered_pairs_test.go b/x/dex/keeper/query/grpc_query_registered_pairs_test.go new file mode 100644 index 000000000..2b6007a4a --- /dev/null +++ b/x/dex/keeper/query/grpc_query_registered_pairs_test.go @@ -0,0 +1,39 @@ +package query_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/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestRegisteredPairsQuery(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := query.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + expectedPair := types.Pair{ + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + PriceTicksize: &keepertest.TestTicksize, + QuantityTicksize: &keepertest.TestTicksize, + } + keeper.AddRegisteredPair(ctx, keepertest.TestContract, expectedPair) + + var expectedRegisteredPairs []types.Pair + expectedRegisteredPairs = append(expectedRegisteredPairs, expectedPair) + + request := types.QueryRegisteredPairsRequest{ + ContractAddr: keepertest.TestContract, + } + expectedResponse := types.QueryRegisteredPairsResponse{ + Pairs: expectedRegisteredPairs, + } + t.Run("Registered Pairs query", func(t *testing.T) { + response, err := wrapper.GetRegisteredPairs(wctx, &request) + require.NoError(t, err) + require.Equal(t, expectedResponse, *response) + }) +} diff --git a/x/dex/keeper/query/grpc_query_short_book.go b/x/dex/keeper/query/grpc_query_short_book.go new file mode 100644 index 000000000..21855a20b --- /dev/null +++ b/x/dex/keeper/query/grpc_query_short_book.go @@ -0,0 +1,46 @@ +package query + +import ( + "context" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/sei-protocol/sei-chain/x/dex/types" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +func (k KeeperWrapper) ShortBookAll(c context.Context, req *types.QueryAllShortBookRequest) (*types.QueryAllShortBookResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + + shortBooks, pageRes, err := k.GetAllShortBookForPairPaginated( + ctx, req.ContractAddr, req.PriceDenom, req.AssetDenom, req.Pagination, + ) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return &types.QueryAllShortBookResponse{ShortBook: shortBooks, Pagination: pageRes}, nil +} + +func (k KeeperWrapper) ShortBook(c context.Context, req *types.QueryGetShortBookRequest) (*types.QueryGetShortBookResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + price, err := sdk.NewDecFromStr(req.Price) + if err != nil { + return nil, err + } + shortBook, found := k.GetShortBookByPrice(ctx, req.ContractAddr, price, req.PriceDenom, req.AssetDenom) + if !found { + return nil, sdkerrors.ErrKeyNotFound + } + + return &types.QueryGetShortBookResponse{ShortBook: shortBook}, nil +} diff --git a/x/dex/keeper/query/grpc_query_short_book_test.go b/x/dex/keeper/query/grpc_query_short_book_test.go new file mode 100644 index 000000000..df919d7fc --- /dev/null +++ b/x/dex/keeper/query/grpc_query_short_book_test.go @@ -0,0 +1,123 @@ +package query_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/stretchr/testify/require" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/testutil/nullify" + keeperquery "github.com/sei-protocol/sei-chain/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func TestShortBookQuerySingle(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := keeperquery.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + msgs := keepertest.CreateNShortBook(keeper, ctx, 2) + for _, tc := range []struct { + desc string + request *types.QueryGetShortBookRequest + response *types.QueryGetShortBookResponse + err error + }{ + { + desc: "First", + request: &types.QueryGetShortBookRequest{Price: msgs[0].Price.String(), ContractAddr: keepertest.TestContract, PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}, + response: &types.QueryGetShortBookResponse{ShortBook: msgs[0]}, + }, + { + desc: "Second", + request: &types.QueryGetShortBookRequest{Price: msgs[1].Price.String(), ContractAddr: keepertest.TestContract, PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}, + response: &types.QueryGetShortBookResponse{ShortBook: msgs[1]}, + }, + { + desc: "KeyNotFound", + request: &types.QueryGetShortBookRequest{Price: "10000", ContractAddr: keepertest.TestContract, PriceDenom: keepertest.TestPriceDenom, AssetDenom: keepertest.TestAssetDenom}, + err: sdkerrors.ErrKeyNotFound, + }, + { + desc: "InvalidRequest", + err: status.Error(codes.InvalidArgument, "invalid request"), + }, + } { + t.Run(tc.desc, func(t *testing.T) { + response, err := wrapper.ShortBook(wctx, tc.request) + if tc.err != nil { + require.ErrorIs(t, err, tc.err) + } else { + require.NoError(t, err) + require.Equal(t, + nullify.Fill(tc.response), + nullify.Fill(response), + ) + } + }) + } +} + +func TestShortBookQueryPaginated(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + wrapper := keeperquery.KeeperWrapper{Keeper: keeper} + wctx := sdk.WrapSDKContext(ctx) + msgs := keepertest.CreateNShortBook(keeper, ctx, 5) + + request := func(next []byte, offset, limit uint64, total bool) *types.QueryAllShortBookRequest { + return &types.QueryAllShortBookRequest{ + Pagination: &query.PageRequest{ + Key: next, + Offset: offset, + Limit: limit, + CountTotal: total, + }, + ContractAddr: keepertest.TestContract, + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + } + } + t.Run("ByOffset", func(t *testing.T) { + step := 2 + for i := 0; i < len(msgs); i += step { + resp, err := wrapper.ShortBookAll(wctx, request(nil, uint64(i), uint64(step), false)) + require.NoError(t, err) + require.LessOrEqual(t, len(resp.ShortBook), step) + require.Subset(t, + nullify.Fill(msgs), + nullify.Fill(resp.ShortBook), + ) + } + }) + t.Run("ByKey", func(t *testing.T) { + step := 2 + var next []byte + for i := 0; i < len(msgs); i += step { + resp, err := wrapper.ShortBookAll(wctx, request(next, 0, uint64(step), false)) + require.NoError(t, err) + require.LessOrEqual(t, len(resp.ShortBook), step) + require.Subset(t, + nullify.Fill(msgs), + nullify.Fill(resp.ShortBook), + ) + next = resp.Pagination.NextKey + } + }) + t.Run("Total", func(t *testing.T) { + resp, err := wrapper.ShortBookAll(wctx, request(nil, 0, 0, true)) + require.NoError(t, err) + require.Equal(t, len(msgs), int(resp.Pagination.Total)) + require.ElementsMatch(t, + nullify.Fill(msgs), + nullify.Fill(resp.ShortBook), + ) + }) + t.Run("InvalidRequest", func(t *testing.T) { + _, err := wrapper.ShortBookAll(wctx, nil) + require.ErrorIs(t, err, status.Error(codes.InvalidArgument, "invalid request")) + }) +} diff --git a/x/dex/keeper/query/keeper_wrapper.go b/x/dex/keeper/query/keeper_wrapper.go new file mode 100644 index 000000000..e1fcfdd04 --- /dev/null +++ b/x/dex/keeper/query/keeper_wrapper.go @@ -0,0 +1,9 @@ +package query + +import ( + "github.com/sei-protocol/sei-chain/x/dex/keeper" +) + +type KeeperWrapper struct { + *keeper.Keeper +} diff --git a/x/dex/keeper/short_book.go b/x/dex/keeper/short_book.go new file mode 100644 index 000000000..3e5763401 --- /dev/null +++ b/x/dex/keeper/short_book.go @@ -0,0 +1,165 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" +) + +// SetShortBook set a specific shortBook in the store +func (k Keeper) SetShortBook(ctx sdk.Context, contractAddr string, shortBook types.ShortBook) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(false, contractAddr, shortBook.Entry.PriceDenom, shortBook.Entry.AssetDenom)) + b := k.Cdc.MustMarshal(&shortBook) + store.Set(GetKeyForShortBook(shortBook), b) +} + +func (k Keeper) SetShortOrderBookEntry(ctx sdk.Context, contractAddr string, shortBook types.OrderBookEntry) { + k.SetShortBook(ctx, contractAddr, *shortBook.(*types.ShortBook)) +} + +func (k Keeper) GetShortBookByPrice(ctx sdk.Context, contractAddr string, price sdk.Dec, priceDenom string, assetDenom string) (val types.ShortBook, found bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(false, contractAddr, priceDenom, assetDenom)) + b := store.Get(GetKeyForPrice(price)) + if b == nil { + return val, false + } + k.Cdc.MustUnmarshal(b, &val) + return val, true +} + +func (k Keeper) GetShortOrderBookEntryByPrice(ctx sdk.Context, contractAddr string, price sdk.Dec, priceDenom string, assetDenom string) (types.OrderBookEntry, bool) { + entry, found := k.GetShortBookByPrice(ctx, contractAddr, price, priceDenom, assetDenom) + return &entry, found +} + +func (k Keeper) RemoveShortBookByPrice(ctx sdk.Context, contractAddr string, price sdk.Dec, priceDenom string, assetDenom string) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(false, contractAddr, priceDenom, assetDenom)) + store.Delete(GetKeyForPrice(price)) +} + +// GetAllShortBook returns all shortBook +func (k Keeper) GetAllShortBook(ctx sdk.Context, contractAddr string) (list []types.ShortBook) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.ContractKeyPrefix(types.ShortBookKey, contractAddr)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.ShortBook + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, val) + } + + return +} + +func (k Keeper) GetAllShortBookForPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string) (list []types.OrderBookEntry) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(false, contractAddr, priceDenom, assetDenom)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.ShortBook + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, &val) + } + + return +} + +func (k Keeper) GetTopNShortBooksForPair(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, n int) (list []types.OrderBookEntry) { + if n == 0 { + return + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(false, contractAddr, priceDenom, assetDenom)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + var val types.ShortBook + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, &val) + if len(list) == n { + break + } + } + + return +} + +// Load the first (up to) N short book entries whose price are larger than the specified limit +// in sorted order. +// Parameters: +// +// n: the largest number of entries to load +// startExclusive: the price limit +func (k Keeper) GetTopNShortBooksForPairStarting(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, n int, startExclusive sdk.Dec) (list []types.OrderBookEntry) { + if n == 0 { + return + } + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(false, contractAddr, priceDenom, assetDenom)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + + // Fast-forward + // TODO: add iterator interface that allows starting at a certain subkey under prefix + for ; iterator.Valid(); iterator.Next() { + key := dexutils.BytesToDec(iterator.Key()) + if key.GT(startExclusive) { + break + } + } + + for ; iterator.Valid(); iterator.Next() { + var val types.ShortBook + k.Cdc.MustUnmarshal(iterator.Value(), &val) + list = append(list, &val) + if len(list) == n { + break + } + } + + return +} + +func (k Keeper) GetAllShortBookForPairPaginated(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, page *query.PageRequest) (list []types.ShortBook, pageRes *query.PageResponse, err error) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.OrderBookPrefix(false, contractAddr, priceDenom, assetDenom)) + + pageRes, err = query.Paginate(store, page, func(key []byte, value []byte) error { + var shortBook types.ShortBook + if err := k.Cdc.Unmarshal(value, &shortBook); err != nil { + return err + } + + list = append(list, shortBook) + return nil + }) + + return +} + +func (k Keeper) GetShortAllocationForOrderID(ctx sdk.Context, contractAddr string, priceDenom string, assetDenom string, price sdk.Dec, orderID uint64) (*types.Allocation, bool) { + orderBook, found := k.GetShortBookByPrice(ctx, contractAddr, price, priceDenom, assetDenom) + if !found { + return nil, false + } + for _, allocation := range orderBook.Entry.Allocations { + if allocation.OrderId == orderID { + return allocation, true + } + } + return nil, false +} + +func (k Keeper) RemoveAllShortBooksForContract(ctx sdk.Context, contractAddr string) { + k.removeAllForPrefix(ctx, types.OrderBookContractPrefix(false, contractAddr)) +} + +func GetKeyForShortBook(shortBook types.ShortBook) []byte { + return GetKeyForPrice(shortBook.Entry.Price) +} diff --git a/x/dex/keeper/short_book_test.go b/x/dex/keeper/short_book_test.go new file mode 100644 index 000000000..62e709dfd --- /dev/null +++ b/x/dex/keeper/short_book_test.go @@ -0,0 +1,92 @@ +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/utils" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestShortBookGet(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + items := keepertest.CreateNShortBook(keeper, ctx, 10) + for i, item := range items { + got, found := keeper.GetShortBookByPrice(ctx, keepertest.TestContract, sdk.NewDec(int64(i)), keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.True(t, found) + require.Equal(t, + nullify.Fill(&item), + nullify.Fill(&got), + ) + } +} + +func TestShortBookRemove(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + items := keepertest.CreateNShortBook(keeper, ctx, 10) + for i := range items { + keeper.RemoveShortBookByPrice(ctx, keepertest.TestContract, sdk.NewDec(int64(i)), keepertest.TestPriceDenom, keepertest.TestAssetDenom) + _, found := keeper.GetShortBookByPrice(ctx, keepertest.TestContract, sdk.NewDec(int64(i)), keepertest.TestPriceDenom, keepertest.TestAssetDenom) + require.False(t, found) + } +} + +func TestShortBookGetAll(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + items := keepertest.CreateNShortBook(keeper, ctx, 10) + require.ElementsMatch(t, + nullify.Fill(items), + nullify.Fill(keeper.GetAllShortBook(ctx, keepertest.TestContract)), + ) +} + +func TestGetTopNShortBooksForPair(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + prices := []string{"9.99", "0.001", "90.0", "10", "10.01", "9.9", "9.0", "1"} + for _, price := range prices { + keeper.SetShortBook(ctx, keepertest.TestContract, types.ShortBook{ + Price: sdk.MustNewDecFromStr(price), + Entry: &types.OrderEntry{ + Price: sdk.MustNewDecFromStr(price), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + }) + } + expected := []sdk.Dec{ + sdk.MustNewDecFromStr("0.001"), + sdk.MustNewDecFromStr("1"), + sdk.MustNewDecFromStr("9.0"), + sdk.MustNewDecFromStr("9.9"), + sdk.MustNewDecFromStr("9.99"), + sdk.MustNewDecFromStr("10"), + sdk.MustNewDecFromStr("10.01"), + sdk.MustNewDecFromStr("90.0"), + } + loaded := keeper.GetTopNShortBooksForPair(ctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom, 10) + require.Equal(t, expected, utils.Map(loaded, func(b types.OrderBookEntry) sdk.Dec { return b.GetPrice() })) +} + +func TestGetTopNShortBooksForPairStarting(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + prices := []string{"9.99", "0.001", "90.0", "10", "10.01", "9.9", "9.0", "1"} + for _, price := range prices { + keeper.SetShortBook(ctx, keepertest.TestContract, types.ShortBook{ + Price: sdk.MustNewDecFromStr(price), + Entry: &types.OrderEntry{ + Price: sdk.MustNewDecFromStr(price), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + }, + }) + } + expected := []sdk.Dec{ + sdk.MustNewDecFromStr("9.0"), + sdk.MustNewDecFromStr("9.9"), + } + loaded := keeper.GetTopNShortBooksForPairStarting(ctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom, 2, sdk.MustNewDecFromStr("1")) + require.Equal(t, expected, utils.Map(loaded, func(b types.OrderBookEntry) sdk.Dec { return b.GetPrice() })) +} diff --git a/x/dex/keeper/tick.go b/x/dex/keeper/tick.go new file mode 100644 index 000000000..d89295266 --- /dev/null +++ b/x/dex/keeper/tick.go @@ -0,0 +1,60 @@ +package keeper + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// contract_addr, pair -> tick size +func (k Keeper) SetPriceTickSizeForPair(ctx sdk.Context, contractAddr string, pair types.Pair, ticksize sdk.Dec) error { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.RegisteredPairPrefix(contractAddr)) + + pair, found := k.GetRegisteredPair(ctx, contractAddr, pair.PriceDenom, pair.AssetDenom) + if !found { + return types.ErrPairNotRegistered + } + pair.PriceTicksize = &ticksize + store.Set(types.PairPrefix(pair.PriceDenom, pair.AssetDenom), k.Cdc.MustMarshal(&pair)) + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeSetPriceTickSize, + sdk.NewAttribute(types.AttributeKeyContractAddress, contractAddr), + )) + return nil +} + +func (k Keeper) GetPriceTickSizeForPair(ctx sdk.Context, contractAddr string, pair types.Pair) (sdk.Dec, bool) { + pair, found := k.GetRegisteredPair(ctx, contractAddr, pair.PriceDenom, pair.AssetDenom) + if !found { + return sdk.ZeroDec(), false + } + return *pair.PriceTicksize, true +} + +// contract_addr, pair -> tick size +func (k Keeper) SetQuantityTickSizeForPair(ctx sdk.Context, contractAddr string, pair types.Pair, ticksize sdk.Dec) error { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.RegisteredPairPrefix(contractAddr)) + + pair, found := k.GetRegisteredPair(ctx, contractAddr, pair.PriceDenom, pair.AssetDenom) + if !found { + return types.ErrPairNotRegistered + } + pair.QuantityTicksize = &ticksize + store.Set(types.PairPrefix(pair.PriceDenom, pair.AssetDenom), k.Cdc.MustMarshal(&pair)) + + ctx.EventManager().EmitEvent(sdk.NewEvent( + types.EventTypeSetQuantityTickSize, + sdk.NewAttribute(types.AttributeKeyContractAddress, contractAddr), + )) + return nil +} + +func (k Keeper) GetQuantityTickSizeForPair(ctx sdk.Context, contractAddr string, pair types.Pair) (sdk.Dec, bool) { + pair, found := k.GetRegisteredPair(ctx, contractAddr, pair.PriceDenom, pair.AssetDenom) + if !found { + return sdk.ZeroDec(), false + } + return *pair.QuantityTicksize, true +} diff --git a/x/dex/keeper/tick_test.go b/x/dex/keeper/tick_test.go new file mode 100644 index 000000000..80abe43e9 --- /dev/null +++ b/x/dex/keeper/tick_test.go @@ -0,0 +1,42 @@ +package keeper_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPriceTickSizeGet(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + // TEST_PAIR = atom/usdc pair + contractAddr := "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m" + ticksize, found := keeper.GetPriceTickSizeForPair(ctx, contractAddr, keepertest.TestPair) + assert.Equal(t, ticksize, sdk.ZeroDec()) + assert.False(t, found) + + keeper.AddRegisteredPair(ctx, contractAddr, keepertest.TestPair) + err := keeper.SetPriceTickSizeForPair(ctx, contractAddr, keepertest.TestPair, sdk.NewDec(2)) + require.NoError(t, err) + ticksize, found = keeper.GetPriceTickSizeForPair(ctx, contractAddr, keepertest.TestPair) + assert.Equal(t, ticksize, sdk.NewDec(2)) + assert.True(t, found) +} + +func TestQuantityTickSizeGet(t *testing.T) { + keeper, ctx := keepertest.DexKeeper(t) + // TEST_PAIR = atom/usdc pair + contractAddr := "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m" + ticksize, found := keeper.GetQuantityTickSizeForPair(ctx, contractAddr, keepertest.TestPair) + assert.Equal(t, ticksize, sdk.ZeroDec()) + assert.False(t, found) + + keeper.AddRegisteredPair(ctx, contractAddr, keepertest.TestPair) + err := keeper.SetQuantityTickSizeForPair(ctx, contractAddr, keepertest.TestPair, sdk.NewDec(2)) + require.NoError(t, err) + ticksize, found = keeper.GetQuantityTickSizeForPair(ctx, contractAddr, keepertest.TestPair) + assert.Equal(t, ticksize, sdk.NewDec(2)) + assert.True(t, found) +} diff --git a/x/dex/keeper/utils/order_book.go b/x/dex/keeper/utils/order_book.go new file mode 100644 index 000000000..c232ac27f --- /dev/null +++ b/x/dex/keeper/utils/order_book.go @@ -0,0 +1,89 @@ +package utils + +import ( + "fmt" + "sync" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/utils/datastructures" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func PopulateOrderbook( + ctx sdk.Context, + keeper *keeper.Keeper, + contractAddr types.ContractAddress, + pair types.Pair, +) *types.OrderBook { + // TODO update to param + loadCnt := int(keeper.GetOrderBookEntriesPerLoad(ctx)) + longLoader := func(lctx sdk.Context, startExclusive sdk.Dec, withLimit bool) []types.OrderBookEntry { + if !withLimit { + return keeper.GetTopNLongBooksForPair(lctx, string(contractAddr), pair.PriceDenom, pair.AssetDenom, loadCnt) + } + return keeper.GetTopNLongBooksForPairStarting(lctx, string(contractAddr), pair.PriceDenom, pair.AssetDenom, loadCnt, startExclusive) + } + shortLoader := func(lctx sdk.Context, startExclusive sdk.Dec, withLimit bool) []types.OrderBookEntry { + if !withLimit { + return keeper.GetTopNShortBooksForPair(lctx, string(contractAddr), pair.PriceDenom, pair.AssetDenom, loadCnt) + } + return keeper.GetTopNShortBooksForPairStarting(lctx, string(contractAddr), pair.PriceDenom, pair.AssetDenom, loadCnt, startExclusive) + } + longSetter := func(lctx sdk.Context, o types.OrderBookEntry) { + keeper.SetLongOrderBookEntry(lctx, string(contractAddr), o) + err := keeper.SetOrderCount(lctx, string(contractAddr), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_LONG, o.GetPrice(), uint64(len(o.GetOrderEntry().GetAllocations()))) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error setting order count: %s", err)) + } + } + shortSetter := func(lctx sdk.Context, o types.OrderBookEntry) { + keeper.SetShortOrderBookEntry(lctx, string(contractAddr), o) + err := keeper.SetOrderCount(lctx, string(contractAddr), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_SHORT, o.GetPrice(), uint64(len(o.GetOrderEntry().GetAllocations()))) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error setting order count: %s", err)) + } + } + longDeleter := func(lctx sdk.Context, o types.OrderBookEntry) { + keeper.RemoveLongBookByPrice(lctx, string(contractAddr), o.GetPrice(), pair.PriceDenom, pair.AssetDenom) + err := keeper.SetOrderCount(lctx, string(contractAddr), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_LONG, o.GetPrice(), 0) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error setting order count: %s", err)) + } + } + shortDeleter := func(lctx sdk.Context, o types.OrderBookEntry) { + keeper.RemoveShortBookByPrice(lctx, string(contractAddr), o.GetPrice(), pair.PriceDenom, pair.AssetDenom) + err := keeper.SetOrderCount(lctx, string(contractAddr), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_SHORT, o.GetPrice(), 0) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("error setting order count: %s", err)) + } + } + return &types.OrderBook{ + Contract: contractAddr, + Pair: pair, + Longs: types.NewCachedSortedOrderBookEntries(longLoader, longSetter, longDeleter), + Shorts: types.NewCachedSortedOrderBookEntries(shortLoader, shortSetter, shortDeleter), + } +} + +func PopulateAllOrderbooks( + ctx sdk.Context, + keeper *keeper.Keeper, + contractsAndPairs map[string][]types.Pair, +) *datastructures.TypedNestedSyncMap[string, types.PairString, *types.OrderBook] { + var orderBooks = datastructures.NewTypedNestedSyncMap[string, types.PairString, *types.OrderBook]() + wg := sync.WaitGroup{} + for contractAddr, pairs := range contractsAndPairs { + orderBooks.Store(contractAddr, datastructures.NewTypedSyncMap[types.PairString, *types.OrderBook]()) + for _, pair := range pairs { + wg.Add(1) + go func(contractAddr string, pair types.Pair) { + defer wg.Done() + orderBook := PopulateOrderbook(ctx, keeper, types.ContractAddress(contractAddr), pair) + orderBooks.StoreNested(contractAddr, types.GetPairString(&pair), orderBook) + }(contractAddr, pair) + } + } + wg.Wait() + return orderBooks +} diff --git a/x/dex/keeper/utils/price.go b/x/dex/keeper/utils/price.go new file mode 100644 index 000000000..9552c2fb7 --- /dev/null +++ b/x/dex/keeper/utils/price.go @@ -0,0 +1,28 @@ +package utils + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/exchange" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func SetPriceStateFromExecutionOutcome( + ctx sdk.Context, + keeper *keeper.Keeper, + contractAddr types.ContractAddress, + pair types.Pair, + outcome exchange.ExecutionOutcome, +) { + if outcome.TotalQuantity.IsZero() { + return + } + + avgPrice := outcome.TotalNotional.Quo(outcome.TotalQuantity) + priceState := types.Price{ + Pair: &pair, + Price: avgPrice, + SnapshotTimestampInSeconds: uint64(ctx.BlockTime().Unix()), + } + keeper.SetPriceState(ctx, priceState, string(contractAddr)) +} diff --git a/x/dex/keeper/utils/wasm.go b/x/dex/keeper/utils/wasm.go new file mode 100644 index 000000000..8cc335455 --- /dev/null +++ b/x/dex/keeper/utils/wasm.go @@ -0,0 +1,116 @@ +package utils + +import ( + "encoding/json" + "fmt" + "strings" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/utils" + "github.com/sei-protocol/sei-chain/utils/logging" + "github.com/sei-protocol/sei-chain/utils/metrics" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +const ErrWasmModuleInstCPUFeatureLiteral = "Error instantiating module: CpuFeature" +const SudoGasEventKey = "sudo-gas" +const LogAfter = 5 * time.Second + +func getMsgType(msg interface{}) string { + switch msg.(type) { + case types.SudoSettlementMsg: + return "settlement" + case types.SudoOrderPlacementMsg: + return "bulk_order_placements" + case types.SudoOrderCancellationMsg: + return "bulk_order_cancellations" + default: + return "unknown" + } +} + +func sudo(sdkCtx sdk.Context, k *keeper.Keeper, contractAddress sdk.AccAddress, wasmMsg []byte, msgType string) ([]byte, uint64, error) { + defer utils.PanicHandler(func(err any) { + utils.MetricsPanicCallback(err, sdkCtx, fmt.Sprintf("%s|%s", contractAddress, msgType)) + })() + + // Measure the time it takes to execute the contract in WASM + defer metrics.MeasureSudoExecutionDuration(time.Now(), msgType) + // set up a tmp context to prevent race condition in reading gas consumed + // Note that the limit will effectively serve as a soft limit since it's + // possible for the actual computation to go above the specified limit, but + // the associated contract would be charged corresponding rent. + gasLimit, err := k.GetContractGasLimit(sdkCtx, contractAddress) + if err != nil { + return nil, 0, err + } + tmpCtx := sdkCtx.WithGasMeter(sdk.NewGasMeterWithMultiplier(sdkCtx, gasLimit)) + data, err := sudoWithoutOutOfGasPanic(tmpCtx, k, contractAddress, wasmMsg, msgType) + gasConsumed := tmpCtx.GasMeter().GasConsumed() + sdkCtx.EventManager().EmitEvent( + sdk.NewEvent( + SudoGasEventKey, + sdk.NewAttribute("consumed", fmt.Sprintf("%d", gasConsumed)), + sdk.NewAttribute("type", msgType), + sdk.NewAttribute("contract", contractAddress.String()), + sdk.NewAttribute("height", fmt.Sprintf("%d", sdkCtx.BlockHeight())), + ), + ) + if gasConsumed > 0 { + sdkCtx.GasMeter().ConsumeGas(gasConsumed, "sudo") + } + if hasErrInstantiatingWasmModuleDueToCPUFeature(err) { + panic(utils.DecorateHardFailError(err)) + } + return data, gasConsumed, err +} + +func sudoWithoutOutOfGasPanic(ctx sdk.Context, k *keeper.Keeper, contractAddress []byte, wasmMsg []byte, logName string) ([]byte, error) { + defer func() { + if err := recover(); err != nil { + // only propagate panic if the error is NOT out of gas + if _, ok := err.(sdk.ErrorOutOfGas); !ok { + panic(err) + } + ctx.Logger().Error(fmt.Sprintf("%s %s is out of gas", sdk.AccAddress(contractAddress).String(), logName)) + } + }() + return logging.LogIfNotDoneAfter(ctx.Logger(), func() ([]byte, error) { + return k.WasmKeeper.Sudo(ctx, contractAddress, wasmMsg) + }, LogAfter, fmt.Sprintf("wasm_sudo_%s", logName)) +} + +func hasErrInstantiatingWasmModuleDueToCPUFeature(err error) bool { + if err == nil { + return false + } + return strings.Contains(err.Error(), ErrWasmModuleInstCPUFeatureLiteral) +} + +func CallContractSudo(sdkCtx sdk.Context, k *keeper.Keeper, contractAddr string, msg interface{}, gasAllowance uint64) ([]byte, error) { + contractAddress, err := sdk.AccAddressFromBech32(contractAddr) + if err != nil { + sdkCtx.Logger().Error(err.Error()) + return []byte{}, err + } + wasmMsg, err := json.Marshal(msg) + if err != nil { + sdkCtx.Logger().Error(err.Error()) + return []byte{}, err + } + msgType := getMsgType(msg) + data, gasUsed, suderr := sudo(sdkCtx, k, contractAddress, wasmMsg, msgType) + if err := k.ChargeRentForGas(sdkCtx, contractAddr, gasUsed, gasAllowance); err != nil { + metrics.IncrementSudoFailCount(msgType) + sdkCtx.Logger().Error(err.Error()) + return []byte{}, err + } + if suderr != nil { + metrics.IncrementSudoFailCount(msgType) + sdkCtx.Logger().Error(suderr.Error()) + return []byte{}, suderr + } + return data, nil +} diff --git a/x/dex/migrations/v10_to_v11.go b/x/dex/migrations/v10_to_v11.go new file mode 100644 index 000000000..4f35a5e68 --- /dev/null +++ b/x/dex/migrations/v10_to_v11.go @@ -0,0 +1,45 @@ +package migrations + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +var DexPrefixes = []string{ + types.LongBookKey, + types.ShortBookKey, + "TriggerBook-value-", + types.OrderKey, + types.TwapKey, + types.RegisteredPairKey, + types.OrderKey, + types.CancelKey, + types.AccountActiveOrdersKey, + types.NextOrderIDKey, + types.MatchResultKey, + types.MemOrderKey, + types.MemCancelKey, + types.MemDepositKey, + types.PriceKey, + "SettlementEntry-", + "NextSettlementID-", +} + +func V10ToV11(ctx sdk.Context, dexkeeper keeper.Keeper) error { + dexkeeper.CreateModuleAccount(ctx) + + // this will nuke all old prefixes data in the store + for _, prefixKey := range DexPrefixes { + store := prefix.NewStore(ctx.KVStore(dexkeeper.GetStoreKey()), []byte(prefixKey)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + store.Delete(iterator.Key()) + } + } + + return nil +} diff --git a/x/dex/migrations/v10_to_v11_test.go b/x/dex/migrations/v10_to_v11_test.go new file mode 100644 index 000000000..775c20928 --- /dev/null +++ b/x/dex/migrations/v10_to_v11_test.go @@ -0,0 +1,60 @@ +package migrations_test + +import ( + "testing" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMigrate10to11(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + // write old contract + store := ctx.KVStore(dexkeeper.GetStoreKey()) + value := []byte("test_value") + store.Set(types.ContractKeyPrefix(types.LongBookKey, keepertest.TestContract), value) + store.Set(types.OrderBookPrefix(false, keepertest.TestContract, "USDC", "ATOM"), value) + store.Set(TriggerOrderBookPrefix(keepertest.TestContract, "USDC", "ATOM"), value) + store.Set(types.PricePrefix(keepertest.TestContract, "USDC", "ATOM"), value) + store.Set(migrations.SettlementEntryPrefix(keepertest.TestContract, "USDC", "ATOM"), value) + store.Set(types.RegisteredPairPrefix(keepertest.TestContract), value) + store.Set(types.OrderPrefix(keepertest.TestContract), value) + store.Set(types.NextOrderIDPrefix(keepertest.TestContract), value) + store.Set(migrations.NextSettlementIDPrefix(keepertest.TestContract, "USDC", "ATOM"), value) + store.Set(types.MatchResultPrefix(keepertest.TestContract), value) + store.Set(types.MemOrderPrefixForPair(keepertest.TestContract, "USDC", "ATOM"), value) + store.Set(types.MemCancelPrefixForPair(keepertest.TestContract, "USDC", "ATOM"), value) + store.Set(types.MemOrderPrefix(keepertest.TestContract), value) + store.Set(types.MemCancelPrefix(keepertest.TestContract), value) + store.Set(types.MemDepositPrefix(keepertest.TestContract), value) + + err := migrations.V10ToV11(ctx, *dexkeeper) + require.NoError(t, err) + + require.False(t, store.Has(types.ContractKeyPrefix(types.LongBookKey, keepertest.TestContract))) + require.False(t, store.Has(types.OrderBookPrefix(false, keepertest.TestContract, "USDC", "ATOM"))) + require.False(t, store.Has(TriggerOrderBookPrefix(keepertest.TestContract, "USDC", "ATOM"))) + require.False(t, store.Has(types.PricePrefix(keepertest.TestContract, "USDC", "ATOM"))) + require.False(t, store.Has(migrations.SettlementEntryPrefix(keepertest.TestContract, "USDC", "ATOM"))) + require.False(t, store.Has(types.RegisteredPairPrefix(keepertest.TestContract))) + require.False(t, store.Has(types.OrderPrefix(keepertest.TestContract))) + require.False(t, store.Has(types.NextOrderIDPrefix(keepertest.TestContract))) + require.False(t, store.Has(migrations.NextSettlementIDPrefix(keepertest.TestContract, "USDC", "ATOM"))) + require.False(t, store.Has(types.MatchResultPrefix(keepertest.TestContract))) + require.False(t, store.Has(types.MemOrderPrefixForPair(keepertest.TestContract, "USDC", "ATOM"))) + require.False(t, store.Has(types.MemCancelPrefixForPair(keepertest.TestContract, "USDC", "ATOM"))) + require.False(t, store.Has(types.MemOrderPrefix(keepertest.TestContract))) + require.False(t, store.Has(types.MemCancelPrefix(keepertest.TestContract))) + require.False(t, store.Has(types.MemDepositPrefix(keepertest.TestContract))) +} + +func TriggerOrderBookPrefix(contractAddr string, priceDenom string, assetDenom string) []byte { + prefix := types.KeyPrefix("TriggerBook-value-") + + return append( + append(prefix, types.AddressKeyPrefix(contractAddr)...), + types.PairPrefix(priceDenom, assetDenom)..., + ) +} diff --git a/x/dex/migrations/v11_to_v12.go b/x/dex/migrations/v11_to_v12.go new file mode 100644 index 000000000..66c68a44a --- /dev/null +++ b/x/dex/migrations/v11_to_v12.go @@ -0,0 +1,13 @@ +package migrations + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func V11ToV12(ctx sdk.Context, dexkeeper keeper.Keeper) error { + defaultParams := types.DefaultParams() + dexkeeper.SetParams(ctx, defaultParams) + return nil +} diff --git a/x/dex/migrations/v11_to_v12_test.go b/x/dex/migrations/v11_to_v12_test.go new file mode 100644 index 000000000..bf0baf6ca --- /dev/null +++ b/x/dex/migrations/v11_to_v12_test.go @@ -0,0 +1,31 @@ +package migrations_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/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMigrate11to12(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + // write old params + defaultParams := types.Params{ + PriceSnapshotRetention: 1, + SudoCallGasPrice: sdk.OneDec(), + BeginBlockGasLimit: 1, + EndBlockGasLimit: 1, + DefaultGasPerOrder: 1, + DefaultGasPerCancel: 1, + } + dexkeeper.SetParams(ctx, defaultParams) + + // migrate to default params + err := migrations.V11ToV12(ctx, *dexkeeper) + require.NoError(t, err) + params := dexkeeper.GetParams(ctx) + require.Equal(t, params, types.DefaultParams()) +} diff --git a/x/dex/migrations/v12_to_v13.go b/x/dex/migrations/v12_to_v13.go new file mode 100644 index 000000000..9bd5891f7 --- /dev/null +++ b/x/dex/migrations/v12_to_v13.go @@ -0,0 +1,15 @@ +package migrations + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func V12ToV13(ctx sdk.Context, dexkeeper keeper.Keeper) error { + // This isn't the cleanest migration since it could potentially revert any dex params we have changed + // but we haven't, so we'll just do this. + defaultParams := types.DefaultParams() + dexkeeper.SetParams(ctx, defaultParams) + return nil +} diff --git a/x/dex/migrations/v12_to_v13_test.go b/x/dex/migrations/v12_to_v13_test.go new file mode 100644 index 000000000..fd70a50ce --- /dev/null +++ b/x/dex/migrations/v12_to_v13_test.go @@ -0,0 +1,32 @@ +package migrations_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/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMigrate12to13(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + // write old params + prevParams := types.Params{ + PriceSnapshotRetention: 1, + SudoCallGasPrice: sdk.OneDec(), + BeginBlockGasLimit: 1, + EndBlockGasLimit: 1, + DefaultGasPerOrder: 1, + DefaultGasPerCancel: 1, + } + dexkeeper.SetParams(ctx, prevParams) + + // migrate to default params + err := migrations.V12ToV13(ctx, *dexkeeper) + require.NoError(t, err) + params := dexkeeper.GetParams(ctx) + require.Equal(t, params.GasAllowancePerSettlement, uint64(types.DefaultGasAllowancePerSettlement)) + require.Equal(t, params.MinProcessableRent, uint64(types.DefaultMinProcessableRent)) +} diff --git a/x/dex/migrations/v13_to_v14.go b/x/dex/migrations/v13_to_v14.go new file mode 100644 index 000000000..062cc35c8 --- /dev/null +++ b/x/dex/migrations/v13_to_v14.go @@ -0,0 +1,69 @@ +package migrations + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/utils" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func V13ToV14(ctx sdk.Context, dexkeeper keeper.Keeper) error { + setDefaultParams(ctx, dexkeeper) + + for _, contractAddr := range getAllContractAddresses(ctx, dexkeeper) { + convertOrderBookEntryKeysForContract(ctx, dexkeeper, contractAddr) + } + return nil +} + +func setDefaultParams(ctx sdk.Context, dexkeeper keeper.Keeper) { + // This isn't the cleanest migration since it could potentially revert any dex params we have changed + // but we haven't, so we'll just do this. + defaultParams := types.DefaultParams() + dexkeeper.SetParams(ctx, defaultParams) +} + +func getAllContractAddresses(ctx sdk.Context, dexkeeper keeper.Keeper) []string { + contracts := dexkeeper.GetAllContractInfo(ctx) + return utils.Map(contracts, func(c types.ContractInfoV2) string { return c.ContractAddr }) +} + +func convertOrderBookEntryKeysForContract(ctx sdk.Context, dexkeeper keeper.Keeper, contractAddr string) { + ctx.Logger().Info(fmt.Sprintf("converting order book entry keys for contract %s", contractAddr)) + store := prefix.NewStore(ctx.KVStore(dexkeeper.GetStoreKey()), types.ContractKeyPrefix(types.LongBookKey, contractAddr)) + iterator := sdk.KVStorePrefixIterator(store, []byte{}) + + keyToVal := map[string][]byte{} + for ; iterator.Valid(); iterator.Next() { + keyToVal[string(iterator.Key())] = iterator.Value() + } + iterator.Close() + + for key, v := range keyToVal { + store.Delete([]byte(key)) + var val types.LongBook + dexkeeper.Cdc.MustUnmarshal(v, &val) + newKey := append(types.PairPrefix(val.Entry.PriceDenom, val.Entry.AssetDenom), keeper.GetKeyForPrice(val.Price)...) + store.Set(newKey, v) + } + + store = prefix.NewStore(ctx.KVStore(dexkeeper.GetStoreKey()), types.ContractKeyPrefix(types.ShortBookKey, contractAddr)) + iterator = sdk.KVStorePrefixIterator(store, []byte{}) + + keyToVal = map[string][]byte{} + for ; iterator.Valid(); iterator.Next() { + keyToVal[string(iterator.Key())] = iterator.Value() + } + iterator.Close() + + for key, v := range keyToVal { + store.Delete([]byte(key)) + var val types.ShortBook + dexkeeper.Cdc.MustUnmarshal(v, &val) + newKey := append(types.PairPrefix(val.Entry.PriceDenom, val.Entry.AssetDenom), keeper.GetKeyForPrice(val.Price)...) + store.Set(newKey, v) + } +} diff --git a/x/dex/migrations/v13_to_v14_test.go b/x/dex/migrations/v13_to_v14_test.go new file mode 100644 index 000000000..b9937b3e3 --- /dev/null +++ b/x/dex/migrations/v13_to_v14_test.go @@ -0,0 +1,79 @@ +package migrations_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/stretchr/testify/require" +) + +func TestMigrate13to14(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + // write old params + prevParams := types.Params{ + PriceSnapshotRetention: 1, + SudoCallGasPrice: sdk.OneDec(), + BeginBlockGasLimit: 1, + EndBlockGasLimit: 1, + DefaultGasPerOrder: 1, + DefaultGasPerCancel: 1, + GasAllowancePerSettlement: 1, + MinProcessableRent: 1, + } + dexkeeper.SetParams(ctx, prevParams) + + dexkeeper.SetContract(ctx, &types.ContractInfoV2{ContractAddr: keepertest.TestContract}) + longStore := prefix.NewStore(ctx.KVStore(dexkeeper.GetStoreKey()), types.OrderBookPrefix( + true, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, + )) + longEntry := types.LongBook{ + Price: sdk.MustNewDecFromStr("10.123"), + Entry: &types.OrderEntry{ + Price: sdk.MustNewDecFromStr("10.123"), + Quantity: sdk.MustNewDecFromStr("5"), + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + }, + } + longEntryKey, err := longEntry.GetPrice().Marshal() + require.Nil(t, err) + longStore.Set(longEntryKey, dexkeeper.Cdc.MustMarshal(&longEntry)) + + shortStore := prefix.NewStore(ctx.KVStore(dexkeeper.GetStoreKey()), types.OrderBookPrefix( + false, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom, + )) + shortEntry := types.ShortBook{ + Price: sdk.MustNewDecFromStr("12.456"), + Entry: &types.OrderEntry{ + Price: sdk.MustNewDecFromStr("12.456"), + Quantity: sdk.MustNewDecFromStr("4"), + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + }, + } + shortEntryKey, err := shortEntry.GetPrice().Marshal() + require.Nil(t, err) + shortStore.Set(shortEntryKey, dexkeeper.Cdc.MustMarshal(&shortEntry)) + + // migrate to default params + err = migrations.V13ToV14(ctx, *dexkeeper) + require.NoError(t, err) + params := dexkeeper.GetParams(ctx) + require.Equal(t, params.OrderBookEntriesPerLoad, uint64(types.DefaultOrderBookEntriesPerLoad)) + + require.Nil(t, longStore.Get(longEntryKey)) + require.Nil(t, shortStore.Get(shortEntryKey)) + var loadedLongEntry types.LongBook + dexkeeper.Cdc.MustUnmarshal(longStore.Get(utils.DecToBigEndian(longEntry.Price)), &loadedLongEntry) + require.Equal(t, longEntry.Price, loadedLongEntry.Price) + require.Equal(t, *longEntry.Entry, *loadedLongEntry.Entry) + var loadedShortEntry types.ShortBook + dexkeeper.Cdc.MustUnmarshal(shortStore.Get(utils.DecToBigEndian(shortEntry.Price)), &loadedShortEntry) + require.Equal(t, shortEntry.Price, loadedShortEntry.Price) + require.Equal(t, *shortEntry.Entry, *loadedShortEntry.Entry) +} diff --git a/x/dex/migrations/v14_to_v15.go b/x/dex/migrations/v14_to_v15.go new file mode 100644 index 000000000..158990fb1 --- /dev/null +++ b/x/dex/migrations/v14_to_v15.go @@ -0,0 +1,15 @@ +package migrations + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func V14ToV15(ctx sdk.Context, dexkeeper keeper.Keeper) error { + // This isn't the cleanest migration since it could potentially revert any dex params we have changed + // but we haven't, so we'll just do this. + defaultParams := types.DefaultParams() + dexkeeper.SetParams(ctx, defaultParams) + return nil +} diff --git a/x/dex/migrations/v14_to_v15_test.go b/x/dex/migrations/v14_to_v15_test.go new file mode 100644 index 000000000..f6d76f1c7 --- /dev/null +++ b/x/dex/migrations/v14_to_v15_test.go @@ -0,0 +1,26 @@ +package migrations_test + +import ( + "testing" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMigrate14to15(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + // write old params + prevParams := types.DefaultParams() + prevParams.MaxOrderPerPrice = 0 + prevParams.MaxPairsPerContract = 0 + dexkeeper.SetParams(ctx, prevParams) + + // migrate to default params + err := migrations.V14ToV15(ctx, *dexkeeper) + require.NoError(t, err) + params := dexkeeper.GetParams(ctx) + require.Equal(t, params.MaxOrderPerPrice, uint64(types.DefaultMaxOrderPerPrice)) + require.Equal(t, params.MaxPairsPerContract, uint64(types.DefaultMaxPairsPerContract)) +} diff --git a/x/dex/migrations/v15_to_v16.go b/x/dex/migrations/v15_to_v16.go new file mode 100644 index 000000000..3e5f9eb39 --- /dev/null +++ b/x/dex/migrations/v15_to_v16.go @@ -0,0 +1,15 @@ +package migrations + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func V15ToV16(ctx sdk.Context, dexkeeper keeper.Keeper) error { + // This isn't the cleanest migration since it could potentially revert any dex params we have changed + // but we haven't, so we'll just do this. + defaultParams := types.DefaultParams() + dexkeeper.SetParams(ctx, defaultParams) + return nil +} diff --git a/x/dex/migrations/v15_to_v16_test.go b/x/dex/migrations/v15_to_v16_test.go new file mode 100644 index 000000000..48fa655ff --- /dev/null +++ b/x/dex/migrations/v15_to_v16_test.go @@ -0,0 +1,24 @@ +package migrations_test + +import ( + "testing" + + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMigrate15to16(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + // write old params + prevParams := types.DefaultParams() + prevParams.DefaultGasPerOrderDataByte = 0 + dexkeeper.SetParams(ctx, prevParams) + + // migrate to default params + err := migrations.V15ToV16(ctx, *dexkeeper) + require.NoError(t, err) + params := dexkeeper.GetParams(ctx) + require.Equal(t, params.DefaultGasPerOrderDataByte, uint64(30)) +} diff --git a/x/dex/migrations/v16_to_v17.go b/x/dex/migrations/v16_to_v17.go new file mode 100644 index 000000000..7066db584 --- /dev/null +++ b/x/dex/migrations/v16_to_v17.go @@ -0,0 +1,110 @@ +package migrations + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/goutils" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +const OldPairSeparator = '|' + +func OldPairPrefix(priceDenom string, assetDenom string) []byte { + return goutils.ImmutableAppend(goutils.ImmutableAppend([]byte(priceDenom), OldPairSeparator), []byte(assetDenom)...) +} + +func V16ToV17(ctx sdk.Context, dexkeeper keeper.Keeper) error { + rootStore := ctx.KVStore(dexkeeper.GetStoreKey()) + + handler := func(oldPref []byte, newPref []byte) { + store := prefix.NewStore(rootStore, oldPref) + kv := map[string][]byte{} + iter := store.Iterator(nil, nil) + defer iter.Close() + for ; iter.Valid(); iter.Next() { + kv[string(iter.Key())] = iter.Value() + } + for k, v := range kv { + kbz := []byte(k) + store.Delete(kbz) + rootStore.Set(goutils.ImmutableAppend(newPref, kbz...), v) + } + } + + for _, c := range dexkeeper.GetAllContractInfo(ctx) { + for _, p := range dexkeeper.GetAllRegisteredPairs(ctx, c.ContractAddr) { + // long order book + handler( + goutils.ImmutableAppend( + types.OrderBookContractPrefix(true, c.ContractAddr), + OldPairPrefix(p.PriceDenom, p.AssetDenom)..., + ), + types.OrderBookPrefix(true, c.ContractAddr, p.PriceDenom, p.AssetDenom), + ) + + // short order book + handler( + goutils.ImmutableAppend( + types.OrderBookContractPrefix(false, c.ContractAddr), + OldPairPrefix(p.PriceDenom, p.AssetDenom)..., + ), + types.OrderBookPrefix(false, c.ContractAddr, p.PriceDenom, p.AssetDenom), + ) + + // price + handler( + goutils.ImmutableAppend( + types.PriceContractPrefix(c.ContractAddr), + OldPairPrefix(p.PriceDenom, p.AssetDenom)..., + ), + types.PricePrefix(c.ContractAddr, p.PriceDenom, p.AssetDenom), + ) + + // order count (long) + handler( + goutils.ImmutableAppend( + goutils.ImmutableAppend(types.KeyPrefix(types.LongOrderCountKey), types.AddressKeyPrefix(c.ContractAddr)...), + OldPairPrefix(p.PriceDenom, p.AssetDenom)..., + ), + types.OrderCountPrefix(c.ContractAddr, p.PriceDenom, p.AssetDenom, true), + ) + + // order count (short) + handler( + goutils.ImmutableAppend( + goutils.ImmutableAppend(types.KeyPrefix(types.ShortOrderCountKey), types.AddressKeyPrefix(c.ContractAddr)...), + OldPairPrefix(p.PriceDenom, p.AssetDenom)..., + ), + types.OrderCountPrefix(c.ContractAddr, p.PriceDenom, p.AssetDenom, false), + ) + + // registered pair + k := goutils.ImmutableAppend(types.RegisteredPairPrefix(c.ContractAddr), OldPairPrefix(p.PriceDenom, p.AssetDenom)...) + pair := rootStore.Get(k) + rootStore.Delete(k) + rootStore.Set( + goutils.ImmutableAppend(types.RegisteredPairPrefix(c.ContractAddr), types.PairPrefix(p.PriceDenom, p.AssetDenom)...), + pair, + ) + } + } + + // asset list + pref := types.KeyPrefix(types.AssetListKey) + store := prefix.NewStore(rootStore, pref) + kv := map[string][]byte{} + iter := store.Iterator(nil, nil) + for ; iter.Valid(); iter.Next() { + kv[string(iter.Key())] = iter.Value() + } + iter.Close() + for k, v := range kv { + kbz := []byte(k) + store.Delete(kbz) + denom := string(kbz) + newKbz := types.AssetListPrefix(denom) + rootStore.Set(newKbz, v) + } + return nil +} diff --git a/x/dex/migrations/v16_to_v17_test.go b/x/dex/migrations/v16_to_v17_test.go new file mode 100644 index 000000000..ac6c7ad0d --- /dev/null +++ b/x/dex/migrations/v16_to_v17_test.go @@ -0,0 +1,89 @@ +package migrations_test + +import ( + "testing" + + "github.com/sei-protocol/goutils" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMigrate16to17(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + store := ctx.KVStore(dexkeeper.GetStoreKey()) + dexkeeper.SetContract(ctx, &types.ContractInfoV2{ContractAddr: keepertest.TestContract}) + // add registered pair using the old key + pair := types.Pair{PriceDenom: keepertest.TestPair.PriceDenom, AssetDenom: keepertest.TestPair.AssetDenom} + store.Set( + goutils.ImmutableAppend( + types.RegisteredPairPrefix(keepertest.TestContract), + migrations.OldPairPrefix(keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom)..., + ), + dexkeeper.Cdc.MustMarshal(&pair), + ) + + value := []byte("test_value") + store.Set(goutils.ImmutableAppend( + types.OrderBookContractPrefix(true, keepertest.TestContract), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ), value) + store.Set(goutils.ImmutableAppend( + types.OrderBookContractPrefix(false, keepertest.TestContract), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ), value) + store.Set(goutils.ImmutableAppend( + types.PriceContractPrefix(keepertest.TestContract), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ), value) + store.Set(goutils.ImmutableAppend( + goutils.ImmutableAppend(types.KeyPrefix(types.LongOrderCountKey), types.AddressKeyPrefix(keepertest.TestContract)...), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ), value) + store.Set(goutils.ImmutableAppend( + goutils.ImmutableAppend(types.KeyPrefix(types.ShortOrderCountKey), types.AddressKeyPrefix(keepertest.TestContract)...), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ), value) + store.Set(goutils.ImmutableAppend(types.KeyPrefix(types.AssetListKey), []byte(pair.PriceDenom)...), value) + + err := migrations.V16ToV17(ctx, *dexkeeper) + require.NoError(t, err) + + require.False(t, store.Has(goutils.ImmutableAppend( + types.OrderBookContractPrefix(true, keepertest.TestContract), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ))) + require.False(t, store.Has(goutils.ImmutableAppend( + types.OrderBookContractPrefix(false, keepertest.TestContract), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ))) + require.False(t, store.Has(goutils.ImmutableAppend( + types.PriceContractPrefix(keepertest.TestContract), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ))) + require.False(t, store.Has(goutils.ImmutableAppend( + goutils.ImmutableAppend(types.KeyPrefix(types.LongOrderCountKey), types.AddressKeyPrefix(keepertest.TestContract)...), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ))) + require.False(t, store.Has(goutils.ImmutableAppend( + goutils.ImmutableAppend(types.KeyPrefix(types.ShortOrderCountKey), types.AddressKeyPrefix(keepertest.TestContract)...), + migrations.OldPairPrefix(pair.PriceDenom, pair.AssetDenom)..., + ))) + require.False(t, store.Has(goutils.ImmutableAppend(types.KeyPrefix(types.AssetListKey), []byte(pair.PriceDenom)...))) + require.False(t, store.Has(goutils.ImmutableAppend( + types.RegisteredPairPrefix(keepertest.TestContract), + migrations.OldPairPrefix(keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom)..., + ))) + + require.True(t, store.Has(types.OrderBookPrefix(true, keepertest.TestContract, pair.PriceDenom, pair.AssetDenom))) + require.True(t, store.Has(types.OrderBookPrefix(false, keepertest.TestContract, pair.PriceDenom, pair.AssetDenom))) + require.True(t, store.Has(types.PricePrefix(keepertest.TestContract, pair.PriceDenom, pair.AssetDenom))) + require.True(t, store.Has(types.OrderCountPrefix(keepertest.TestContract, pair.PriceDenom, pair.AssetDenom, true))) + require.True(t, store.Has(types.OrderCountPrefix(keepertest.TestContract, pair.PriceDenom, pair.AssetDenom, false))) + require.True(t, store.Has(types.AssetListPrefix(pair.PriceDenom))) + require.True(t, store.Has(goutils.ImmutableAppend( + types.RegisteredPairPrefix(keepertest.TestContract), + types.PairPrefix(keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom)..., + ))) +} diff --git a/x/dex/migrations/v17_to_v18.go b/x/dex/migrations/v17_to_v18.go new file mode 100644 index 000000000..7e6448bac --- /dev/null +++ b/x/dex/migrations/v17_to_v18.go @@ -0,0 +1,33 @@ +package migrations + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func V17ToV18(ctx sdk.Context, dexkeeper keeper.Keeper) error { + // iterate over all contracts and unregister them + for _, c := range dexkeeper.GetAllContractInfo(ctx) { + if err := dexkeeper.DoUnregisterContractWithRefund(ctx, c); err != nil { + return err + } + } + // get module address + dexAddr := dexkeeper.AccountKeeper.GetModuleAddress(dextypes.ModuleName) + // send usei to the feecollector + useiCoins := dexkeeper.BankKeeper.GetBalance(ctx, dexAddr, sdk.MustGetBaseDenom()) + if err := dexkeeper.BankKeeper.SendCoinsFromModuleToModule(ctx, dextypes.ModuleName, authtypes.FeeCollectorName, sdk.NewCoins(useiCoins)); err != nil { + return err + } + // get bank balances remaining for module + balances := dexkeeper.BankKeeper.GetAllBalances(ctx, dexAddr) + // update accountkeeper to give dex burner perms + dexkeeper.CreateModuleAccount(ctx) + // burn all remaining module balances - need burner perms + if err := dexkeeper.BankKeeper.BurnCoins(ctx, dextypes.ModuleName, balances); err != nil { + return err + } + return nil +} diff --git a/x/dex/migrations/v17_to_v18_test.go b/x/dex/migrations/v17_to_v18_test.go new file mode 100644 index 000000000..cec6d67bb --- /dev/null +++ b/x/dex/migrations/v17_to_v18_test.go @@ -0,0 +1,62 @@ +package migrations_test + +import ( + "testing" + "time" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" + sdk "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + "github.com/sei-protocol/sei-chain/app" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMigrate17to18(t *testing.T) { + tm := time.Now().UTC() + valPub := secp256k1.GenPrivKey().PubKey() + + testWrapper := app.NewTestWrapper(t, tm, valPub, false) + + testAddr := sdk.MustAccAddressFromBech32(keepertest.TestAccount) + + testWrapper.FundAcc(testAddr, sdk.NewCoins(sdk.NewCoin(sdk.MustGetBaseDenom(), sdk.NewInt(100000)))) + testWrapper.FundAcc(testAddr, sdk.NewCoins(sdk.NewCoin("ueth", sdk.NewInt(100)))) + + dexkeeper, ctx := testWrapper.App.DexKeeper, testWrapper.Ctx + bal := dexkeeper.BankKeeper.GetBalance(ctx, testAddr, sdk.MustGetBaseDenom()) + require.Equal(t, int64(100000), bal.Amount.Int64()) + // add contract rent + rentAmt := int64(10000) + err := dexkeeper.BankKeeper.SendCoins(ctx, testAddr, dexkeeper.AccountKeeper.GetModuleAddress(types.ModuleName), sdk.NewCoins(sdk.NewCoin(sdk.MustGetBaseDenom(), sdk.NewInt(rentAmt)))) + require.NoError(t, err) + + contract := &types.ContractInfoV2{ContractAddr: keepertest.TestContract, Creator: keepertest.TestAccount, RentBalance: uint64(rentAmt)} + err = dexkeeper.SetContract(ctx, contract) + require.NoError(t, err) + // add some balance to the module just bc + err = dexkeeper.BankKeeper.SendCoins(ctx, testAddr, dexkeeper.AccountKeeper.GetModuleAddress(types.ModuleName), sdk.NewCoins(sdk.NewCoin("ueth", sdk.NewInt(10)), sdk.NewCoin(sdk.MustGetBaseDenom(), sdk.NewInt(1000)))) + require.NoError(t, err) + + supplyUseiInitial := dexkeeper.BankKeeper.GetSupply(ctx, sdk.MustGetBaseDenom()) + + // do migration + err = migrations.V17ToV18(ctx, dexkeeper) + require.NoError(t, err) + + // user refunded rent now has 99000usei and 90ueth + bals := dexkeeper.BankKeeper.GetAllBalances(ctx, testAddr) + require.Equal(t, sdk.NewCoins(sdk.NewCoin("ueth", sdk.NewInt(90)), sdk.NewCoin(sdk.MustGetBaseDenom(), sdk.NewInt(99000))), bals) + // feecollector gets 1000usei + bals = dexkeeper.BankKeeper.GetAllBalances(ctx, dexkeeper.AccountKeeper.GetModuleAddress(authtypes.FeeCollectorName)) + require.Equal(t, sdk.NewCoins(sdk.NewCoin(sdk.MustGetBaseDenom(), sdk.NewInt(1000))), bals) + // ueth supply decreased due to burn + supply := dexkeeper.BankKeeper.GetSupply(ctx, "ueth") + require.Equal(t, sdk.NewInt(90), supply.Amount) + // usei supply unchanged + supplyUseiFinal := dexkeeper.BankKeeper.GetSupply(ctx, sdk.MustGetBaseDenom()) + require.Equal(t, supplyUseiInitial, supplyUseiFinal) + +} diff --git a/x/dex/migrations/v2_to_v3.go b/x/dex/migrations/v2_to_v3.go new file mode 100644 index 000000000..de789df98 --- /dev/null +++ b/x/dex/migrations/v2_to_v3.go @@ -0,0 +1,35 @@ +package migrations + +import ( + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +/** + * No `dex` state exists in any public chain at the time this data type update happened. + * Any new chain (including local ones) should be based on a Sei version newer than this update + * and therefore doesn't need this migration + */ +func DataTypeUpdate(ctx sdk.Context, storeKey sdk.StoreKey, _ codec.BinaryCodec) error { + ClearStore(ctx, storeKey) + return nil +} + +/** + * CAUTION: this function clears up the entire `dex` module store, so it should only ever + * be used outside of a production setting. + */ +func ClearStore(ctx sdk.Context, storeKey sdk.StoreKey) { + for i := 0; i < 256; i++ { + clearStoreForByte(ctx, storeKey, byte(i)) + } +} + +func clearStoreForByte(ctx sdk.Context, storeKey sdk.StoreKey, b byte) { + store := ctx.KVStore(storeKey) + iterator := sdk.KVStorePrefixIterator(store, []byte{b}) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + store.Delete(iterator.Key()) + } +} diff --git a/x/dex/migrations/v3_to_v4.go b/x/dex/migrations/v3_to_v4.go new file mode 100644 index 000000000..b7b9217fc --- /dev/null +++ b/x/dex/migrations/v3_to_v4.go @@ -0,0 +1,21 @@ +package migrations + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func PriceSnapshotUpdate(ctx sdk.Context, paramStore paramtypes.Subspace) error { + err := migratePriceSnapshotParam(ctx, paramStore) + return err +} + +func migratePriceSnapshotParam(ctx sdk.Context, paramStore paramtypes.Subspace) error { + defaultParams := types.Params{ + PriceSnapshotRetention: types.DefaultPriceSnapshotRetention, + SudoCallGasPrice: types.DefaultSudoCallGasPrice, + } + paramStore.SetParamSet(ctx, &defaultParams) + return nil +} diff --git a/x/dex/migrations/v3_to_v4_test.go b/x/dex/migrations/v3_to_v4_test.go new file mode 100644 index 000000000..18712ba89 --- /dev/null +++ b/x/dex/migrations/v3_to_v4_test.go @@ -0,0 +1,48 @@ +package migrations_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/store" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + typesparams "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmdb "github.com/tendermint/tm-db" +) + +func TestMigrate3to4(t *testing.T) { + storeKey := sdk.NewKVStoreKey(types.StoreKey) + memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + + db := tmdb.NewMemDB() + stateStore := store.NewCommitMultiStore(db) + stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) + require.NoError(t, stateStore.LoadLatestVersion()) + + registry := codectypes.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(registry) + + paramsSubspace := typesparams.NewSubspace(cdc, + types.Amino, + storeKey, + memStoreKey, + "DexParams", + ) + ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) + if !paramsSubspace.HasKeyTable() { + paramsSubspace = paramsSubspace.WithKeyTable(types.ParamKeyTable()) + } + migrations.PriceSnapshotUpdate(ctx, paramsSubspace) + + params := types.Params{} + paramsSubspace.GetParamSet(ctx, ¶ms) + require.Equal(t, uint64(types.DefaultPriceSnapshotRetention), params.PriceSnapshotRetention) +} diff --git a/x/dex/migrations/v4_to_v5.go b/x/dex/migrations/v4_to_v5.go new file mode 100644 index 000000000..8e40d7da3 --- /dev/null +++ b/x/dex/migrations/v4_to_v5.go @@ -0,0 +1,28 @@ +package migrations + +import ( + "encoding/binary" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" +) + +/** + * No `dex` state exists in any public chain at the time this data type update happened. + * Any new chain (including local ones) should be based on a Sei version newer than this update + * and therefore doesn't need this migration + */ +func V4ToV5(ctx sdk.Context, storeKey sdk.StoreKey, paramStore paramtypes.Subspace) error { + ClearStore(ctx, storeKey) + if err := migratePriceSnapshotParam(ctx, paramStore); err != nil { + return err + } + + // initialize epoch to 0 + store := ctx.KVStore(storeKey) + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, 0) + store.Set([]byte(keeper.EpochKey), bz) + return nil +} diff --git a/x/dex/migrations/v4_to_v5_test.go b/x/dex/migrations/v4_to_v5_test.go new file mode 100644 index 000000000..78eaa9c0e --- /dev/null +++ b/x/dex/migrations/v4_to_v5_test.go @@ -0,0 +1,59 @@ +package migrations_test + +import ( + "encoding/binary" + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/store" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + typesparams "github.com/cosmos/cosmos-sdk/x/params/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmdb "github.com/tendermint/tm-db" +) + +func TestMigrate4to5(t *testing.T) { + storeKey := sdk.NewKVStoreKey(types.StoreKey) + memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + + db := tmdb.NewMemDB() + stateStore := store.NewCommitMultiStore(db) + stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) + require.NoError(t, stateStore.LoadLatestVersion()) + + registry := codectypes.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(registry) + + paramsSubspace := typesparams.NewSubspace(cdc, + types.Amino, + storeKey, + memStoreKey, + "DexParams", + ) + ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) + if !paramsSubspace.HasKeyTable() { + paramsSubspace = paramsSubspace.WithKeyTable(types.ParamKeyTable()) + } + store := ctx.KVStore(storeKey) + store.Set([]byte("garbage key"), []byte("garbage value")) + require.True(t, store.Has([]byte("garbage key"))) + err := migrations.V4ToV5(ctx, storeKey, paramsSubspace) + require.Nil(t, err) + require.False(t, store.Has([]byte("garbage key"))) + + params := types.Params{} + paramsSubspace.GetParamSet(ctx, ¶ms) + require.Equal(t, uint64(types.DefaultPriceSnapshotRetention), params.PriceSnapshotRetention) + + epochBytes := store.Get([]byte(keeper.EpochKey)) + epoch := binary.BigEndian.Uint64(epochBytes) + require.Equal(t, uint64(0), epoch) +} diff --git a/x/dex/migrations/v5_to_v6.go b/x/dex/migrations/v5_to_v6.go new file mode 100644 index 000000000..870bc82e7 --- /dev/null +++ b/x/dex/migrations/v5_to_v6.go @@ -0,0 +1,57 @@ +package migrations + +import ( + "errors" + "fmt" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// This migration updates contract info to match the new data format +func V5ToV6(ctx sdk.Context, storeKey sdk.StoreKey, _ codec.BinaryCodec) error { + for i := 0; i < 256; i++ { + if err := updateContractInfoForBytePrefix(ctx, storeKey, byte(i)); err != nil { + return err + } + } + return nil +} + +// assuming no dependency exists at the time of this migration +func updateContractInfoForBytePrefix(ctx sdk.Context, storeKey sdk.StoreKey, b byte) error { + store := prefix.NewStore( + ctx.KVStore(storeKey), + []byte(keeper.ContractPrefixKey), + ) + iterator := sdk.KVStorePrefixIterator(store, []byte{b}) + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + oldContractInfoBytes := iterator.Value() + oldContractInfo := types.LegacyContractInfo{} + if err := oldContractInfo.Unmarshal(oldContractInfoBytes); err != nil { + ctx.Logger().Error(fmt.Sprintf("Failed to unmarshal contract info for %s", iterator.Key())) + return err + } + if oldContractInfo.DependentContractAddrs != nil { + ctx.Logger().Error(fmt.Sprintf("Contract info of %s has dependencies!", iterator.Key())) + return errors.New("contract has unexpected dependencies") + } + newContractInfo := types.ContractInfo{ + CodeId: oldContractInfo.CodeId, + ContractAddr: oldContractInfo.ContractAddr, + NeedHook: oldContractInfo.NeedHook, + NeedOrderMatching: oldContractInfo.NeedOrderMatching, + } + bz, err := newContractInfo.Marshal() + if err != nil { + ctx.Logger().Error(fmt.Sprintf("Failed to marshal contract info for %s", iterator.Key())) + return err + } + store.Set([]byte(newContractInfo.ContractAddr), bz) + } + return nil +} diff --git a/x/dex/migrations/v5_to_v6_test.go b/x/dex/migrations/v5_to_v6_test.go new file mode 100644 index 000000000..3035ec0c1 --- /dev/null +++ b/x/dex/migrations/v5_to_v6_test.go @@ -0,0 +1,79 @@ +package migrations_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/codec" + codectypes "github.com/cosmos/cosmos-sdk/codec/types" + "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmdb "github.com/tendermint/tm-db" +) + +func TestMigrate5to6(t *testing.T) { + storeKey := sdk.NewKVStoreKey(types.StoreKey) + memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + + db := tmdb.NewMemDB() + stateStore := store.NewCommitMultiStore(db) + stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) + require.NoError(t, stateStore.LoadLatestVersion()) + + registry := codectypes.NewInterfaceRegistry() + cdc := codec.NewProtoCodec(registry) + ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) + store := prefix.NewStore( + ctx.KVStore(storeKey), + []byte(keeper.ContractPrefixKey), + ) + + oldContractA := types.LegacyContractInfo{ + CodeId: 1, + ContractAddr: "abc", + NeedHook: true, + NeedOrderMatching: false, + } + oldContractB := types.LegacyContractInfo{ + CodeId: 2, + ContractAddr: "def", + NeedHook: false, + NeedOrderMatching: true, + } + bzA, _ := oldContractA.Marshal() + bzB, _ := oldContractB.Marshal() + store.Set([]byte("abc"), bzA) + store.Set([]byte("def"), bzB) + + err := migrations.V5ToV6(ctx, storeKey, cdc) + require.Nil(t, err) + + newBzA := store.Get([]byte("abc")) + newBzB := store.Get([]byte("def")) + newContractA := types.ContractInfo{} + newContractB := types.ContractInfo{} + err = newContractA.Unmarshal(newBzA) + require.Nil(t, err) + err = newContractB.Unmarshal(newBzB) + require.Nil(t, err) + require.Equal(t, types.ContractInfo{ + CodeId: 1, + ContractAddr: "abc", + NeedHook: true, + NeedOrderMatching: false, + }, newContractA) + require.Equal(t, types.ContractInfo{ + CodeId: 2, + ContractAddr: "def", + NeedHook: false, + NeedOrderMatching: true, + }, newContractB) +} diff --git a/x/dex/migrations/v6_to_v7.go b/x/dex/migrations/v6_to_v7.go new file mode 100644 index 000000000..c7df17849 --- /dev/null +++ b/x/dex/migrations/v6_to_v7.go @@ -0,0 +1,84 @@ +package migrations + +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/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func V6ToV7(ctx sdk.Context, storeKey sdk.StoreKey) error { + backfillOrderIDPerContract(ctx, storeKey) + reformatPriceState(ctx, storeKey) + return nil +} + +// this function backfills contract order ID according to the old global order ID +func backfillOrderIDPerContract(ctx sdk.Context, storeKey sdk.StoreKey) { + oldStore := prefix.NewStore( + ctx.KVStore(storeKey), + []byte{}, + ) + oldKey := types.KeyPrefix(types.NextOrderIDKey) + oldIDBytes := oldStore.Get(oldKey) + if oldIDBytes == nil { + // nothing to backfill + return + } + oldID := binary.BigEndian.Uint64(oldIDBytes) + + contractStore := prefix.NewStore(ctx.KVStore(storeKey), []byte(keeper.ContractPrefixKey)) + iterator := sdk.KVStorePrefixIterator(contractStore, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + contract := types.ContractInfo{} + if err := contract.Unmarshal(iterator.Value()); err == nil { + if contract.NeedOrderMatching { + newIDStore := prefix.NewStore(ctx.KVStore(storeKey), types.NextOrderIDPrefix(contract.ContractAddr)) + byteKey := types.KeyPrefix(types.NextOrderIDKey) + bz := make([]byte, 8) + binary.BigEndian.PutUint64(bz, oldID) + newIDStore.Set(byteKey, bz) + } + } + } +} + +func reformatPriceState(ctx sdk.Context, storeKey sdk.StoreKey) { + contractStore := prefix.NewStore(ctx.KVStore(storeKey), []byte(keeper.ContractPrefixKey)) + iterator := sdk.KVStorePrefixIterator(contractStore, []byte{}) + + defer iterator.Close() + + for ; iterator.Valid(); iterator.Next() { + contract := types.ContractInfo{} + if err := contract.Unmarshal(iterator.Value()); err == nil { + pairStore := prefix.NewStore(ctx.KVStore(storeKey), types.RegisteredPairPrefix(contract.ContractAddr)) + pairIterator := sdk.KVStorePrefixIterator(pairStore, []byte{}) + for ; pairIterator.Valid(); pairIterator.Next() { + pair := types.Pair{} + if err := pair.Unmarshal(pairIterator.Value()); err == nil { + oldPriceStore := prefix.NewStore(ctx.KVStore(storeKey), append( + append( + append(types.KeyPrefix(types.PriceKey), types.KeyPrefix(contract.ContractAddr)...), + types.KeyPrefix(pair.PriceDenom)..., + ), + types.KeyPrefix(pair.AssetDenom)..., + )) + newPriceStore := prefix.NewStore(ctx.KVStore(storeKey), types.PricePrefix(contract.ContractAddr, pair.PriceDenom, pair.AssetDenom)) + oldPriceIterator := sdk.KVStorePrefixIterator(oldPriceStore, []byte{}) + for ; oldPriceIterator.Valid(); oldPriceIterator.Next() { + newPriceStore.Set(oldPriceIterator.Key(), oldPriceIterator.Value()) + } + oldPriceIterator.Close() + } + } + + pairIterator.Close() + } + } +} diff --git a/x/dex/migrations/v6_to_v7_test.go b/x/dex/migrations/v6_to_v7_test.go new file mode 100644 index 000000000..e00f9adbc --- /dev/null +++ b/x/dex/migrations/v6_to_v7_test.go @@ -0,0 +1,89 @@ +package migrations_test + +import ( + "encoding/binary" + "testing" + + "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmdb "github.com/tendermint/tm-db" +) + +func TestMigrate6to7(t *testing.T) { + storeKey := sdk.NewKVStoreKey(types.StoreKey) + memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + + db := tmdb.NewMemDB() + stateStore := store.NewCommitMultiStore(db) + stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) + require.NoError(t, stateStore.LoadLatestVersion()) + + ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) + + // write old order ID + store := prefix.NewStore(ctx.KVStore(storeKey), []byte{}) + oldID := make([]byte, 8) + binary.BigEndian.PutUint64(oldID, 10) + store.Set(types.KeyPrefix(types.NextOrderIDKey), oldID) + + // write old price state + store = prefix.NewStore(ctx.KVStore(storeKey), append( + append( + append(types.KeyPrefix(types.PriceKey), types.KeyPrefix(keepertest.TestContract)...), + types.KeyPrefix(keepertest.TestPriceDenom)..., + ), + types.KeyPrefix(keepertest.TestAssetDenom)...), + ) + + price := types.Price{ + SnapshotTimestampInSeconds: 5, + Price: sdk.MustNewDecFromStr("123.4"), + Pair: &keepertest.TestPair, + } + priceBytes, _ := price.Marshal() + store.Set(keeper.GetKeyForTs(price.SnapshotTimestampInSeconds), priceBytes) + + // register contract / pair + store = prefix.NewStore( + ctx.KVStore(storeKey), + []byte(keeper.ContractPrefixKey), + ) + contract := types.ContractInfo{ + CodeId: 1, + ContractAddr: keepertest.TestContract, + NeedOrderMatching: true, + } + contractBytes, _ := contract.Marshal() + store.Set([]byte(contract.ContractAddr), contractBytes) + + store = prefix.NewStore(ctx.KVStore(storeKey), types.RegisteredPairPrefix(keepertest.TestContract)) + keyBytes := make([]byte, 8) + binary.BigEndian.PutUint64(keyBytes, 0) + pairBytes, _ := keepertest.TestPair.Marshal() + store.Set(keyBytes, pairBytes) + + err := migrations.V6ToV7(ctx, storeKey) + require.Nil(t, err) + + store = prefix.NewStore(ctx.KVStore(storeKey), types.NextOrderIDPrefix(keepertest.TestContract)) + byteKey := types.KeyPrefix(types.NextOrderIDKey) + bz := store.Get(byteKey) + require.Equal(t, uint64(10), binary.BigEndian.Uint64(bz)) + + store = prefix.NewStore(ctx.KVStore(storeKey), types.PricePrefix(keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom)) + key := keeper.GetKeyForTs(5) + priceRes := types.Price{} + b := store.Get(key) + _ = priceRes.Unmarshal(b) + require.Equal(t, price, priceRes) +} diff --git a/x/dex/migrations/v7_to_v8.go b/x/dex/migrations/v7_to_v8.go new file mode 100644 index 000000000..26914ff4d --- /dev/null +++ b/x/dex/migrations/v7_to_v8.go @@ -0,0 +1,101 @@ +package migrations + +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/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func V7ToV8(ctx sdk.Context, storeKey sdk.StoreKey) error { + return flattenSettlements(ctx, storeKey) +} + +func flattenSettlements(ctx sdk.Context, storeKey sdk.StoreKey) error { + contractStore := prefix.NewStore(ctx.KVStore(storeKey), []byte(keeper.ContractPrefixKey)) + iterator := sdk.KVStorePrefixIterator(contractStore, []byte{}) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + contract := types.ContractInfo{} + if err := contract.Unmarshal(iterator.Value()); err != nil { + return err + } + pairStore := prefix.NewStore(ctx.KVStore(storeKey), types.RegisteredPairPrefix(contract.ContractAddr)) + pairIterator := sdk.KVStorePrefixIterator(pairStore, []byte{}) + for ; pairIterator.Valid(); pairIterator.Next() { + pair := types.Pair{} + if err := pair.Unmarshal(pairIterator.Value()); err != nil { + pairIterator.Close() + return err + } + settlementStore := prefix.NewStore( + ctx.KVStore(storeKey), + SettlementEntryPrefix(contract.ContractAddr, pair.PriceDenom, pair.AssetDenom), + ) + settlementIterator := sdk.KVStorePrefixIterator(settlementStore, []byte{}) + + oldKeys := [][]byte{} + newKeys := [][]byte{} + newVals := [][]byte{} + for ; settlementIterator.Valid(); settlementIterator.Next() { + var val types.Settlements + if err := val.Unmarshal(settlementIterator.Value()); err != nil { + pairIterator.Close() + settlementIterator.Close() + return err + } + for i, settlementEntry := range val.Entries { + settlementBytes, err := settlementEntry.Marshal() + if err != nil { + pairIterator.Close() + settlementIterator.Close() + return err + } + newKeys = append(newKeys, types.GetSettlementKey(settlementEntry.OrderId, settlementEntry.Account, uint64(i))) + newVals = append(newVals, settlementBytes) + } + + if len(val.Entries) > 0 { + settlementIDStore := prefix.NewStore( + ctx.KVStore(storeKey), + NextSettlementIDPrefix(contract.ContractAddr, pair.PriceDenom, pair.AssetDenom), + ) + key := make([]byte, 8) + binary.BigEndian.PutUint64(key, val.Entries[0].OrderId) + value := make([]byte, 8) + binary.BigEndian.PutUint64(value, uint64(len(val.Entries))) + settlementIDStore.Set(key, value) + } + oldKeys = append(oldKeys, settlementIterator.Key()) + } + + settlementIterator.Close() + + for _, oldKey := range oldKeys { + settlementStore.Delete(oldKey) + } + for i, newKey := range newKeys { + settlementStore.Set(newKey, newVals[i]) + } + } + pairIterator.Close() + } + return nil +} + +func SettlementEntryPrefix(contractAddr string, priceDenom string, assetDenom string) []byte { + return append( + append(types.KeyPrefix("SettlementEntry-"), types.AddressKeyPrefix(contractAddr)...), + types.PairPrefix(priceDenom, assetDenom)..., + ) +} + +func NextSettlementIDPrefix(contractAddr string, priceDenom string, assetDenom string) []byte { + return append( + append(types.KeyPrefix("NextSettlementID-"), types.AddressKeyPrefix(contractAddr)...), + types.PairPrefix(priceDenom, assetDenom)..., + ) +} diff --git a/x/dex/migrations/v7_to_v8_test.go b/x/dex/migrations/v7_to_v8_test.go new file mode 100644 index 000000000..5960ff7e7 --- /dev/null +++ b/x/dex/migrations/v7_to_v8_test.go @@ -0,0 +1,98 @@ +package migrations_test + +import ( + "encoding/binary" + "testing" + + "github.com/cosmos/cosmos-sdk/store" + "github.com/cosmos/cosmos-sdk/store/prefix" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmdb "github.com/tendermint/tm-db" +) + +func TestMigrate7to8(t *testing.T) { + storeKey := sdk.NewKVStoreKey(types.StoreKey) + memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey) + + db := tmdb.NewMemDB() + stateStore := store.NewCommitMultiStore(db) + stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db) + stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil) + require.NoError(t, stateStore.LoadLatestVersion()) + + ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger()) + + // write old settlements + store := prefix.NewStore( + ctx.KVStore(storeKey), + migrations.SettlementEntryPrefix(keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom), + ) + settlements := types.Settlements{ + Entries: []*types.SettlementEntry{ + { + Account: keepertest.TestAccount, + OrderId: 1, + Quantity: sdk.MustNewDecFromStr("0.3"), + }, + { + Account: keepertest.TestAccount, + OrderId: 1, + Quantity: sdk.MustNewDecFromStr("0.7"), + }, + }, + } + bz, _ := settlements.Marshal() + store.Set(types.GetSettlementOrderIDPrefix(1, keepertest.TestAccount), bz) + + // register contract / pair + store = prefix.NewStore( + ctx.KVStore(storeKey), + []byte(keeper.ContractPrefixKey), + ) + contract := types.ContractInfo{ + CodeId: 1, + ContractAddr: keepertest.TestContract, + NeedOrderMatching: true, + } + contractBytes, _ := contract.Marshal() + store.Set([]byte(contract.ContractAddr), contractBytes) + + store = prefix.NewStore(ctx.KVStore(storeKey), types.RegisteredPairPrefix(keepertest.TestContract)) + keyBytes := make([]byte, 8) + binary.BigEndian.PutUint64(keyBytes, 0) + pairBytes, _ := keepertest.TestPair.Marshal() + store.Set(keyBytes, pairBytes) + + err := migrations.V7ToV8(ctx, storeKey) + require.Nil(t, err) + + store = prefix.NewStore( + ctx.KVStore(storeKey), + migrations.SettlementEntryPrefix(keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom), + ) + settlementEntry1Key := types.GetSettlementKey(1, keepertest.TestAccount, 0) + settlementEntry1 := types.SettlementEntry{} + settlementEntry1Bytes := store.Get(settlementEntry1Key) + _ = settlementEntry1.Unmarshal(settlementEntry1Bytes) + require.Equal(t, sdk.MustNewDecFromStr("0.3"), settlementEntry1.Quantity) + settlementEntry2Key := types.GetSettlementKey(1, keepertest.TestAccount, 1) + settlementEntry2 := types.SettlementEntry{} + settlementEntry2Bytes := store.Get(settlementEntry2Key) + _ = settlementEntry2.Unmarshal(settlementEntry2Bytes) + require.Equal(t, sdk.MustNewDecFromStr("0.7"), settlementEntry2.Quantity) + + require.False(t, store.Has(types.GetSettlementOrderIDPrefix(1, keepertest.TestAccount))) + + store = prefix.NewStore(ctx.KVStore(storeKey), migrations.NextSettlementIDPrefix(keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom)) + key := make([]byte, 8) + binary.BigEndian.PutUint64(key, uint64(1)) + require.Equal(t, uint64(2), binary.BigEndian.Uint64(store.Get(key))) +} diff --git a/x/dex/migrations/v8_to_v9.go b/x/dex/migrations/v8_to_v9.go new file mode 100644 index 000000000..cb0e6095d --- /dev/null +++ b/x/dex/migrations/v8_to_v9.go @@ -0,0 +1,38 @@ +package migrations + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +func V8ToV9(ctx sdk.Context, dexkeeper keeper.Keeper) error { + dexkeeper.CreateModuleAccount(ctx) + + contractStore := prefix.NewStore(ctx.KVStore(dexkeeper.GetStoreKey()), []byte(keeper.ContractPrefixKey)) + iterator := sdk.KVStorePrefixIterator(contractStore, []byte{}) + + defer iterator.Close() + for ; iterator.Valid(); iterator.Next() { + contract := types.ContractInfo{} + if err := contract.Unmarshal(iterator.Value()); err != nil { + return err + } + contractV2 := types.ContractInfoV2{ + CodeId: contract.CodeId, + ContractAddr: contract.ContractAddr, + NeedHook: contract.NeedHook, + NeedOrderMatching: contract.NeedOrderMatching, + Dependencies: contract.Dependencies, + NumIncomingDependencies: contract.NumIncomingDependencies, + } + bz, err := contractV2.Marshal() + if err != nil { + return err + } + contractStore.Set(iterator.Key(), bz) + } + + return nil +} diff --git a/x/dex/migrations/v8_to_v9_test.go b/x/dex/migrations/v8_to_v9_test.go new file mode 100644 index 000000000..c1b87b3d6 --- /dev/null +++ b/x/dex/migrations/v8_to_v9_test.go @@ -0,0 +1,42 @@ +package migrations_test + +import ( + "testing" + + "github.com/cosmos/cosmos-sdk/store/prefix" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMigrate8to9(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + // write old contract + store := prefix.NewStore( + ctx.KVStore(dexkeeper.GetStoreKey()), + []byte(keeper.ContractPrefixKey), + ) + contract := types.ContractInfo{ + CodeId: 1, + ContractAddr: keepertest.TestContract, + NeedOrderMatching: true, + } + contractBytes, _ := contract.Marshal() + store.Set(types.ContractKey(contract.ContractAddr), contractBytes) + + err := migrations.V8ToV9(ctx, *dexkeeper) + require.NoError(t, err) + + contractV2, err := dexkeeper.GetContract(ctx, keepertest.TestContract) + require.NoError(t, err) + require.Equal(t, types.ContractInfoV2{ + CodeId: 1, + ContractAddr: keepertest.TestContract, + NeedOrderMatching: true, + }, contractV2) + + moduleAccount := dexkeeper.AccountKeeper.GetModuleAccount(ctx, types.ModuleName) + require.NotNil(t, moduleAccount) +} diff --git a/x/dex/migrations/v9_to_v10.go b/x/dex/migrations/v9_to_v10.go new file mode 100644 index 000000000..c8484d9b1 --- /dev/null +++ b/x/dex/migrations/v9_to_v10.go @@ -0,0 +1,91 @@ +package migrations + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +const PriceTickSizeKey = "ticks" +const QuantityTickSizeKey = "quantityticks" +const RegisteredPairCount = "rpcnt" + +// This migration deprecates the tick size store keys and registered pair count store keys. +// It also refactors the registered pair store to use pair denoms for key construction +// instead of index based key construction. +func V9ToV10(ctx sdk.Context, dexkeeper keeper.Keeper) error { + dexkeeper.CreateModuleAccount(ctx) + store := ctx.KVStore(dexkeeper.GetStoreKey()) + + rpIterator := sdk.KVStorePrefixIterator(store, []byte(types.RegisteredPairKey)) + + rpcntByte := []byte(RegisteredPairCount) + defer rpIterator.Close() + for ; rpIterator.Valid(); rpIterator.Next() { + // need to skip anything that has rpcnt in the key prefix + if string(rpIterator.Key()[:len(rpcntByte)]) == RegisteredPairCount { + continue + } + var registeredPair types.Pair + b := rpIterator.Value() + err := registeredPair.Unmarshal(b) + if err != nil { + return err + } + // this key is the contractAddress + index + rpKey := rpIterator.Key() + // remove first 2 bytes for prefix and last 8 bytes since that is the index + rpContractKey := rpKey[2 : len(rpKey)-8] + // get pair prefix used for indexing + pairPrefix := types.PairPrefix(registeredPair.PriceDenom, registeredPair.AssetDenom) + + // set the price and quantity ticks from the appropriate store + priceTickStore := prefix.NewStore(store, append([]byte(PriceTickSizeKey), rpContractKey...)) + priceTickSize := sdk.Dec{} + b = priceTickStore.Get(pairPrefix) + err = priceTickSize.Unmarshal(b) + if err != nil { + return err + } + registeredPair.PriceTicksize = &priceTickSize + + quantityTickStore := prefix.NewStore(store, append([]byte(QuantityTickSizeKey), rpContractKey...)) + quantityTickSize := sdk.Dec{} + b = quantityTickStore.Get(pairPrefix) + err = quantityTickSize.Unmarshal(b) + if err != nil { + return err + } + registeredPair.QuantityTicksize = &quantityTickSize + + // delete the old store value + rpStore := prefix.NewStore(store, append([]byte(types.RegisteredPairKey), rpContractKey...)) + rpStore.Delete(rpKey) + // updated registered pair, now we need to set it to the correct store value + writeBytes := dexkeeper.Cdc.MustMarshal(®isteredPair) + rpStore.Set(pairPrefix, writeBytes) + } + + // delete rpcnt + rpcIterator := sdk.KVStorePrefixIterator(store, []byte(RegisteredPairCount)) + defer rpcIterator.Close() + for ; rpcIterator.Valid(); rpcIterator.Next() { + store.Delete(rpcIterator.Key()) + } + + // delete price Ticks + priceTickIterator := sdk.KVStorePrefixIterator(store, []byte(PriceTickSizeKey)) + defer priceTickIterator.Close() + for ; priceTickIterator.Valid(); priceTickIterator.Next() { + store.Delete(priceTickIterator.Key()) + } + + // delete quantityTicks + quantityTickIterator := sdk.KVStorePrefixIterator(store, []byte(QuantityTickSizeKey)) + defer quantityTickIterator.Close() + for ; quantityTickIterator.Valid(); quantityTickIterator.Next() { + store.Delete(quantityTickIterator.Key()) + } + return nil +} diff --git a/x/dex/migrations/v9_to_v10_test.go b/x/dex/migrations/v9_to_v10_test.go new file mode 100644 index 000000000..27f6406a8 --- /dev/null +++ b/x/dex/migrations/v9_to_v10_test.go @@ -0,0 +1,94 @@ +package migrations_test + +import ( + "encoding/binary" + "testing" + + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkaddress "github.com/cosmos/cosmos-sdk/types/address" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMigrate9to10(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + // write old contract + dexStore := ctx.KVStore(dexkeeper.GetStoreKey()) + rpStore := prefix.NewStore( + dexStore, + []byte(types.RegisteredPairKey), + ) + priceTickSize := sdk.MustNewDecFromStr("0.0001") + quantityTickSize := sdk.MustNewDecFromStr("0.0001") + pair := types.Pair{ + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + PriceTicksize: &priceTickSize, + QuantityTicksize: &quantityTickSize, + } + pairPrefix := types.PairPrefix(keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom) + + pairBytes := dexkeeper.Cdc.MustMarshal(&pair) + countBytes := make([]byte, 8) + binary.BigEndian.PutUint64(countBytes, 1) + // simulate legacy store where registered pairs are indexed by auto increment count + address, _ := sdk.AccAddressFromBech32(keepertest.TestContract) + address = sdkaddress.MustLengthPrefix(address) + rpStore.Set(append(address, countBytes...), pairBytes) + + bytes := rpStore.Get(append(address, countBytes...)) + require.Equal(t, pairBytes, bytes) + + // set count, ticksize, and quantity size + newCountBytes := make([]byte, 8) + binary.BigEndian.PutUint64(newCountBytes, 2) + dexStore.Set( + append([]byte(migrations.RegisteredPairCount), address...), + newCountBytes, + ) + + tickBytes, _ := sdk.MustNewDecFromStr("0.0002").Marshal() + dexStore.Set( + append(append([]byte(migrations.PriceTickSizeKey), address...), pairPrefix...), + tickBytes, + ) + + dexStore.Set( + append(append([]byte(migrations.QuantityTickSizeKey), address...), pairPrefix...), + tickBytes, + ) + + err := migrations.V9ToV10(ctx, *dexkeeper) + require.NoError(t, err) + + pair, found := dexkeeper.GetRegisteredPair(ctx, keepertest.TestContract, keepertest.TestPair.PriceDenom, keepertest.TestPair.AssetDenom) + require.True(t, found) + newTickSize := sdk.MustNewDecFromStr("0.0002") + require.Equal(t, types.Pair{ + PriceDenom: keepertest.TestPair.PriceDenom, + AssetDenom: keepertest.TestPair.AssetDenom, + PriceTicksize: &newTickSize, + QuantityTicksize: &newTickSize, + }, pair) + + // verify old/deprecated keeper store data is removed + require.False( + t, + dexStore.Has(append(address, countBytes...)), + ) + require.False( + t, + dexStore.Has(append([]byte(migrations.RegisteredPairCount), address...)), + ) + require.False( + t, + dexStore.Has(append(append([]byte(migrations.PriceTickSizeKey), address...), pairPrefix...)), + ) + require.False( + t, + dexStore.Has(append(append([]byte(migrations.QuantityTickSizeKey), address...), pairPrefix...)), + ) +} diff --git a/x/dex/module.go b/x/dex/module.go new file mode 100644 index 000000000..0a82142be --- /dev/null +++ b/x/dex/module.go @@ -0,0 +1,383 @@ +package dex + +import ( + "context" + "encoding/json" + "fmt" + "sync" + "time" + + "github.com/CosmWasm/wasmd/x/wasm" + "github.com/cosmos/cosmos-sdk/store/prefix" + "github.com/cosmos/cosmos-sdk/telemetry" + "github.com/gorilla/mux" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/spf13/cobra" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/utils/tracing" + "github.com/sei-protocol/sei-chain/utils" + "github.com/sei-protocol/sei-chain/utils/datastructures" + "github.com/sei-protocol/sei-chain/x/dex/client/cli/query" + "github.com/sei-protocol/sei-chain/x/dex/client/cli/tx" + "github.com/sei-protocol/sei-chain/x/dex/contract" + "github.com/sei-protocol/sei-chain/x/dex/keeper" + dexkeeperabci "github.com/sei-protocol/sei-chain/x/dex/keeper/abci" + "github.com/sei-protocol/sei-chain/x/dex/keeper/msgserver" + dexkeeperquery "github.com/sei-protocol/sei-chain/x/dex/keeper/query" + "github.com/sei-protocol/sei-chain/x/dex/migrations" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + "github.com/sei-protocol/sei-chain/x/store" +) + +var ( + _ module.AppModule = AppModule{} + _ module.AppModuleBasic = AppModuleBasic{} +) + +// ---------------------------------------------------------------------------- +// AppModuleBasic +// ---------------------------------------------------------------------------- + +// AppModuleBasic implements the AppModuleBasic interface for the capability module. +type AppModuleBasic struct { + cdc codec.BinaryCodec +} + +func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic { + return AppModuleBasic{cdc: cdc} +} + +// Name returns the capability module's name. +func (AppModuleBasic) Name() string { + return types.ModuleName +} + +func (AppModuleBasic) RegisterCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino) { + types.RegisterCodec(cdc) +} + +// RegisterInterfaces registers the module's interface types +func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry) { + types.RegisterInterfaces(reg) +} + +// DefaultGenesis returns the capability module's default genesis state. +func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { + return cdc.MustMarshalJSON(types.DefaultGenesis()) +} + +// ValidateGenesis performs genesis state validation for the capability module. +func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { + var genState types.GenesisState + if err := cdc.UnmarshalJSON(bz, &genState); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) + } + return genState.Validate() +} + +// ExportGenesisStream returns the tokenfactory module's exported genesis state as raw JSON bytes in a streaming fashion. +func (am AppModule) ExportGenesisStream(ctx sdk.Context, cdc codec.JSONCodec) <-chan json.RawMessage { + ch := make(chan json.RawMessage) + go func() { + ch <- am.ExportGenesis(ctx, cdc) + close(ch) + }() + return ch +} + +// ValidateGenesisStream performs genesis state validation for the x/tokenfactory module in a streaming fashion. +func (am AppModuleBasic) ValidateGenesisStream(cdc codec.JSONCodec, config client.TxEncodingConfig, genesisCh <-chan json.RawMessage) error { + for genesis := range genesisCh { + err := am.ValidateGenesis(cdc, config, genesis) + if err != nil { + return err + } + } + return nil +} + +// RegisterRESTRoutes registers the capability module's REST service handlers. +func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) { +} + +// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module. +func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) { + types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)) //nolint:errcheck // this is inside a module, and the method doesn't return error. Leave it alone. +} + +// GetTxCmd returns the capability module's root tx command. +func (a AppModuleBasic) GetTxCmd() *cobra.Command { + return tx.GetTxCmd() +} + +// GetQueryCmd returns the capability module's root query command. +func (AppModuleBasic) GetQueryCmd() *cobra.Command { + return query.GetQueryCmd() +} + +// ---------------------------------------------------------------------------- +// AppModule +// ---------------------------------------------------------------------------- + +// AppModule implements the AppModule interface for the capability module. +type AppModule struct { + AppModuleBasic + + keeper keeper.Keeper + accountKeeper types.AccountKeeper + bankKeeper types.BankKeeper + wasmKeeper wasm.Keeper + + abciWrapper dexkeeperabci.KeeperWrapper + + tracingInfo *tracing.Info +} + +func NewAppModule( + cdc codec.Codec, + keeper keeper.Keeper, + accountKeeper types.AccountKeeper, + bankKeeper types.BankKeeper, + wasmKeeper wasm.Keeper, + tracingInfo *tracing.Info, +) AppModule { + return AppModule{ + AppModuleBasic: NewAppModuleBasic(cdc), + keeper: keeper, + accountKeeper: accountKeeper, + bankKeeper: bankKeeper, + wasmKeeper: wasmKeeper, + abciWrapper: dexkeeperabci.KeeperWrapper{Keeper: &keeper}, + tracingInfo: tracingInfo, + } +} + +// Name returns the capability module's name. +func (am AppModule) Name() string { + return am.AppModuleBasic.Name() +} + +// Route returns the capability module's message routing key. +func (am AppModule) Route() sdk.Route { + return sdk.NewRoute(types.RouterKey, NewHandler(am.keeper)) +} + +// QuerierRoute returns the capability module's query routing key. +func (AppModule) QuerierRoute() string { return types.QuerierRoute } + +// LegacyQuerierHandler returns the capability module's Querier. +func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier { + return nil +} + +// RegisterServices registers a GRPC query service to respond to the +// module-specific GRPC queries. +func (am AppModule) RegisterServices(cfg module.Configurator) { + types.RegisterMsgServer(cfg.MsgServer(), msgserver.NewMsgServerImpl(am.keeper)) + types.RegisterQueryServer(cfg.QueryServer(), dexkeeperquery.KeeperWrapper{Keeper: &am.keeper}) + + _ = cfg.RegisterMigration(types.ModuleName, 1, func(ctx sdk.Context) error { return nil }) + _ = cfg.RegisterMigration(types.ModuleName, 2, func(ctx sdk.Context) error { + return migrations.DataTypeUpdate(ctx, am.keeper.GetStoreKey(), am.keeper.Cdc) + }) + _ = cfg.RegisterMigration(types.ModuleName, 3, func(ctx sdk.Context) error { + return migrations.PriceSnapshotUpdate(ctx, am.keeper.Paramstore) + }) + _ = cfg.RegisterMigration(types.ModuleName, 4, func(ctx sdk.Context) error { + return migrations.V4ToV5(ctx, am.keeper.GetStoreKey(), am.keeper.Paramstore) + }) + _ = cfg.RegisterMigration(types.ModuleName, 5, func(ctx sdk.Context) error { + return migrations.V5ToV6(ctx, am.keeper.GetStoreKey(), am.keeper.Cdc) + }) + _ = cfg.RegisterMigration(types.ModuleName, 6, func(ctx sdk.Context) error { + return migrations.V6ToV7(ctx, am.keeper.GetStoreKey()) + }) + _ = cfg.RegisterMigration(types.ModuleName, 7, func(ctx sdk.Context) error { + return migrations.V7ToV8(ctx, am.keeper.GetStoreKey()) + }) + _ = cfg.RegisterMigration(types.ModuleName, 8, func(ctx sdk.Context) error { + return migrations.V8ToV9(ctx, am.keeper) + }) + _ = cfg.RegisterMigration(types.ModuleName, 9, func(ctx sdk.Context) error { + return migrations.V9ToV10(ctx, am.keeper) + }) + _ = cfg.RegisterMigration(types.ModuleName, 10, func(ctx sdk.Context) error { + return migrations.V10ToV11(ctx, am.keeper) + }) + _ = cfg.RegisterMigration(types.ModuleName, 11, func(ctx sdk.Context) error { + return migrations.V11ToV12(ctx, am.keeper) + }) + _ = cfg.RegisterMigration(types.ModuleName, 12, func(ctx sdk.Context) error { + return migrations.V12ToV13(ctx, am.keeper) + }) + _ = cfg.RegisterMigration(types.ModuleName, 13, func(ctx sdk.Context) error { + return migrations.V13ToV14(ctx, am.keeper) + }) + _ = cfg.RegisterMigration(types.ModuleName, 14, func(ctx sdk.Context) error { + return migrations.V14ToV15(ctx, am.keeper) + }) + _ = cfg.RegisterMigration(types.ModuleName, 15, func(ctx sdk.Context) error { + return migrations.V15ToV16(ctx, am.keeper) + }) + _ = cfg.RegisterMigration(types.ModuleName, 16, func(ctx sdk.Context) error { + return nil + }) + _ = cfg.RegisterMigration(types.ModuleName, 17, func(ctx sdk.Context) error { + return migrations.V17ToV18(ctx, am.keeper) + }) +} + +// RegisterInvariants registers the capability module's invariants. +func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry) {} + +// InitGenesis performs the capability module's genesis initialization It returns +// no validator updates. +func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate { + var genState types.GenesisState + // Initialize global index to index in genesis state + cdc.MustUnmarshalJSON(gs, &genState) + + InitGenesis(ctx, am.keeper, genState) + + return []abci.ValidatorUpdate{} +} + +// ExportGenesis returns the capability module's exported genesis state as raw JSON bytes. +func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage { + genState := ExportGenesis(ctx, am.keeper) + return cdc.MustMarshalJSON(genState) +} + +// ConsensusVersion implements ConsensusVersion. +func (AppModule) ConsensusVersion() uint64 { return 18 } + +// BeginBlock executes all ABCI BeginBlock logic respective to the capability module. +func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { + defer func() { + _, span := am.tracingInfo.Start("DexBeginBlockRollback") + defer span.End() + }() + + dexutils.GetMemState(ctx.Context()).Clear(ctx) + isNewEpoch, currentEpoch := am.keeper.IsNewEpoch(ctx) + if isNewEpoch { + am.keeper.SetEpoch(ctx, currentEpoch) + } + cachedCtx, cachedStore := store.GetCachedContext(ctx) + priceRetention := am.keeper.GetParams(ctx).PriceSnapshotRetention + cutOffTime := uint64(ctx.BlockTime().Unix()) - priceRetention + wg := sync.WaitGroup{} + mutex := sync.Mutex{} + allContracts := am.keeper.GetAllProcessableContractInfo(ctx) + allPricesToDelete := make(map[string][]*types.PriceStore, len(allContracts)) + + // Parallelize the logic to find all prices to delete + for _, contract := range allContracts { + wg.Add(1) + go func(contract types.ContractInfoV2) { + priceKeysToDelete := am.getPriceToDelete(cachedCtx, contract, cutOffTime) + mutex.Lock() + allPricesToDelete[contract.ContractAddr] = priceKeysToDelete + mutex.Unlock() + wg.Done() + }(contract) + } + wg.Wait() + + // Execute the deletion in order + for _, contract := range allContracts { + if priceStores, found := allPricesToDelete[contract.ContractAddr]; found { + for _, priceStore := range priceStores { + for _, key := range priceStore.PriceKeys { + priceStore.Store.Delete(key) + } + } + } + } + // only write if all contracts have been processed + cachedStore.Write() +} + +func (am AppModule) getPriceToDelete( + ctx sdk.Context, + contract types.ContractInfoV2, + timestamp uint64, +) []*types.PriceStore { + var result []*types.PriceStore + if contract.NeedOrderMatching { + for _, pair := range am.keeper.GetAllRegisteredPairs(ctx, contract.ContractAddr) { + store := prefix.NewStore(ctx.KVStore(am.keeper.GetStoreKey()), types.PricePrefix(contract.ContractAddr, pair.PriceDenom, pair.AssetDenom)) + keysToDelete := am.keeper.GetPriceKeysToDelete(store, timestamp) + result = append(result, &types.PriceStore{ + Store: store, + PriceKeys: keysToDelete, + }) + } + } + return result +} + +// EndBlock executes all ABCI EndBlock logic respective to the capability module. It +// returns no validator updates. +func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) (ret []abci.ValidatorUpdate) { + defer func() { + if err := recover(); err != nil { + telemetry.IncrCounter(1, "recovered_panics") + ctx.Logger().Error(fmt.Sprintf("panic in endblock recovered: %s", err)) + } + }() + _, span := am.tracingInfo.Start("DexEndBlock") + defer span.End() + defer dexutils.GetMemState(ctx.Context()).Clear(ctx) + + validContractsInfo := am.keeper.GetAllProcessableContractInfo(ctx) + // Each iteration is atomic. If an iteration finishes without any error, it will return, + // otherwise it will rollback any state change, filter out contracts that cause the error, + // and proceed to the next iteration. The loop is guaranteed to finish since + // `validContractAddresses` will always decrease in size every iteration. + iterCounter := len(validContractsInfo) + endBlockerStartTime := time.Now() + for len(validContractsInfo) > 0 { + newValidContractsInfo, newOutOfRentContractsInfo, failedContractToReasons, ctx, ok := contract.EndBlockerAtomic(ctx, &am.keeper, validContractsInfo, am.tracingInfo) + if ok { + break + } + telemetry.IncrCounter(float32(len(newOutOfRentContractsInfo)), am.Name(), "total_out_of_rent_contracts") + keptContractAddrs := datastructures.NewSyncSet(utils.Map(newValidContractsInfo, func(c types.ContractInfoV2) string { return c.ContractAddr })) + keptContractAddrs.AddAll(utils.Map(newOutOfRentContractsInfo, func(c types.ContractInfoV2) string { return c.ContractAddr })) + for failedContract, reason := range failedContractToReasons { + ctx.Logger().Info(fmt.Sprintf("Suspending invalid contract %s", failedContract)) + err := am.keeper.SuspendContract(ctx, failedContract, reason) + if err != nil { + ctx.Logger().Error(fmt.Sprintf("failed to suspend invalid contract %s: %s", failedContract, err)) + } + telemetry.IncrCounter(float32(1), am.Name(), "total_suspended_contracts") + } + validContractsInfo = am.keeper.GetAllProcessableContractInfo(ctx) // reload contract info to get updated dependencies due to unregister above + if len(failedContractToReasons) != 0 { + dexutils.GetMemState(ctx.Context()).ClearContractToDependencies(ctx) + } + // technically we don't really need this if `EndBlockerAtomic` guarantees that `validContractsInfo` size will + // always shrink if not `ok`, but just in case, we decided to have an explicit termination criteria here to + // prevent the chain from being stuck. + iterCounter-- + if iterCounter == 0 { + ctx.Logger().Error("All contracts failed in dex EndBlock. Doing nothing.") + break + } + } + telemetry.MeasureSince(endBlockerStartTime, am.Name(), "total_end_blocker_atomic") + + return []abci.ValidatorUpdate{} +} diff --git a/x/dex/module_simulation.go b/x/dex/module_simulation.go new file mode 100644 index 000000000..c7b9f2942 --- /dev/null +++ b/x/dex/module_simulation.go @@ -0,0 +1,91 @@ +package dex + +import ( + "math/rand" + + "github.com/cosmos/cosmos-sdk/baseapp" + simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" + "github.com/cosmos/cosmos-sdk/x/simulation" + "github.com/sei-protocol/sei-chain/testutil/sample" + dexsimulation "github.com/sei-protocol/sei-chain/x/dex/simulation" + "github.com/sei-protocol/sei-chain/x/dex/types" +) + +// avoid unused import issue +var ( + _ = sample.AccAddress + _ = dexsimulation.FindAccount + _ = simappparams.StakePerAccount + _ = simulation.MsgEntryKind + _ = baseapp.Paramspace +) + +//nolint:deadcode,unused,gosec // Assume this will be used later, and gosec is nolint because there are no hard-coded credentials here. +const ( + opWeightMsgLimitBuy = "op_weight_msg_create_chain" + // TODO: Determine the simulation weight value + defaultWeightMsgLimitBuy int = 100 + + opWeightMsgLimitSell = "op_weight_msg_create_chain" + // TODO: Determine the simulation weight value + defaultWeightMsgLimitSell int = 100 + + opWeightMsgMarketBuy = "op_weight_msg_create_chain" + // TODO: Determine the simulation weight value + defaultWeightMsgMarketBuy int = 100 + + opWeightMsgMarketSell = "op_weight_msg_create_chain" + // TODO: Determine the simulation weight value + defaultWeightMsgMarketSell int = 100 + + opWeightMsgCancelBuy = "op_weight_msg_create_chain" + // TODO: Determine the simulation weight value + defaultWeightMsgCancelBuy int = 100 + + opWeightMsgCancelSell = "op_weight_msg_create_chain" + // TODO: Determine the simulation weight value + defaultWeightMsgCancelSell int = 100 + + opWeightMsgCancelAll = "op_weight_msg_create_chain" + // TODO: Determine the simulation weight value + defaultWeightMsgCancelAll int = 100 + + // this line is used by starport scaffolding # simapp/module/const +) + +// GenerateGenesisState creates a randomized GenState of the module +func (AppModule) GenerateGenesisState(simState *module.SimulationState) { + accs := make([]string, len(simState.Accounts)) + for i, acc := range simState.Accounts { + accs[i] = acc.Address.String() + } + dexGenesis := types.GenesisState{ + // this line is used by starport scaffolding # simapp/module/genesisState + } + simState.GenState[types.ModuleName] = simState.Cdc.MustMarshalJSON(&dexGenesis) +} + +// ProposalContents doesn't return any content functions for governance proposals +func (AppModule) ProposalContents(_ module.SimulationState) []simtypes.WeightedProposalContent { + return nil +} + +// RandomizedParams creates randomized param changes for the simulator +func (am AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { + return []simtypes.ParamChange{} +} + +// RegisterStoreDecoder registers a decoder +func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry) {} + +// WeightedOperations returns the all the gov module operations with their respective weights. +func (am AppModule) WeightedOperations(_ module.SimulationState) []simtypes.WeightedOperation { + operations := make([]simtypes.WeightedOperation, 0) + + // this line is used by starport scaffolding # simapp/module/operation + + return operations +} diff --git a/x/dex/module_test.go b/x/dex/module_test.go new file mode 100644 index 000000000..cea426c10 --- /dev/null +++ b/x/dex/module_test.go @@ -0,0 +1,835 @@ +package dex_test + +import ( + "context" + "io/ioutil" + "testing" + "time" + + wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper" + wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/utils/tracing" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + "github.com/sei-protocol/sei-chain/x/dex/contract" + "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" + minttypes "github.com/sei-protocol/sei-chain/x/mint/types" + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" +) + +const ( + GOOD_CONTRACT_INSTANTIATE = `{"whitelist": ["sei1h9yjz89tl0dl6zu65dpxcqnxfhq60wxx8s5kag"], + "use_whitelist":false,"admin":"sei1h9yjz89tl0dl6zu65dpxcqnxfhq60wxx8s5kag", + "limit_order_fee":{"decimal":"0.0001","negative":false}, + "market_order_fee":{"decimal":"0.0001","negative":false}, + "liquidation_order_fee":{"decimal":"0.0001","negative":false}, + "margin_ratio":{"decimal":"0.0625","negative":false}, + "max_leverage":{"decimal":"4","negative":false}, + "default_base":"USDC", + "native_token":"USDC","denoms": ["SEI","ATOM","USDC","SOL","ETH","OSMO","AVAX","BTC"], + "full_denom_mapping": [["usei","SEI","0.000001"],["uatom","ATOM","0.000001"],["uusdc","USDC","0.000001"]], + "funding_payment_lookback":3600,"spot_market_contract":"sei1h9yjz89tl0dl6zu65dpxcqnxfhq60wxx8s5kag", + "supported_collateral_denoms": ["USDC"], + "supported_multicollateral_denoms": ["ATOM"], + "oracle_denom_mapping": [["usei","SEI","1"],["uatom","ATOM","1"],["uusdc","USDC","1"],["ueth","ETH","1"]], + "multicollateral_whitelist": ["sei1h9yjz89tl0dl6zu65dpxcqnxfhq60wxx8s5kag"], + "multicollateral_whitelist_enable": true, + "funding_payment_pairs": [["USDC","ETH"]], + "default_margin_ratios":{ + "initial":"0.3", + "partial":"0.25", + "maintenance":"0.06" + }}` +) + +func TestEndBlockMarketOrder(t *testing.T) { + testApp := keepertest.TestApp() + dexkeeper := testApp.DexKeeper + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(dexkeeper.GetMemStoreKey()))) + pair := types.Pair{PriceDenom: "SEI", AssetDenom: "ATOM"} + + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(10000000)), sdk.NewCoin("uusdc", sdk.NewInt(10000000))) + bankkeeper := testApp.BankKeeper + bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts) + bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts) + dexAmounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(5000000)), sdk.NewCoin("uusdc", sdk.NewInt(10000000))) + bankkeeper.SendCoinsFromAccountToModule(ctx, testAccount, types.ModuleName, dexAmounts) + wasm, err := ioutil.ReadFile("./testdata/mars.wasm") + if err != nil { + panic(err) + } + wasmKeeper := testApp.WasmKeeper + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(&wasmKeeper) + var perm *wasmtypes.AccessConfig + codeId, err := contractKeeper.Create(ctx, testAccount, wasm, perm) + if err != nil { + panic(err) + } + contractAddr, _, err := contractKeeper.Instantiate(ctx, codeId, testAccount, testAccount, []byte(GOOD_CONTRACT_INSTANTIATE), "test", + sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100000)))) + if err != nil { + panic(err) + } + err = dexkeeper.SetContract(ctx, &types.ContractInfoV2{CodeId: 123, ContractAddr: contractAddr.String(), NeedHook: false, NeedOrderMatching: true, RentBalance: 100000000}) + if err != nil { + panic(err) + } + dexkeeper.AddRegisteredPair(ctx, contractAddr.String(), pair) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 1, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 2, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("2"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetDepositInfo(ctx, types.ContractAddress(contractAddr.String())).Add( + &types.DepositInfoEntry{ + Creator: testAccount.String(), + Denom: "uusdc", + Amount: sdk.MustNewDecFromStr("2000000"), + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + + ctx = ctx.WithBlockHeight(1) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + _, found := dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("1"), pair.PriceDenom, pair.AssetDenom) + // Long book should be populated + require.True(t, found) + + dexutils.GetMemState(ctx.Context()).Clear(ctx) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 3, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_MARKET, + PositionDirection: types.PositionDirection_SHORT, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + + ctx = ctx.WithBlockHeight(2) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + + // Long book should be removed since it's executed + // No state change should've been persisted for bad contract + _, found = dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("2"), pair.PriceDenom, pair.AssetDenom) + // Long book should be populated + require.False(t, found) + _, found = dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("1"), pair.PriceDenom, pair.AssetDenom) + require.True(t, found) + + matchResults, _ := dexkeeper.GetMatchResultState(ctx, contractAddr.String()) + require.Equal(t, 1, len(matchResults.Orders)) + require.Equal(t, 2, len(matchResults.Settlements)) + + dexutils.GetMemState(ctx.Context()).Clear(ctx) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 4, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("1000000"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_MARKET, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + + ctx = ctx.WithBlockHeight(3) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + + matchResults, _ = dexkeeper.GetMatchResultState(ctx, contractAddr.String()) + require.Equal(t, 1, len(matchResults.Orders)) + require.Equal(t, 0, len(matchResults.Settlements)) +} + +func TestEndBlockLimitOrder(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + dexkeeper := testApp.DexKeeper + pair := types.Pair{PriceDenom: "SEI", AssetDenom: "ATOM"} + + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(10000000)), sdk.NewCoin("uusdc", sdk.NewInt(10000000))) + bankkeeper := testApp.BankKeeper + bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts) + bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts) + dexAmounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(5000000)), sdk.NewCoin("uusdc", sdk.NewInt(10000000))) + bankkeeper.SendCoinsFromAccountToModule(ctx, testAccount, types.ModuleName, dexAmounts) + wasm, err := ioutil.ReadFile("./testdata/mars.wasm") + if err != nil { + panic(err) + } + wasmKeeper := testApp.WasmKeeper + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(&wasmKeeper) + var perm *wasmtypes.AccessConfig + codeId, err := contractKeeper.Create(ctx, testAccount, wasm, perm) + if err != nil { + panic(err) + } + contractAddr, _, err := contractKeeper.Instantiate(ctx, codeId, testAccount, testAccount, []byte(GOOD_CONTRACT_INSTANTIATE), "test", + sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100000)))) + if err != nil { + panic(err) + } + + dexkeeper.SetContract(ctx, &types.ContractInfoV2{CodeId: 123, ContractAddr: contractAddr.String(), NeedHook: false, NeedOrderMatching: true, RentBalance: 100000000}) + dexkeeper.AddRegisteredPair(ctx, contractAddr.String(), pair) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 1, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 2, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("2"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 3, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("3"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_SHORT, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetDepositInfo(ctx, types.ContractAddress(contractAddr.String())).Add( + &types.DepositInfoEntry{ + Creator: testAccount.String(), + Denom: "uusdc", + Amount: sdk.MustNewDecFromStr("2000000"), + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + + ctx = ctx.WithBlockHeight(1) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + _, found := dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("1"), pair.PriceDenom, pair.AssetDenom) + require.True(t, found) + _, found = dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("2"), pair.PriceDenom, pair.AssetDenom) + require.True(t, found) + _, found = dexkeeper.GetShortBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("3"), pair.PriceDenom, pair.AssetDenom) + require.True(t, found) + + dexutils.GetMemState(ctx.Context()).Clear(ctx) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 4, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("2"), + Quantity: sdk.MustNewDecFromStr("2"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_SHORT, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 5, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("3"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + + ctx = ctx.WithBlockHeight(2) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + + _, found = dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("2"), pair.PriceDenom, pair.AssetDenom) + require.False(t, found) + _, found = dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("1"), pair.PriceDenom, pair.AssetDenom) + require.True(t, found) + _, found = dexkeeper.GetShortBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("3"), pair.PriceDenom, pair.AssetDenom) + require.True(t, found) + _, found = dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("3"), pair.PriceDenom, pair.AssetDenom) + require.False(t, found) + + matchResults, _ := dexkeeper.GetMatchResultState(ctx, contractAddr.String()) + require.Equal(t, 2, len(matchResults.Orders)) + require.Equal(t, 4, len(matchResults.Settlements)) + + dexutils.GetMemState(ctx.Context()).Clear(ctx) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 6, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("1000000"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + + ctx = ctx.WithBlockHeight(3) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + + _, found = dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("1"), pair.PriceDenom, pair.AssetDenom) + require.True(t, found) + _, found = dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("1000000"), pair.PriceDenom, pair.AssetDenom) + require.False(t, found) + _, found = dexkeeper.GetShortBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("3"), pair.PriceDenom, pair.AssetDenom) + require.False(t, found) + + matchResults, _ = dexkeeper.GetMatchResultState(ctx, contractAddr.String()) + require.Equal(t, 1, len(matchResults.Orders)) + require.Equal(t, 2, len(matchResults.Settlements)) +} + +func TestEndBlockRollback(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + dexkeeper := testApp.DexKeeper + pair := TEST_PAIR() + // register contract and pair + dexkeeper.SetContract(ctx, &types.ContractInfoV2{CodeId: 123, ContractAddr: keepertest.TestContract, NeedHook: false, NeedOrderMatching: true, RentBalance: 100000000}) + dexkeeper.AddRegisteredPair(ctx, keepertest.TestContract, pair) + // place one order to a nonexistent contract + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(keepertest.TestContract), pair).Add( + &types.Order{ + Id: 1, + Account: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, keepertest.TestContract, dexkeeper.GetContractWithoutGasCharge) + ctx = ctx.WithBlockHeight(1) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + // No state change should've been persisted + matchResult, _ := dexkeeper.GetMatchResultState(ctx, keepertest.TestContract) + require.Equal(t, &types.MatchResult{}, matchResult) + // contract should be suspended + contract, err := dexkeeper.GetContract(ctx, keepertest.TestContract) + require.Nil(t, err) + require.True(t, contract.Suspended) +} + +func TestEndBlockPartialRollback(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + // BAD CONTRACT + dexkeeper := testApp.DexKeeper + pair := TEST_PAIR() + // register contract and pair + dexkeeper.SetContract(ctx, &types.ContractInfoV2{CodeId: 123, ContractAddr: keepertest.TestContract, NeedHook: false, NeedOrderMatching: true, RentBalance: 100000000}) + dexkeeper.AddRegisteredPair(ctx, keepertest.TestContract, pair) + // place one order to a nonexistent contract + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(keepertest.TestContract), pair).Add( + &types.Order{ + Id: 1, + Account: keepertest.TestAccount, + ContractAddr: keepertest.TestContract, + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, keepertest.TestContract, dexkeeper.GetContractWithoutGasCharge) + // GOOD CONTRACT + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(1000000)), sdk.NewCoin("uusdc", sdk.NewInt(1000000))) + bankkeeper := testApp.BankKeeper + bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts) + bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts) + dexAmounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(500000)), sdk.NewCoin("uusdc", sdk.NewInt(1000000))) + bankkeeper.SendCoinsFromAccountToModule(ctx, testAccount, types.ModuleName, dexAmounts) + wasm, err := ioutil.ReadFile("./testdata/mars.wasm") + if err != nil { + panic(err) + } + wasmKeeper := testApp.WasmKeeper + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(&wasmKeeper) + var perm *wasmtypes.AccessConfig + codeId, err := contractKeeper.Create(ctx, testAccount, wasm, perm) + if err != nil { + panic(err) + } + contractAddr, _, err := contractKeeper.Instantiate(ctx, codeId, testAccount, testAccount, []byte(GOOD_CONTRACT_INSTANTIATE), "test", + sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100000)))) + if err != nil { + panic(err) + } + dexkeeper.SetContract(ctx, &types.ContractInfoV2{CodeId: 123, ContractAddr: contractAddr.String(), NeedHook: false, NeedOrderMatching: true, RentBalance: 100000000}) + dexkeeper.AddRegisteredPair(ctx, contractAddr.String(), pair) + // place one order to the good contract + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 2, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("0.0001"), + Quantity: sdk.MustNewDecFromStr("0.0001"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetDepositInfo(ctx, types.ContractAddress(contractAddr.String())).Add( + &types.DepositInfoEntry{ + Creator: testAccount.String(), + Denom: "uusdc", + Amount: sdk.MustNewDecFromStr("10000"), + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + + ctx = ctx.WithBlockHeight(1) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + // No state change should've been persisted for bad contract + matchResult, _ := dexkeeper.GetMatchResultState(ctx, keepertest.TestContract) + require.Equal(t, &types.MatchResult{}, matchResult) + // bad contract should be suspended + contract, err := dexkeeper.GetContract(ctx, keepertest.TestContract) + require.Nil(t, err) + require.True(t, contract.Suspended) + // state change should've been persisted for good contract + matchResult, _ = dexkeeper.GetMatchResultState(ctx, contractAddr.String()) + require.Equal(t, 1, len(matchResult.Orders)) + _, found := dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("0.0001"), pair.PriceDenom, pair.AssetDenom) + require.True(t, found) +} + +func TestBeginBlock(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + dexkeeper := testApp.DexKeeper + + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(10000000))) + bankkeeper := testApp.BankKeeper + bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts) + bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts) + wasm, err := ioutil.ReadFile("./testdata/mars.wasm") + if err != nil { + panic(err) + } + wasmKeeper := testApp.WasmKeeper + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(&wasmKeeper) + var perm *wasmtypes.AccessConfig + codeId, err := contractKeeper.Create(ctx, testAccount, wasm, perm) + if err != nil { + panic(err) + } + contractAddr, _, err := contractKeeper.Instantiate(ctx, codeId, testAccount, testAccount, []byte(GOOD_CONTRACT_INSTANTIATE), "test", + sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100000)))) + if err != nil { + panic(err) + } + dexkeeper.SetContract(ctx, &types.ContractInfoV2{CodeId: 123, ContractAddr: contractAddr.String(), NeedHook: false, NeedOrderMatching: true, RentBalance: 100000000}) + + // right now just make sure it doesn't crash since it doesn't register any state to be checked against + testApp.BeginBlocker(ctx, abci.RequestBeginBlock{}) +} + +// Note that once the bug that causes EndBlock to panic is fixed, this test will need to be +// updated to trigger the next bug that causes panics, if any. +func TestEndBlockPanicHandling(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + dexkeeper := testApp.DexKeeper + pair := types.Pair{PriceDenom: "SEI", AssetDenom: "ATOM"} + + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(10000000))) + bankkeeper := testApp.BankKeeper + bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts) + bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts) + dexAmounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(5000000))) + bankkeeper.SendCoinsFromAccountToModule(ctx, testAccount, types.ModuleName, dexAmounts) + wasm, err := ioutil.ReadFile("./testdata/mars.wasm") + if err != nil { + panic(err) + } + wasmKeeper := testApp.WasmKeeper + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(&wasmKeeper) + var perm *wasmtypes.AccessConfig + codeId, err := contractKeeper.Create(ctx, testAccount, wasm, perm) + if err != nil { + panic(err) + } + contractAddr, _, err := contractKeeper.Instantiate(ctx, codeId, testAccount, testAccount, []byte(GOOD_CONTRACT_INSTANTIATE), "test", + sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100000)))) + if err != nil { + panic(err) + } + dexkeeper.SetContract(ctx, &types.ContractInfoV2{CodeId: 123, ContractAddr: contractAddr.String(), NeedHook: false, NeedOrderMatching: true, RentBalance: 100000000}) + dexkeeper.AddRegisteredPair(ctx, contractAddr.String(), pair) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 1, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.Dec{}, + Quantity: sdk.Dec{}, + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetDepositInfo(ctx, types.ContractAddress(contractAddr.String())).Add( + &types.DepositInfoEntry{ + Creator: testAccount.String(), + Denom: "usei", + Amount: sdk.MustNewDecFromStr("2000000"), + }, + ) + + require.NotPanics(t, func() { testApp.EndBlocker(ctx, abci.RequestEndBlock{}) }) + _, found := dexkeeper.GetLongBookByPrice(ctx, contractAddr.String(), sdk.MustNewDecFromStr("1"), pair.PriceDenom, pair.AssetDenom) + require.False(t, found) +} + +func TestEndBlockRollbackWithRentCharge(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + dexkeeper := testApp.DexKeeper + pair := TEST_PAIR() + // GOOD CONTRACT + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(1000000)), sdk.NewCoin("uusdc", sdk.NewInt(1000000))) + bankkeeper := testApp.BankKeeper + bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts) + bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts) + dexAmounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(500000)), sdk.NewCoin("uusdc", sdk.NewInt(1000000))) + bankkeeper.SendCoinsFromAccountToModule(ctx, testAccount, types.ModuleName, dexAmounts) + wasm, err := ioutil.ReadFile("./testdata/mars.wasm") + if err != nil { + panic(err) + } + wasmKeeper := testApp.WasmKeeper + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(&wasmKeeper) + var perm *wasmtypes.AccessConfig + codeId, err := contractKeeper.Create(ctx, testAccount, wasm, perm) + if err != nil { + panic(err) + } + contractAddr, _, err := contractKeeper.Instantiate(ctx, codeId, testAccount, testAccount, []byte(GOOD_CONTRACT_INSTANTIATE), "test", + sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100000)))) + if err != nil { + panic(err) + } + dexkeeper.SetContract(ctx, &types.ContractInfoV2{CodeId: 123, ContractAddr: contractAddr.String(), NeedHook: false, NeedOrderMatching: true, RentBalance: 1}) + dexkeeper.AddRegisteredPair(ctx, contractAddr.String(), pair) + // place one order to a nonexistent contract + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 2, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("0.0001"), + Quantity: sdk.MustNewDecFromStr("0.0001"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetDepositInfo(ctx, types.ContractAddress(contractAddr.String())).Add( + &types.DepositInfoEntry{ + Creator: testAccount.String(), + Denom: "uusdc", + Amount: sdk.MustNewDecFromStr("10000"), + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + // overwrite params for testing + params := dexkeeper.GetParams(ctx) + params.MinProcessableRent = 0 + dexkeeper.SetParams(ctx, params) + + ctx = ctx.WithBlockHeight(1) + creatorBalanceBefore := bankkeeper.GetBalance(ctx, testAccount, "usei") + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + // no state change should've been persisted for good contract because it should've run out of gas + matchResult, _ := dexkeeper.GetMatchResultState(ctx, contractAddr.String()) + require.Equal(t, 0, len(matchResult.Orders)) + // rent should still be charged even if the contract failed + c, err := dexkeeper.GetContract(ctx, contractAddr.String()) + require.Nil(t, err) + require.True(t, c.Suspended) // bad contract is suspended not because of out-of-rent but because of execution error + require.Equal(t, uint64(0), c.RentBalance) // rent balance should be drained + require.Equal(t, int64(1), dexkeeper.BankKeeper.GetBalance( + ctx, + dexkeeper.AccountKeeper.GetModuleAddress(authtypes.FeeCollectorName), + "usei", + ).Amount.Int64()) // bad contract rent should be sent to fee collector + creatorBalanceAfter := bankkeeper.GetBalance(ctx, testAccount, "usei") + require.Equal(t, creatorBalanceBefore, creatorBalanceAfter) +} + +func TestEndBlockContractWithoutPair(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + dexkeeper := testApp.DexKeeper + + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(10000000)), sdk.NewCoin("uusdc", sdk.NewInt(10000000))) + bankkeeper := testApp.BankKeeper + bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts) + bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts) + dexAmounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(5000000)), sdk.NewCoin("uusdc", sdk.NewInt(10000000))) + bankkeeper.SendCoinsFromAccountToModule(ctx, testAccount, types.ModuleName, dexAmounts) + wasm, err := ioutil.ReadFile("./testdata/mars.wasm") + if err != nil { + panic(err) + } + wasmKeeper := testApp.WasmKeeper + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(&wasmKeeper) + var perm *wasmtypes.AccessConfig + codeId, err := contractKeeper.Create(ctx, testAccount, wasm, perm) + if err != nil { + panic(err) + } + contractAddr, _, err := contractKeeper.Instantiate(ctx, codeId, testAccount, testAccount, []byte(GOOD_CONTRACT_INSTANTIATE), "test", + sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100000)))) + if err != nil { + panic(err) + } + + // no pair registered + contractInfo := types.ContractInfoV2{CodeId: 123, ContractAddr: contractAddr.String(), NeedHook: false, NeedOrderMatching: true, RentBalance: 100000000} + dexkeeper.SetContract(ctx, &contractInfo) + + tp := trace.NewNoopTracerProvider() + otel.SetTracerProvider(trace.NewNoopTracerProvider()) + tr := tp.Tracer("component-main") + ti := tracing.Info{ + Tracer: &tr, + } + _, _, _, _, success := contract.EndBlockerAtomic(ctx, &testApp.DexKeeper, []types.ContractInfoV2{contractInfo}, &ti) + require.True(t, success) + + contractInfo, err = dexkeeper.GetContract(ctx, contractInfo.ContractAddr) + require.Nil(t, err) + require.False(t, contractInfo.Suspended) +} + +func TestOrderCountUpdate(t *testing.T) { + testApp := keepertest.TestApp() + ctx := testApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(testApp.GetMemKey(types.MemStoreKey)))) + dexkeeper := testApp.DexKeeper + pair := types.Pair{PriceDenom: "SEI", AssetDenom: "ATOM"} + + testAccount, _ := sdk.AccAddressFromBech32("sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx") + amounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(10000000)), sdk.NewCoin("uusdc", sdk.NewInt(10000000))) + bankkeeper := testApp.BankKeeper + bankkeeper.MintCoins(ctx, minttypes.ModuleName, amounts) + bankkeeper.SendCoinsFromModuleToAccount(ctx, minttypes.ModuleName, testAccount, amounts) + dexAmounts := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(5000000)), sdk.NewCoin("uusdc", sdk.NewInt(10000000))) + bankkeeper.SendCoinsFromAccountToModule(ctx, testAccount, types.ModuleName, dexAmounts) + wasm, err := ioutil.ReadFile("./testdata/mars.wasm") + if err != nil { + panic(err) + } + wasmKeeper := testApp.WasmKeeper + contractKeeper := wasmkeeper.NewDefaultPermissionKeeper(&wasmKeeper) + var perm *wasmtypes.AccessConfig + codeId, err := contractKeeper.Create(ctx, testAccount, wasm, perm) + if err != nil { + panic(err) + } + contractAddr, _, err := contractKeeper.Instantiate(ctx, codeId, testAccount, testAccount, []byte(GOOD_CONTRACT_INSTANTIATE), "test", + sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(100000)))) + if err != nil { + panic(err) + } + + dexkeeper.SetContract(ctx, &types.ContractInfoV2{CodeId: 123, ContractAddr: contractAddr.String(), NeedHook: false, NeedOrderMatching: true, RentBalance: 100000000}) + dexkeeper.AddRegisteredPair(ctx, contractAddr.String(), pair) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 1, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 2, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("2"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 3, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("3"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_SHORT, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetDepositInfo(ctx, types.ContractAddress(contractAddr.String())).Add( + &types.DepositInfoEntry{ + Creator: testAccount.String(), + Denom: "uusdc", + Amount: sdk.MustNewDecFromStr("2000000"), + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + + ctx = ctx.WithBlockHeight(1) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + require.Equal(t, uint64(1), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(1))) + require.Equal(t, uint64(0), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_SHORT, sdk.NewDec(1))) + require.Equal(t, uint64(1), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(2))) + require.Equal(t, uint64(0), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_SHORT, sdk.NewDec(2))) + require.Equal(t, uint64(0), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(3))) + require.Equal(t, uint64(1), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_SHORT, sdk.NewDec(3))) + + dexutils.GetMemState(ctx.Context()).Clear(ctx) + dexutils.GetMemState(ctx.Context()).GetBlockOrders(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Order{ + Id: 4, + Account: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("1"), + Quantity: sdk.MustNewDecFromStr("1"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + OrderType: types.OrderType_LIMIT, + PositionDirection: types.PositionDirection_LONG, + Data: "{\"position_effect\":\"Open\",\"leverage\":\"1\"}", + }, + ) + dexutils.GetMemState(ctx.Context()).GetBlockCancels(ctx, types.ContractAddress(contractAddr.String()), pair).Add( + &types.Cancellation{ + Id: 2, + Creator: testAccount.String(), + ContractAddr: contractAddr.String(), + Price: sdk.MustNewDecFromStr("2"), + PriceDenom: pair.PriceDenom, + AssetDenom: pair.AssetDenom, + PositionDirection: types.PositionDirection_LONG, + }, + ) + dexutils.GetMemState(ctx.Context()).SetDownstreamsToProcess(ctx, contractAddr.String(), dexkeeper.GetContractWithoutGasCharge) + ctx = ctx.WithBlockHeight(2) + testApp.EndBlocker(ctx, abci.RequestEndBlock{}) + require.Equal(t, uint64(2), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(1))) + require.Equal(t, uint64(0), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_SHORT, sdk.NewDec(1))) + require.Equal(t, uint64(0), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(2))) + require.Equal(t, uint64(0), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_SHORT, sdk.NewDec(2))) + require.Equal(t, uint64(0), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_LONG, sdk.NewDec(3))) + require.Equal(t, uint64(1), dexkeeper.GetOrderCountState(ctx, contractAddr.String(), pair.PriceDenom, pair.AssetDenom, types.PositionDirection_SHORT, sdk.NewDec(3))) +} diff --git a/x/dex/simulation/simap.go b/x/dex/simulation/simap.go new file mode 100644 index 000000000..92c437c0d --- /dev/null +++ b/x/dex/simulation/simap.go @@ -0,0 +1,15 @@ +package simulation + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + simtypes "github.com/cosmos/cosmos-sdk/types/simulation" +) + +// FindAccount find a specific address from an account list +func FindAccount(accs []simtypes.Account, address string) (simtypes.Account, bool) { + creator, err := sdk.AccAddressFromBech32(address) + if err != nil { + panic(err) + } + return simtypes.FindAccount(accs, creator) +} diff --git a/x/dex/spec/README.md b/x/dex/spec/README.md new file mode 100644 index 000000000..36f46e3bd --- /dev/null +++ b/x/dex/spec/README.md @@ -0,0 +1,56 @@ +## Abstract +`dex` module is responsible for matching orders for registered contracts. + +## Concepts +### Frequent Batch Auction +The traditional implementation of exchange logic would look something like the following: +1. User A sends an order placement transaction +2. User B sends another order placement transaction +3. User A's transaction is processed by matching it against the order book state and settle accordingly +4. User B's transaction is processed similarly + +Sei's `dex` module takes a different approach: +1. User A sends an order placement transaction +2. User B sends another order placement transaction +3. User A's transaction is processed by simply adding the order to an in-memory queue, without matching +4. User B's transaction is processed similarly +5. At the end of the block that contains both transactions, the in-memory queue as a whole will be matched against the order book state + +Step 5 is where the majority of `dex`'s logic takes place. Specifically it consists of the follow stages for each market: +1. Cancel orders for transactions in the current block +2. Add new limit orders to the order book +3. Match market orders in the current block against the order book +4. Market limit orders in the current block against the order book + +### Contract Registration +Since `dex` only provides order matching logic, product logic specific to individual protocols still needs to be defined in CosmWasm contracts. As such, `dex` offers a way to inform the protocol contracts about order placement and matching results. `dex` achieves this by requiring contracts that want to leverage `dex`'s order matching logic to explicitly register via a special transaction type `MsgRegisterContract`. + +## State (KV Store) +The following prefixes are persisted in disk: +- "LongBook-value-": order book state on the long side where each entry represents a price level and can contain multiple orders at that same price. +- "ShortBook-value-": similar to the above but on the short side. +- "x-wasm-contract": contract registration information. +- "MatchResult-": match results of the most recent block. + +The following prefixes are only used intrablock and are cleared before committing the block, since they serve no purpose beyond the scope of its enclosing block and flushing them to disk would be computationally expensive: +- "MemOrder-": orders added by transactions in the current block and will be matched against the order book states at the end of the block. +- "MemCancel-": cancellations added by transactions in the current block and will update the order book states at the end of the block. + +## Hooks +A registered contract can define the following `sudo` hooks that will be called by the `dex` module at appropriate times: +- BulkOrderPlacements: informs the contract about order placements +- BulkOrderCancellations: informs the contract about order cancellations +- Settlement: informs the contract about matched orders and the settlement prices + +There are two more utility hooks that a contract can define for housekeeping purposes (e.g. recalculate TWAPs): +- NewBlock +- FinalizeBlock (note that this is distinct from ABCI++'s FinalizeBlock) + +## Transactions +- MsgPlaceOrders - place one or more orders against a registered contract +- MsgCancelOrders - cancel one or more orders against a registered contract +- MsgRegisterContract - register or reregister a CosmWasm contract with `dex` + + +## Spam Prevention +Conventionally, spamming to a blockchain is mainly mitigated through charging gas based on the resource a transaction consumes. With `dex`'s unique design though, the bulk of resource comsumption happens at the end of a block, which cannot be quantified precisely beforehand. Thus the `dex` module charges transaction messages of type MsgPlaceOrders and MsgCancelOrders based on a flat rate per order/cancel. This amount is guaranteed to well cover any `dex`-level computation, and any exceeded usage must have come from registered contract's logic being expensive and will be charged against the contract, which is required to post a rent sum upon registration. \ No newline at end of file diff --git a/x/dex/testdata/clearing_house.wasm b/x/dex/testdata/clearing_house.wasm new file mode 100644 index 000000000..358f88487 Binary files /dev/null and b/x/dex/testdata/clearing_house.wasm differ diff --git a/x/dex/testdata/mars.wasm b/x/dex/testdata/mars.wasm new file mode 100644 index 000000000..8addcee30 Binary files /dev/null and b/x/dex/testdata/mars.wasm differ diff --git a/x/dex/types/alias.go b/x/dex/types/alias.go new file mode 100644 index 000000000..e50603631 --- /dev/null +++ b/x/dex/types/alias.go @@ -0,0 +1,24 @@ +package types + +import ( + "fmt" + "strings" +) + +type ( + ContractAddress string + PairString string +) + +const PairDelim = "|" + +func GetPairString(pair *Pair) PairString { + return PairString( + fmt.Sprintf("%s%s%s", pair.PriceDenom, PairDelim, pair.AssetDenom), + ) +} + +func GetPriceAssetString(pairString PairString) (string, string) { + output := strings.Split(string(pairString), "|") + return output[0], output[1] +} diff --git a/x/dex/types/alias_test.go b/x/dex/types/alias_test.go new file mode 100644 index 000000000..76736bb99 --- /dev/null +++ b/x/dex/types/alias_test.go @@ -0,0 +1,20 @@ +package types_test + +import ( + "testing" + + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGetPairString(t *testing.T) { + pair := types.Pair{PriceDenom: "USDC", AssetDenom: "ATOM"} + expected := types.PairString("USDC|ATOM") + require.Equal(t, expected, types.GetPairString(&pair)) +} + +func TestGetPriceAssetString(t *testing.T) { + priceDenom, assetDenom := types.GetPriceAssetString(types.PairString("USDC|ATOM")) + require.Equal(t, "USDC", priceDenom) + require.Equal(t, "ATOM", assetDenom) +} diff --git a/x/dex/types/asset_list.pb.go b/x/dex/types/asset_list.pb.go new file mode 100644 index 000000000..4ae77c2d8 --- /dev/null +++ b/x/dex/types/asset_list.pb.go @@ -0,0 +1,768 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/asset_list.proto + +package types + +import ( + fmt "fmt" + types "github.com/cosmos/cosmos-sdk/x/bank/types" + _ "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 AssetIBCInfo struct { + SourceChannel string `protobuf:"bytes,1,opt,name=sourceChannel,proto3" json:"source_channel"` + DstChannel string `protobuf:"bytes,2,opt,name=dstChannel,proto3" json:"dst_channel"` + SourceDenom string `protobuf:"bytes,3,opt,name=sourceDenom,proto3" json:"source_denom"` + SourceChainID string `protobuf:"bytes,4,opt,name=sourceChainID,proto3" json:"source_chain_id"` +} + +func (m *AssetIBCInfo) Reset() { *m = AssetIBCInfo{} } +func (m *AssetIBCInfo) String() string { return proto.CompactTextString(m) } +func (*AssetIBCInfo) ProtoMessage() {} +func (*AssetIBCInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_65992190d1b6a2ed, []int{0} +} +func (m *AssetIBCInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AssetIBCInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AssetIBCInfo.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 *AssetIBCInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_AssetIBCInfo.Merge(m, src) +} +func (m *AssetIBCInfo) XXX_Size() int { + return m.Size() +} +func (m *AssetIBCInfo) XXX_DiscardUnknown() { + xxx_messageInfo_AssetIBCInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_AssetIBCInfo proto.InternalMessageInfo + +func (m *AssetIBCInfo) GetSourceChannel() string { + if m != nil { + return m.SourceChannel + } + return "" +} + +func (m *AssetIBCInfo) GetDstChannel() string { + if m != nil { + return m.DstChannel + } + return "" +} + +func (m *AssetIBCInfo) GetSourceDenom() string { + if m != nil { + return m.SourceDenom + } + return "" +} + +func (m *AssetIBCInfo) GetSourceChainID() string { + if m != nil { + return m.SourceChainID + } + return "" +} + +type AssetMetadata struct { + IbcInfo *AssetIBCInfo `protobuf:"bytes,1,opt,name=ibcInfo,proto3" json:"ibc_info"` + TypeAsset string `protobuf:"bytes,2,opt,name=type_asset,json=typeAsset,proto3" json:"type_asset"` + Metadata types.Metadata `protobuf:"bytes,3,opt,name=metadata,proto3" json:"metadata"` +} + +func (m *AssetMetadata) Reset() { *m = AssetMetadata{} } +func (m *AssetMetadata) String() string { return proto.CompactTextString(m) } +func (*AssetMetadata) ProtoMessage() {} +func (*AssetMetadata) Descriptor() ([]byte, []int) { + return fileDescriptor_65992190d1b6a2ed, []int{1} +} +func (m *AssetMetadata) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AssetMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AssetMetadata.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 *AssetMetadata) XXX_Merge(src proto.Message) { + xxx_messageInfo_AssetMetadata.Merge(m, src) +} +func (m *AssetMetadata) XXX_Size() int { + return m.Size() +} +func (m *AssetMetadata) XXX_DiscardUnknown() { + xxx_messageInfo_AssetMetadata.DiscardUnknown(m) +} + +var xxx_messageInfo_AssetMetadata proto.InternalMessageInfo + +func (m *AssetMetadata) GetIbcInfo() *AssetIBCInfo { + if m != nil { + return m.IbcInfo + } + return nil +} + +func (m *AssetMetadata) GetTypeAsset() string { + if m != nil { + return m.TypeAsset + } + return "" +} + +func (m *AssetMetadata) GetMetadata() types.Metadata { + if m != nil { + return m.Metadata + } + return types.Metadata{} +} + +func init() { + proto.RegisterType((*AssetIBCInfo)(nil), "seiprotocol.seichain.dex.AssetIBCInfo") + proto.RegisterType((*AssetMetadata)(nil), "seiprotocol.seichain.dex.AssetMetadata") +} + +func init() { proto.RegisterFile("dex/asset_list.proto", fileDescriptor_65992190d1b6a2ed) } + +var fileDescriptor_65992190d1b6a2ed = []byte{ + // 404 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x52, 0x31, 0xcf, 0xd3, 0x30, + 0x10, 0x4d, 0x00, 0xc1, 0xf7, 0x39, 0xfd, 0xda, 0xca, 0x74, 0x88, 0x2a, 0x91, 0xa0, 0x0e, 0x88, + 0xa5, 0xb6, 0x5a, 0x16, 0x18, 0x49, 0x2b, 0xa1, 0x0a, 0xc1, 0x90, 0x91, 0x25, 0x72, 0x1c, 0xb7, + 0xb5, 0x68, 0xec, 0xaa, 0x76, 0x51, 0xf9, 0x17, 0xfc, 0xac, 0x8e, 0x1d, 0x91, 0x90, 0x22, 0xd4, + 0x2e, 0x28, 0xbf, 0x02, 0xd9, 0x49, 0x4a, 0x3a, 0xb0, 0x3d, 0xdf, 0xdd, 0xbb, 0x7b, 0xef, 0xce, + 0x60, 0x90, 0xb1, 0x03, 0x26, 0x4a, 0x31, 0x9d, 0x6c, 0xb8, 0xd2, 0x68, 0xbb, 0x93, 0x5a, 0x42, + 0x5f, 0x31, 0x6e, 0x11, 0x95, 0x1b, 0xa4, 0x18, 0xa7, 0x6b, 0xc2, 0x05, 0xca, 0xd8, 0x61, 0x18, + 0x50, 0xa9, 0x72, 0xa9, 0x70, 0x4a, 0xc4, 0x57, 0xfc, 0x6d, 0x92, 0x32, 0x4d, 0x26, 0xf6, 0x51, + 0x31, 0x87, 0x83, 0x95, 0x5c, 0x49, 0x0b, 0xb1, 0x41, 0x55, 0x74, 0xf4, 0xc7, 0x05, 0x9d, 0xf7, + 0x66, 0xc8, 0x22, 0x9a, 0x2d, 0xc4, 0x52, 0xc2, 0xb7, 0xe0, 0x41, 0xc9, 0xfd, 0x8e, 0xb2, 0xd9, + 0x9a, 0x08, 0xc1, 0x36, 0xbe, 0xfb, 0xd2, 0x7d, 0x7d, 0x1f, 0xc1, 0xb2, 0x08, 0xbb, 0x55, 0x22, + 0xa1, 0x55, 0x26, 0xbe, 0x2d, 0x84, 0x18, 0x80, 0x4c, 0xe9, 0x86, 0xf6, 0xc8, 0xd2, 0x7a, 0x65, + 0x11, 0x7a, 0x99, 0xd2, 0x57, 0x4e, 0xab, 0x04, 0x4e, 0x81, 0x57, 0x75, 0x98, 0x33, 0x21, 0x73, + 0xff, 0xb1, 0x65, 0xf4, 0xcb, 0x22, 0xec, 0xd4, 0x83, 0x32, 0x13, 0x8f, 0xdb, 0x45, 0xf0, 0x5d, + 0x4b, 0x1e, 0x17, 0x8b, 0xb9, 0xff, 0xc4, 0xb2, 0x9e, 0x97, 0x45, 0xd8, 0xfb, 0x27, 0x8f, 0x8b, + 0x84, 0x67, 0xf1, 0x6d, 0xe5, 0xe8, 0x97, 0x0b, 0x1e, 0xac, 0xd5, 0x4f, 0x4c, 0x93, 0x8c, 0x68, + 0x02, 0x3f, 0x83, 0x67, 0x3c, 0xa5, 0xc6, 0xb6, 0x75, 0xe9, 0x4d, 0x5f, 0xa1, 0xff, 0xad, 0x17, + 0xb5, 0x97, 0x14, 0x75, 0xca, 0x22, 0xbc, 0xe3, 0x29, 0x4d, 0xb8, 0x58, 0xca, 0xb8, 0x69, 0x02, + 0xc7, 0x00, 0xe8, 0xef, 0x5b, 0x96, 0xd8, 0xab, 0xd5, 0x1b, 0xe8, 0x96, 0x45, 0xd8, 0x8a, 0xc6, + 0xf7, 0x06, 0xdb, 0x66, 0xf0, 0x23, 0xb8, 0xcb, 0x6b, 0x29, 0xd6, 0xbc, 0x37, 0x7d, 0x81, 0xaa, + 0x23, 0x22, 0x7b, 0xb7, 0xfa, 0x88, 0xa8, 0xd1, 0x1b, 0xf5, 0x8f, 0x45, 0xe8, 0x98, 0xd1, 0x0d, + 0x2d, 0xbe, 0xa2, 0xe8, 0xc3, 0xf1, 0x1c, 0xb8, 0xa7, 0x73, 0xe0, 0xfe, 0x3e, 0x07, 0xee, 0x8f, + 0x4b, 0xe0, 0x9c, 0x2e, 0x81, 0xf3, 0xf3, 0x12, 0x38, 0x5f, 0xc6, 0x2b, 0xae, 0xd7, 0xfb, 0x14, + 0x51, 0x99, 0x63, 0xc5, 0xf8, 0xb8, 0xf1, 0x67, 0x1f, 0xd6, 0x20, 0x3e, 0x60, 0xf3, 0xd9, 0x8c, + 0x32, 0x95, 0x3e, 0xb5, 0xf9, 0x37, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xa7, 0xaa, 0x78, 0x83, + 0x80, 0x02, 0x00, 0x00, +} + +func (m *AssetIBCInfo) 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 *AssetIBCInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AssetIBCInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SourceChainID) > 0 { + i -= len(m.SourceChainID) + copy(dAtA[i:], m.SourceChainID) + i = encodeVarintAssetList(dAtA, i, uint64(len(m.SourceChainID))) + i-- + dAtA[i] = 0x22 + } + if len(m.SourceDenom) > 0 { + i -= len(m.SourceDenom) + copy(dAtA[i:], m.SourceDenom) + i = encodeVarintAssetList(dAtA, i, uint64(len(m.SourceDenom))) + i-- + dAtA[i] = 0x1a + } + if len(m.DstChannel) > 0 { + i -= len(m.DstChannel) + copy(dAtA[i:], m.DstChannel) + i = encodeVarintAssetList(dAtA, i, uint64(len(m.DstChannel))) + i-- + dAtA[i] = 0x12 + } + if len(m.SourceChannel) > 0 { + i -= len(m.SourceChannel) + copy(dAtA[i:], m.SourceChannel) + i = encodeVarintAssetList(dAtA, i, uint64(len(m.SourceChannel))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *AssetMetadata) 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 *AssetMetadata) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AssetMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAssetList(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.TypeAsset) > 0 { + i -= len(m.TypeAsset) + copy(dAtA[i:], m.TypeAsset) + i = encodeVarintAssetList(dAtA, i, uint64(len(m.TypeAsset))) + i-- + dAtA[i] = 0x12 + } + if m.IbcInfo != nil { + { + size, err := m.IbcInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintAssetList(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintAssetList(dAtA []byte, offset int, v uint64) int { + offset -= sovAssetList(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *AssetIBCInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.SourceChannel) + if l > 0 { + n += 1 + l + sovAssetList(uint64(l)) + } + l = len(m.DstChannel) + if l > 0 { + n += 1 + l + sovAssetList(uint64(l)) + } + l = len(m.SourceDenom) + if l > 0 { + n += 1 + l + sovAssetList(uint64(l)) + } + l = len(m.SourceChainID) + if l > 0 { + n += 1 + l + sovAssetList(uint64(l)) + } + return n +} + +func (m *AssetMetadata) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IbcInfo != nil { + l = m.IbcInfo.Size() + n += 1 + l + sovAssetList(uint64(l)) + } + l = len(m.TypeAsset) + if l > 0 { + n += 1 + l + sovAssetList(uint64(l)) + } + l = m.Metadata.Size() + n += 1 + l + sovAssetList(uint64(l)) + return n +} + +func sovAssetList(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozAssetList(x uint64) (n int) { + return sovAssetList(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *AssetIBCInfo) 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 ErrIntOverflowAssetList + } + 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: AssetIBCInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AssetIBCInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceChannel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAssetList + } + 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 ErrInvalidLengthAssetList + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAssetList + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SourceChannel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DstChannel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAssetList + } + 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 ErrInvalidLengthAssetList + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAssetList + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DstChannel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceDenom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAssetList + } + 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 ErrInvalidLengthAssetList + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAssetList + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SourceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SourceChainID", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAssetList + } + 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 ErrInvalidLengthAssetList + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAssetList + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SourceChainID = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAssetList(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAssetList + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *AssetMetadata) 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 ErrIntOverflowAssetList + } + 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: AssetMetadata: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AssetMetadata: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IbcInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAssetList + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAssetList + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAssetList + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.IbcInfo == nil { + m.IbcInfo = &AssetIBCInfo{} + } + if err := m.IbcInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TypeAsset", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAssetList + } + 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 ErrInvalidLengthAssetList + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthAssetList + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TypeAsset = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowAssetList + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthAssetList + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthAssetList + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipAssetList(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthAssetList + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipAssetList(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, ErrIntOverflowAssetList + } + 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, ErrIntOverflowAssetList + } + 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, ErrIntOverflowAssetList + } + 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, ErrInvalidLengthAssetList + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupAssetList + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthAssetList + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthAssetList = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowAssetList = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupAssetList = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/codec.go b/x/dex/types/codec.go new file mode 100644 index 000000000..1dcfae37c --- /dev/null +++ b/x/dex/types/codec.go @@ -0,0 +1,71 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/codec" + cdctypes "github.com/cosmos/cosmos-sdk/codec/types" + cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/msgservice" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +func RegisterCodec(cdc *codec.LegacyAmino) { + cdc.RegisterConcrete(&MsgPlaceOrders{}, "dex/MsgPlaceOrders", nil) + cdc.RegisterConcrete(&MsgCancelOrders{}, "dex/MsgCancelOrders", nil) + cdc.RegisterConcrete(&MsgRegisterContract{}, "dex/MsgRegisterContract", nil) + cdc.RegisterConcrete(&MsgRegisterPairs{}, "dex/MsgRegisterPairs", nil) + cdc.RegisterConcrete(&MsgUpdatePriceTickSize{}, "dex/MsgUpdatePriceTickSize", nil) + cdc.RegisterConcrete(&MsgUpdateQuantityTickSize{}, "dex/MsgUpdateQuantityTickSize", nil) + cdc.RegisterConcrete(&AddAssetMetadataProposal{}, "dex/AddAssetMetadataProposal", nil) + cdc.RegisterConcrete(&MsgUnregisterContract{}, "dex/MsgUnregisterContract", nil) + cdc.RegisterConcrete(&MsgContractDepositRent{}, "dex/MsgContractDepositRent", nil) + cdc.RegisterConcrete(&MsgUnsuspendContract{}, "dex/MsgUnsuspendContract", nil) + // this line is used by starport scaffolding # 2 +} + +func RegisterInterfaces(registry cdctypes.InterfaceRegistry) { + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgPlaceOrders{}, + ) + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgCancelOrders{}, + ) + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgRegisterContract{}, + ) + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgRegisterPairs{}, + ) + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgUpdatePriceTickSize{}, + ) + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgUpdateQuantityTickSize{}, + ) + registry.RegisterImplementations((*govtypes.Content)(nil), + &AddAssetMetadataProposal{}, + ) + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgUnregisterContract{}, + ) + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgContractDepositRent{}, + ) + registry.RegisterImplementations((*sdk.Msg)(nil), + &MsgUnsuspendContract{}, + ) + // this line is used by starport scaffolding # 3 + + msgservice.RegisterMsgServiceDesc(registry, &_Msg_serviceDesc) +} + +var ( + Amino = codec.NewLegacyAmino() + ModuleCdc = codec.NewProtoCodec(cdctypes.NewInterfaceRegistry()) +) + +func init() { + RegisterCodec(Amino) + cryptocodec.RegisterCrypto(Amino) + Amino.Seal() +} diff --git a/x/dex/types/contract.pb.go b/x/dex/types/contract.pb.go new file mode 100644 index 000000000..701429157 --- /dev/null +++ b/x/dex/types/contract.pb.go @@ -0,0 +1,1902 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/contract.proto + +package types + +import ( + fmt "fmt" + 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 ContractInfo struct { + CodeId uint64 `protobuf:"varint,1,opt,name=codeId,proto3" json:"codeId,omitempty"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"` + NeedHook bool `protobuf:"varint,3,opt,name=needHook,proto3" json:"needHook,omitempty"` + NeedOrderMatching bool `protobuf:"varint,4,opt,name=needOrderMatching,proto3" json:"needOrderMatching,omitempty"` + Dependencies []*ContractDependencyInfo `protobuf:"bytes,5,rep,name=dependencies,proto3" json:"dependencies,omitempty"` + NumIncomingDependencies int64 `protobuf:"varint,6,opt,name=numIncomingDependencies,proto3" json:"numIncomingDependencies,omitempty"` +} + +func (m *ContractInfo) Reset() { *m = ContractInfo{} } +func (m *ContractInfo) String() string { return proto.CompactTextString(m) } +func (*ContractInfo) ProtoMessage() {} +func (*ContractInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_ee35557664974a8a, []int{0} +} +func (m *ContractInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContractInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractInfo.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 *ContractInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractInfo.Merge(m, src) +} +func (m *ContractInfo) XXX_Size() int { + return m.Size() +} +func (m *ContractInfo) XXX_DiscardUnknown() { + xxx_messageInfo_ContractInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractInfo proto.InternalMessageInfo + +func (m *ContractInfo) GetCodeId() uint64 { + if m != nil { + return m.CodeId + } + return 0 +} + +func (m *ContractInfo) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *ContractInfo) GetNeedHook() bool { + if m != nil { + return m.NeedHook + } + return false +} + +func (m *ContractInfo) GetNeedOrderMatching() bool { + if m != nil { + return m.NeedOrderMatching + } + return false +} + +func (m *ContractInfo) GetDependencies() []*ContractDependencyInfo { + if m != nil { + return m.Dependencies + } + return nil +} + +func (m *ContractInfo) GetNumIncomingDependencies() int64 { + if m != nil { + return m.NumIncomingDependencies + } + return 0 +} + +type ContractInfoV2 struct { + CodeId uint64 `protobuf:"varint,1,opt,name=codeId,proto3" json:"codeId,omitempty"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"` + NeedHook bool `protobuf:"varint,3,opt,name=needHook,proto3" json:"needHook,omitempty"` + NeedOrderMatching bool `protobuf:"varint,4,opt,name=needOrderMatching,proto3" json:"needOrderMatching,omitempty"` + Dependencies []*ContractDependencyInfo `protobuf:"bytes,5,rep,name=dependencies,proto3" json:"dependencies,omitempty"` + NumIncomingDependencies int64 `protobuf:"varint,6,opt,name=numIncomingDependencies,proto3" json:"numIncomingDependencies,omitempty"` + Creator string `protobuf:"bytes,7,opt,name=creator,proto3" json:"creator,omitempty"` + RentBalance uint64 `protobuf:"varint,8,opt,name=rentBalance,proto3" json:"rentBalance,omitempty"` + Suspended bool `protobuf:"varint,9,opt,name=suspended,proto3" json:"suspended,omitempty"` + SuspensionReason string `protobuf:"bytes,10,opt,name=suspensionReason,proto3" json:"suspensionReason,omitempty"` +} + +func (m *ContractInfoV2) Reset() { *m = ContractInfoV2{} } +func (m *ContractInfoV2) String() string { return proto.CompactTextString(m) } +func (*ContractInfoV2) ProtoMessage() {} +func (*ContractInfoV2) Descriptor() ([]byte, []int) { + return fileDescriptor_ee35557664974a8a, []int{1} +} +func (m *ContractInfoV2) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContractInfoV2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractInfoV2.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 *ContractInfoV2) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractInfoV2.Merge(m, src) +} +func (m *ContractInfoV2) XXX_Size() int { + return m.Size() +} +func (m *ContractInfoV2) XXX_DiscardUnknown() { + xxx_messageInfo_ContractInfoV2.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractInfoV2 proto.InternalMessageInfo + +func (m *ContractInfoV2) GetCodeId() uint64 { + if m != nil { + return m.CodeId + } + return 0 +} + +func (m *ContractInfoV2) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *ContractInfoV2) GetNeedHook() bool { + if m != nil { + return m.NeedHook + } + return false +} + +func (m *ContractInfoV2) GetNeedOrderMatching() bool { + if m != nil { + return m.NeedOrderMatching + } + return false +} + +func (m *ContractInfoV2) GetDependencies() []*ContractDependencyInfo { + if m != nil { + return m.Dependencies + } + return nil +} + +func (m *ContractInfoV2) GetNumIncomingDependencies() int64 { + if m != nil { + return m.NumIncomingDependencies + } + return 0 +} + +func (m *ContractInfoV2) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *ContractInfoV2) GetRentBalance() uint64 { + if m != nil { + return m.RentBalance + } + return 0 +} + +func (m *ContractInfoV2) GetSuspended() bool { + if m != nil { + return m.Suspended + } + return false +} + +func (m *ContractInfoV2) GetSuspensionReason() string { + if m != nil { + return m.SuspensionReason + } + return "" +} + +// suppose A is first registered and depends on X, then B is added and depends on X, +// and then C is added and depends on X, then A is the elder sibling to B and B is +// the younger sibling to A, and B is the elder sibling to C and C is the younger to B +type ContractDependencyInfo struct { + Dependency string `protobuf:"bytes,1,opt,name=dependency,proto3" json:"dependency,omitempty"` + ImmediateElderSibling string `protobuf:"bytes,2,opt,name=immediateElderSibling,proto3" json:"immediateElderSibling,omitempty"` + ImmediateYoungerSibling string `protobuf:"bytes,3,opt,name=immediateYoungerSibling,proto3" json:"immediateYoungerSibling,omitempty"` +} + +func (m *ContractDependencyInfo) Reset() { *m = ContractDependencyInfo{} } +func (m *ContractDependencyInfo) String() string { return proto.CompactTextString(m) } +func (*ContractDependencyInfo) ProtoMessage() {} +func (*ContractDependencyInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_ee35557664974a8a, []int{2} +} +func (m *ContractDependencyInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContractDependencyInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractDependencyInfo.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 *ContractDependencyInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractDependencyInfo.Merge(m, src) +} +func (m *ContractDependencyInfo) XXX_Size() int { + return m.Size() +} +func (m *ContractDependencyInfo) XXX_DiscardUnknown() { + xxx_messageInfo_ContractDependencyInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractDependencyInfo proto.InternalMessageInfo + +func (m *ContractDependencyInfo) GetDependency() string { + if m != nil { + return m.Dependency + } + return "" +} + +func (m *ContractDependencyInfo) GetImmediateElderSibling() string { + if m != nil { + return m.ImmediateElderSibling + } + return "" +} + +func (m *ContractDependencyInfo) GetImmediateYoungerSibling() string { + if m != nil { + return m.ImmediateYoungerSibling + } + return "" +} + +type LegacyContractInfo struct { + CodeId uint64 `protobuf:"varint,1,opt,name=codeId,proto3" json:"codeId,omitempty"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"` + NeedHook bool `protobuf:"varint,3,opt,name=needHook,proto3" json:"needHook,omitempty"` + NeedOrderMatching bool `protobuf:"varint,4,opt,name=needOrderMatching,proto3" json:"needOrderMatching,omitempty"` + DependentContractAddrs []string `protobuf:"bytes,5,rep,name=dependentContractAddrs,proto3" json:"dependentContractAddrs,omitempty"` +} + +func (m *LegacyContractInfo) Reset() { *m = LegacyContractInfo{} } +func (m *LegacyContractInfo) String() string { return proto.CompactTextString(m) } +func (*LegacyContractInfo) ProtoMessage() {} +func (*LegacyContractInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_ee35557664974a8a, []int{3} +} +func (m *LegacyContractInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LegacyContractInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LegacyContractInfo.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 *LegacyContractInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_LegacyContractInfo.Merge(m, src) +} +func (m *LegacyContractInfo) XXX_Size() int { + return m.Size() +} +func (m *LegacyContractInfo) XXX_DiscardUnknown() { + xxx_messageInfo_LegacyContractInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_LegacyContractInfo proto.InternalMessageInfo + +func (m *LegacyContractInfo) GetCodeId() uint64 { + if m != nil { + return m.CodeId + } + return 0 +} + +func (m *LegacyContractInfo) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *LegacyContractInfo) GetNeedHook() bool { + if m != nil { + return m.NeedHook + } + return false +} + +func (m *LegacyContractInfo) GetNeedOrderMatching() bool { + if m != nil { + return m.NeedOrderMatching + } + return false +} + +func (m *LegacyContractInfo) GetDependentContractAddrs() []string { + if m != nil { + return m.DependentContractAddrs + } + return nil +} + +type DownsteamContracts struct { + ContractAddrs []string `protobuf:"bytes,1,rep,name=contractAddrs,proto3" json:"contractAddrs,omitempty"` +} + +func (m *DownsteamContracts) Reset() { *m = DownsteamContracts{} } +func (m *DownsteamContracts) String() string { return proto.CompactTextString(m) } +func (*DownsteamContracts) ProtoMessage() {} +func (*DownsteamContracts) Descriptor() ([]byte, []int) { + return fileDescriptor_ee35557664974a8a, []int{4} +} +func (m *DownsteamContracts) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DownsteamContracts) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DownsteamContracts.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 *DownsteamContracts) XXX_Merge(src proto.Message) { + xxx_messageInfo_DownsteamContracts.Merge(m, src) +} +func (m *DownsteamContracts) XXX_Size() int { + return m.Size() +} +func (m *DownsteamContracts) XXX_DiscardUnknown() { + xxx_messageInfo_DownsteamContracts.DiscardUnknown(m) +} + +var xxx_messageInfo_DownsteamContracts proto.InternalMessageInfo + +func (m *DownsteamContracts) GetContractAddrs() []string { + if m != nil { + return m.ContractAddrs + } + return nil +} + +func init() { + proto.RegisterType((*ContractInfo)(nil), "seiprotocol.seichain.dex.ContractInfo") + proto.RegisterType((*ContractInfoV2)(nil), "seiprotocol.seichain.dex.ContractInfoV2") + proto.RegisterType((*ContractDependencyInfo)(nil), "seiprotocol.seichain.dex.ContractDependencyInfo") + proto.RegisterType((*LegacyContractInfo)(nil), "seiprotocol.seichain.dex.LegacyContractInfo") + proto.RegisterType((*DownsteamContracts)(nil), "seiprotocol.seichain.dex.DownsteamContracts") +} + +func init() { proto.RegisterFile("dex/contract.proto", fileDescriptor_ee35557664974a8a) } + +var fileDescriptor_ee35557664974a8a = []byte{ + // 481 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x54, 0x41, 0x8b, 0x13, 0x31, + 0x14, 0x6e, 0xb6, 0x6b, 0xb7, 0x7d, 0x5b, 0x45, 0x03, 0xd6, 0x20, 0x32, 0x0c, 0x83, 0x87, 0x22, + 0xee, 0x54, 0x56, 0x11, 0xf1, 0xe6, 0x6e, 0x45, 0x0b, 0x8a, 0x30, 0x8a, 0xa0, 0xb7, 0x34, 0x79, + 0x4e, 0x83, 0x9d, 0xa4, 0x4c, 0x52, 0x6c, 0xff, 0x85, 0x3f, 0xc2, 0x83, 0x07, 0x7f, 0x88, 0xc7, + 0xc5, 0x93, 0x47, 0x69, 0xff, 0x88, 0x4c, 0xba, 0xd3, 0x9d, 0xb2, 0xed, 0xdd, 0x83, 0xb7, 0xbc, + 0xef, 0x4b, 0xbe, 0xc7, 0xf7, 0xbd, 0x37, 0x03, 0x54, 0xe2, 0xac, 0x27, 0x8c, 0x76, 0x39, 0x17, + 0x2e, 0x9e, 0xe4, 0xc6, 0x19, 0xca, 0x2c, 0x2a, 0x7f, 0x12, 0x66, 0x1c, 0x5b, 0x54, 0x62, 0xc4, + 0x95, 0x8e, 0x25, 0xce, 0xa2, 0x6f, 0x7b, 0xd0, 0x3e, 0x3d, 0xbf, 0x3c, 0xd0, 0x9f, 0x0c, 0xed, + 0x40, 0x43, 0x18, 0x89, 0x03, 0xc9, 0x48, 0x48, 0xba, 0xfb, 0xc9, 0x79, 0x45, 0x23, 0x68, 0x97, + 0xa2, 0xcf, 0xa4, 0xcc, 0xd9, 0x5e, 0x48, 0xba, 0xad, 0x64, 0x03, 0xa3, 0xb7, 0xa1, 0xa9, 0x11, + 0xe5, 0x4b, 0x63, 0x3e, 0xb3, 0x7a, 0x48, 0xba, 0xcd, 0x64, 0x5d, 0xd3, 0xfb, 0x70, 0xa3, 0x38, + 0xbf, 0xc9, 0x25, 0xe6, 0xaf, 0xb9, 0x13, 0x23, 0xa5, 0x53, 0xb6, 0xef, 0x2f, 0x5d, 0x26, 0xe8, + 0x3b, 0x68, 0x4b, 0x9c, 0xa0, 0x96, 0xa8, 0x85, 0x42, 0xcb, 0xae, 0x84, 0xf5, 0xee, 0xe1, 0xf1, + 0x83, 0x78, 0x97, 0x8f, 0xb8, 0xf4, 0xd0, 0x2f, 0x5f, 0xcd, 0x0b, 0x37, 0xc9, 0x86, 0x0a, 0x7d, + 0x02, 0xb7, 0xf4, 0x34, 0x1b, 0x68, 0x61, 0x32, 0xa5, 0xd3, 0x7e, 0xb5, 0x41, 0x23, 0x24, 0xdd, + 0x7a, 0xb2, 0x8b, 0x8e, 0x7e, 0xd4, 0xe1, 0x5a, 0x35, 0xa6, 0xf7, 0xc7, 0xff, 0x83, 0xda, 0x46, + 0x53, 0x06, 0x07, 0x22, 0x47, 0xee, 0x4c, 0xce, 0x0e, 0xbc, 0xf1, 0xb2, 0xa4, 0x21, 0x1c, 0xe6, + 0xa8, 0xdd, 0x09, 0x1f, 0x73, 0x2d, 0x90, 0x35, 0x7d, 0x68, 0x55, 0x88, 0xde, 0x81, 0x96, 0x9d, + 0x5a, 0x2f, 0x26, 0x59, 0xcb, 0x3b, 0xbe, 0x00, 0xe8, 0x3d, 0xb8, 0xbe, 0x2a, 0xac, 0x32, 0x3a, + 0x41, 0x6e, 0x8d, 0x66, 0xe0, 0x5b, 0x5c, 0xc2, 0xa3, 0xef, 0x04, 0x3a, 0xdb, 0x8d, 0xd2, 0x00, + 0x60, 0x6d, 0x75, 0xee, 0x47, 0xd7, 0x4a, 0x2a, 0x08, 0x7d, 0x04, 0x37, 0x55, 0x96, 0xa1, 0x54, + 0xdc, 0xe1, 0xf3, 0xb1, 0xc4, 0xfc, 0xad, 0x1a, 0x8e, 0x8b, 0x11, 0xac, 0xe6, 0xb8, 0x9d, 0x2c, + 0x02, 0x5b, 0x13, 0x1f, 0xcc, 0x54, 0xa7, 0x17, 0xef, 0xea, 0xfe, 0xdd, 0x2e, 0x3a, 0xfa, 0x45, + 0x80, 0xbe, 0xc2, 0x94, 0x8b, 0xf9, 0x3f, 0xf8, 0x19, 0x3e, 0x86, 0x4e, 0x19, 0x8d, 0x3b, 0xad, + 0xb4, 0x58, 0xed, 0x59, 0x2b, 0xd9, 0xc1, 0x46, 0x4f, 0x81, 0xf6, 0xcd, 0x17, 0x6d, 0x1d, 0xf2, + 0xac, 0x64, 0x2c, 0xbd, 0x0b, 0x57, 0xc5, 0x86, 0x08, 0xf1, 0x22, 0x9b, 0xe0, 0xc9, 0x8b, 0x9f, + 0x8b, 0x80, 0x9c, 0x2d, 0x02, 0xf2, 0x67, 0x11, 0x90, 0xaf, 0xcb, 0xa0, 0x76, 0xb6, 0x0c, 0x6a, + 0xbf, 0x97, 0x41, 0xed, 0xe3, 0x51, 0xaa, 0xdc, 0x68, 0x3a, 0x8c, 0x85, 0xc9, 0x7a, 0x16, 0xd5, + 0x51, 0xb9, 0xe0, 0xbe, 0xf0, 0x1b, 0xde, 0x9b, 0xf5, 0x8a, 0xbf, 0x9f, 0x9b, 0x4f, 0xd0, 0x0e, + 0x1b, 0x9e, 0x7f, 0xf8, 0x37, 0x00, 0x00, 0xff, 0xff, 0x37, 0xae, 0xf3, 0x6f, 0x11, 0x05, 0x00, + 0x00, +} + +func (m *ContractInfo) 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 *ContractInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.NumIncomingDependencies != 0 { + i = encodeVarintContract(dAtA, i, uint64(m.NumIncomingDependencies)) + i-- + dAtA[i] = 0x30 + } + if len(m.Dependencies) > 0 { + for iNdEx := len(m.Dependencies) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Dependencies[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintContract(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if m.NeedOrderMatching { + i-- + if m.NeedOrderMatching { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if m.NeedHook { + i-- + if m.NeedHook { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintContract(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if m.CodeId != 0 { + i = encodeVarintContract(dAtA, i, uint64(m.CodeId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ContractInfoV2) 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 *ContractInfoV2) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractInfoV2) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.SuspensionReason) > 0 { + i -= len(m.SuspensionReason) + copy(dAtA[i:], m.SuspensionReason) + i = encodeVarintContract(dAtA, i, uint64(len(m.SuspensionReason))) + i-- + dAtA[i] = 0x52 + } + if m.Suspended { + i-- + if m.Suspended { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x48 + } + if m.RentBalance != 0 { + i = encodeVarintContract(dAtA, i, uint64(m.RentBalance)) + i-- + dAtA[i] = 0x40 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintContract(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0x3a + } + if m.NumIncomingDependencies != 0 { + i = encodeVarintContract(dAtA, i, uint64(m.NumIncomingDependencies)) + i-- + dAtA[i] = 0x30 + } + if len(m.Dependencies) > 0 { + for iNdEx := len(m.Dependencies) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Dependencies[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintContract(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if m.NeedOrderMatching { + i-- + if m.NeedOrderMatching { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if m.NeedHook { + i-- + if m.NeedHook { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintContract(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if m.CodeId != 0 { + i = encodeVarintContract(dAtA, i, uint64(m.CodeId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ContractDependencyInfo) 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 *ContractDependencyInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractDependencyInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ImmediateYoungerSibling) > 0 { + i -= len(m.ImmediateYoungerSibling) + copy(dAtA[i:], m.ImmediateYoungerSibling) + i = encodeVarintContract(dAtA, i, uint64(len(m.ImmediateYoungerSibling))) + i-- + dAtA[i] = 0x1a + } + if len(m.ImmediateElderSibling) > 0 { + i -= len(m.ImmediateElderSibling) + copy(dAtA[i:], m.ImmediateElderSibling) + i = encodeVarintContract(dAtA, i, uint64(len(m.ImmediateElderSibling))) + i-- + dAtA[i] = 0x12 + } + if len(m.Dependency) > 0 { + i -= len(m.Dependency) + copy(dAtA[i:], m.Dependency) + i = encodeVarintContract(dAtA, i, uint64(len(m.Dependency))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LegacyContractInfo) 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 *LegacyContractInfo) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LegacyContractInfo) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.DependentContractAddrs) > 0 { + for iNdEx := len(m.DependentContractAddrs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.DependentContractAddrs[iNdEx]) + copy(dAtA[i:], m.DependentContractAddrs[iNdEx]) + i = encodeVarintContract(dAtA, i, uint64(len(m.DependentContractAddrs[iNdEx]))) + i-- + dAtA[i] = 0x2a + } + } + if m.NeedOrderMatching { + i-- + if m.NeedOrderMatching { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } + if m.NeedHook { + i-- + if m.NeedHook { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintContract(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if m.CodeId != 0 { + i = encodeVarintContract(dAtA, i, uint64(m.CodeId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *DownsteamContracts) 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 *DownsteamContracts) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DownsteamContracts) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddrs) > 0 { + for iNdEx := len(m.ContractAddrs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.ContractAddrs[iNdEx]) + copy(dAtA[i:], m.ContractAddrs[iNdEx]) + i = encodeVarintContract(dAtA, i, uint64(len(m.ContractAddrs[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintContract(dAtA []byte, offset int, v uint64) int { + offset -= sovContract(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ContractInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CodeId != 0 { + n += 1 + sovContract(uint64(m.CodeId)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovContract(uint64(l)) + } + if m.NeedHook { + n += 2 + } + if m.NeedOrderMatching { + n += 2 + } + if len(m.Dependencies) > 0 { + for _, e := range m.Dependencies { + l = e.Size() + n += 1 + l + sovContract(uint64(l)) + } + } + if m.NumIncomingDependencies != 0 { + n += 1 + sovContract(uint64(m.NumIncomingDependencies)) + } + return n +} + +func (m *ContractInfoV2) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CodeId != 0 { + n += 1 + sovContract(uint64(m.CodeId)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovContract(uint64(l)) + } + if m.NeedHook { + n += 2 + } + if m.NeedOrderMatching { + n += 2 + } + if len(m.Dependencies) > 0 { + for _, e := range m.Dependencies { + l = e.Size() + n += 1 + l + sovContract(uint64(l)) + } + } + if m.NumIncomingDependencies != 0 { + n += 1 + sovContract(uint64(m.NumIncomingDependencies)) + } + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovContract(uint64(l)) + } + if m.RentBalance != 0 { + n += 1 + sovContract(uint64(m.RentBalance)) + } + if m.Suspended { + n += 2 + } + l = len(m.SuspensionReason) + if l > 0 { + n += 1 + l + sovContract(uint64(l)) + } + return n +} + +func (m *ContractDependencyInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Dependency) + if l > 0 { + n += 1 + l + sovContract(uint64(l)) + } + l = len(m.ImmediateElderSibling) + if l > 0 { + n += 1 + l + sovContract(uint64(l)) + } + l = len(m.ImmediateYoungerSibling) + if l > 0 { + n += 1 + l + sovContract(uint64(l)) + } + return n +} + +func (m *LegacyContractInfo) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CodeId != 0 { + n += 1 + sovContract(uint64(m.CodeId)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovContract(uint64(l)) + } + if m.NeedHook { + n += 2 + } + if m.NeedOrderMatching { + n += 2 + } + if len(m.DependentContractAddrs) > 0 { + for _, s := range m.DependentContractAddrs { + l = len(s) + n += 1 + l + sovContract(uint64(l)) + } + } + return n +} + +func (m *DownsteamContracts) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ContractAddrs) > 0 { + for _, s := range m.ContractAddrs { + l = len(s) + n += 1 + l + sovContract(uint64(l)) + } + } + return n +} + +func sovContract(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozContract(x uint64) (n int) { + return sovContract(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ContractInfo) 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 ErrIntOverflowContract + } + 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: ContractInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeId", wireType) + } + m.CodeId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NeedHook", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NeedHook = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NeedOrderMatching", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NeedOrderMatching = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dependencies", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthContract + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Dependencies = append(m.Dependencies, &ContractDependencyInfo{}) + if err := m.Dependencies[len(m.Dependencies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumIncomingDependencies", wireType) + } + m.NumIncomingDependencies = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumIncomingDependencies |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipContract(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthContract + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ContractInfoV2) 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 ErrIntOverflowContract + } + 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: ContractInfoV2: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractInfoV2: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeId", wireType) + } + m.CodeId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NeedHook", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NeedHook = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NeedOrderMatching", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NeedOrderMatching = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dependencies", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthContract + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Dependencies = append(m.Dependencies, &ContractDependencyInfo{}) + if err := m.Dependencies[len(m.Dependencies)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumIncomingDependencies", wireType) + } + m.NumIncomingDependencies = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumIncomingDependencies |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RentBalance", wireType) + } + m.RentBalance = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RentBalance |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Suspended", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Suspended = bool(v != 0) + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SuspensionReason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SuspensionReason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipContract(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthContract + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ContractDependencyInfo) 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 ErrIntOverflowContract + } + 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: ContractDependencyInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractDependencyInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Dependency", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Dependency = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ImmediateElderSibling", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ImmediateElderSibling = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ImmediateYoungerSibling", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ImmediateYoungerSibling = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipContract(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthContract + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LegacyContractInfo) 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 ErrIntOverflowContract + } + 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: LegacyContractInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LegacyContractInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CodeId", wireType) + } + m.CodeId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CodeId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NeedHook", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NeedHook = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NeedOrderMatching", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NeedOrderMatching = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DependentContractAddrs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DependentContractAddrs = append(m.DependentContractAddrs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipContract(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthContract + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DownsteamContracts) 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 ErrIntOverflowContract + } + 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: DownsteamContracts: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DownsteamContracts: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddrs", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowContract + } + 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 ErrInvalidLengthContract + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthContract + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddrs = append(m.ContractAddrs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipContract(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthContract + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipContract(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, ErrIntOverflowContract + } + 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, ErrIntOverflowContract + } + 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, ErrIntOverflowContract + } + 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, ErrInvalidLengthContract + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupContract + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthContract + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthContract = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowContract = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupContract = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/deposit.go b/x/dex/types/deposit.go new file mode 100644 index 000000000..3479571ad --- /dev/null +++ b/x/dex/types/deposit.go @@ -0,0 +1,19 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type ContractDepositInfo struct { + Account string `json:"account"` + Denom string `json:"denom"` + Amount sdk.Dec `json:"amount"` +} + +func (d *DepositInfoEntry) ToContractDepositInfo() ContractDepositInfo { + return ContractDepositInfo{ + Account: d.Creator, + Denom: d.Denom, + Amount: d.Amount, + } +} diff --git a/x/dex/types/deposit.pb.go b/x/dex/types/deposit.pb.go new file mode 100644 index 000000000..fbdaff23c --- /dev/null +++ b/x/dex/types/deposit.pb.go @@ -0,0 +1,422 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/deposit.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 DepositInfoEntry struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator"` + Denom string `protobuf:"bytes,2,opt,name=denom,proto3" json:"denom"` + Amount github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=amount,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"amount" yaml:"amount"` +} + +func (m *DepositInfoEntry) Reset() { *m = DepositInfoEntry{} } +func (m *DepositInfoEntry) String() string { return proto.CompactTextString(m) } +func (*DepositInfoEntry) ProtoMessage() {} +func (*DepositInfoEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_93caea15661b640e, []int{0} +} +func (m *DepositInfoEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DepositInfoEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DepositInfoEntry.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 *DepositInfoEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_DepositInfoEntry.Merge(m, src) +} +func (m *DepositInfoEntry) XXX_Size() int { + return m.Size() +} +func (m *DepositInfoEntry) XXX_DiscardUnknown() { + xxx_messageInfo_DepositInfoEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_DepositInfoEntry proto.InternalMessageInfo + +func (m *DepositInfoEntry) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *DepositInfoEntry) GetDenom() string { + if m != nil { + return m.Denom + } + return "" +} + +func init() { + proto.RegisterType((*DepositInfoEntry)(nil), "seiprotocol.seichain.dex.DepositInfoEntry") +} + +func init() { proto.RegisterFile("dex/deposit.proto", fileDescriptor_93caea15661b640e) } + +var fileDescriptor_93caea15661b640e = []byte{ + // 273 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x50, 0x3f, 0x4b, 0xfb, 0x40, + 0x18, 0xce, 0xfd, 0x7e, 0x58, 0x69, 0x44, 0xd0, 0xe0, 0x10, 0x1c, 0xee, 0x24, 0xa0, 0xb8, 0x24, + 0x19, 0xdc, 0x1c, 0x4b, 0x45, 0xba, 0x66, 0x74, 0x4b, 0x2f, 0xaf, 0xe9, 0x61, 0x93, 0x37, 0xe4, + 0xae, 0x90, 0x7c, 0x0b, 0xbf, 0x90, 0x7b, 0xc7, 0x8e, 0xe2, 0x70, 0x48, 0xb2, 0x65, 0xf4, 0x13, + 0x48, 0xef, 0x12, 0x70, 0x7a, 0x9f, 0x7f, 0x77, 0x0f, 0x3c, 0xee, 0x65, 0x06, 0x4d, 0x9c, 0x41, + 0x85, 0x52, 0xa8, 0xa8, 0xaa, 0x51, 0xa1, 0xe7, 0x4b, 0x10, 0x06, 0x71, 0xdc, 0x46, 0x12, 0x04, + 0xdf, 0xa4, 0xa2, 0x8c, 0x32, 0x68, 0xae, 0xaf, 0x72, 0xcc, 0xd1, 0x58, 0xf1, 0x11, 0xd9, 0x7c, + 0xf0, 0x41, 0xdc, 0x8b, 0xa5, 0xfd, 0x61, 0x55, 0xbe, 0xe2, 0x53, 0xa9, 0xea, 0xd6, 0xbb, 0x75, + 0x4f, 0x79, 0x0d, 0xa9, 0xc2, 0xda, 0x27, 0x37, 0xe4, 0x7e, 0xbe, 0x38, 0x1b, 0x34, 0x9b, 0xa4, + 0x64, 0x02, 0x1e, 0x73, 0x4f, 0x32, 0x28, 0xb1, 0xf0, 0xff, 0x99, 0xd0, 0x7c, 0xd0, 0xcc, 0x0a, + 0x89, 0x3d, 0x5e, 0xea, 0xce, 0xd2, 0x02, 0x77, 0xa5, 0xf2, 0xff, 0x9b, 0xc4, 0x6a, 0xaf, 0x99, + 0xf3, 0xa5, 0xd9, 0x5d, 0x2e, 0xd4, 0x66, 0xb7, 0x8e, 0x38, 0x16, 0x31, 0x47, 0x59, 0xa0, 0x1c, + 0x4f, 0x28, 0xb3, 0xb7, 0x58, 0xb5, 0x15, 0xc8, 0x68, 0x09, 0x7c, 0xd0, 0x6c, 0x7c, 0xff, 0xa3, + 0xd9, 0x79, 0x9b, 0x16, 0xdb, 0xc7, 0xc0, 0xf2, 0x20, 0x19, 0x8d, 0xc5, 0xf3, 0xbe, 0xa3, 0xe4, + 0xd0, 0x51, 0xf2, 0xdd, 0x51, 0xf2, 0xde, 0x53, 0xe7, 0xd0, 0x53, 0xe7, 0xb3, 0xa7, 0xce, 0x4b, + 0xf8, 0xa7, 0x44, 0x82, 0x08, 0xa7, 0x55, 0x0c, 0x31, 0xb3, 0xc4, 0xc7, 0xf1, 0x1a, 0xdb, 0xb7, + 0x9e, 0x19, 0xff, 0xe1, 0x37, 0x00, 0x00, 0xff, 0xff, 0x06, 0xf6, 0x98, 0x0a, 0x54, 0x01, 0x00, + 0x00, +} + +func (m *DepositInfoEntry) 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 *DepositInfoEntry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DepositInfoEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.Amount.Size() + i -= size + if _, err := m.Amount.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintDeposit(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + if len(m.Denom) > 0 { + i -= len(m.Denom) + copy(dAtA[i:], m.Denom) + i = encodeVarintDeposit(dAtA, i, uint64(len(m.Denom))) + i-- + dAtA[i] = 0x12 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintDeposit(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintDeposit(dAtA []byte, offset int, v uint64) int { + offset -= sovDeposit(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *DepositInfoEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovDeposit(uint64(l)) + } + l = len(m.Denom) + if l > 0 { + n += 1 + l + sovDeposit(uint64(l)) + } + l = m.Amount.Size() + n += 1 + l + sovDeposit(uint64(l)) + return n +} + +func sovDeposit(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozDeposit(x uint64) (n int) { + return sovDeposit(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *DepositInfoEntry) 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 ErrIntOverflowDeposit + } + 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: DepositInfoEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DepositInfoEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDeposit + } + 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 ErrInvalidLengthDeposit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDeposit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDeposit + } + 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 ErrInvalidLengthDeposit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDeposit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowDeposit + } + 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 ErrInvalidLengthDeposit + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthDeposit + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Amount.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipDeposit(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthDeposit + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipDeposit(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, ErrIntOverflowDeposit + } + 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, ErrIntOverflowDeposit + } + 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, ErrIntOverflowDeposit + } + 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, ErrInvalidLengthDeposit + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupDeposit + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthDeposit + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthDeposit = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowDeposit = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupDeposit = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/enums.go b/x/dex/types/enums.go new file mode 100644 index 000000000..0ac28ea0e --- /dev/null +++ b/x/dex/types/enums.go @@ -0,0 +1,29 @@ +package types + +import ( + "fmt" + "strings" +) + +func GetPositionEffectFromStr(str string) (PositionEffect, error) { + val, err := getEnumFromStr(str, PositionEffect_value) + return PositionEffect(val), err +} + +func GetPositionDirectionFromStr(str string) (PositionDirection, error) { + val, err := getEnumFromStr(str, PositionDirection_value) + return PositionDirection(val), err +} + +func GetOrderTypeFromStr(str string) (OrderType, error) { + val, err := getEnumFromStr(str, OrderType_value) + return OrderType(val), err +} + +func getEnumFromStr(str string, enumMap map[string]int32) (int32, error) { + upperStr := strings.ToUpper(str) + if val, ok := enumMap[upperStr]; ok { + return val, nil + } + return 0, fmt.Errorf("unknown enum literal: %s", str) +} diff --git a/x/dex/types/enums.pb.go b/x/dex/types/enums.pb.go new file mode 100644 index 000000000..97464194a --- /dev/null +++ b/x/dex/types/enums.pb.go @@ -0,0 +1,235 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/enums.proto + +package types + +import ( + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + math "math" +) + +// 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 PositionDirection int32 + +const ( + PositionDirection_LONG PositionDirection = 0 + PositionDirection_SHORT PositionDirection = 1 +) + +var PositionDirection_name = map[int32]string{ + 0: "LONG", + 1: "SHORT", +} + +var PositionDirection_value = map[string]int32{ + "LONG": 0, + "SHORT": 1, +} + +func (x PositionDirection) String() string { + return proto.EnumName(PositionDirection_name, int32(x)) +} + +func (PositionDirection) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_b8c5bb23c6eb0b88, []int{0} +} + +type PositionEffect int32 + +const ( + PositionEffect_OPEN PositionEffect = 0 + PositionEffect_CLOSE PositionEffect = 1 +) + +var PositionEffect_name = map[int32]string{ + 0: "OPEN", + 1: "CLOSE", +} + +var PositionEffect_value = map[string]int32{ + "OPEN": 0, + "CLOSE": 1, +} + +func (x PositionEffect) String() string { + return proto.EnumName(PositionEffect_name, int32(x)) +} + +func (PositionEffect) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_b8c5bb23c6eb0b88, []int{1} +} + +type OrderType int32 + +const ( + OrderType_LIMIT OrderType = 0 + OrderType_MARKET OrderType = 1 + OrderType_FOKMARKET OrderType = 3 + OrderType_FOKMARKETBYVALUE OrderType = 4 + OrderType_STOPLOSS OrderType = 5 + OrderType_STOPLIMIT OrderType = 6 +) + +var OrderType_name = map[int32]string{ + 0: "LIMIT", + 1: "MARKET", + 3: "FOKMARKET", + 4: "FOKMARKETBYVALUE", + 5: "STOPLOSS", + 6: "STOPLIMIT", +} + +var OrderType_value = map[string]int32{ + "LIMIT": 0, + "MARKET": 1, + "FOKMARKET": 3, + "FOKMARKETBYVALUE": 4, + "STOPLOSS": 5, + "STOPLIMIT": 6, +} + +func (x OrderType) String() string { + return proto.EnumName(OrderType_name, int32(x)) +} + +func (OrderType) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_b8c5bb23c6eb0b88, []int{2} +} + +type Unit int32 + +const ( + Unit_STANDARD Unit = 0 + Unit_MILLI Unit = 1 + Unit_MICRO Unit = 2 + Unit_NANO Unit = 3 +) + +var Unit_name = map[int32]string{ + 0: "STANDARD", + 1: "MILLI", + 2: "MICRO", + 3: "NANO", +} + +var Unit_value = map[string]int32{ + "STANDARD": 0, + "MILLI": 1, + "MICRO": 2, + "NANO": 3, +} + +func (x Unit) String() string { + return proto.EnumName(Unit_name, int32(x)) +} + +func (Unit) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_b8c5bb23c6eb0b88, []int{3} +} + +type OrderStatus int32 + +const ( + OrderStatus_PLACED OrderStatus = 0 + OrderStatus_FAILED_TO_PLACE OrderStatus = 1 + OrderStatus_CANCELLED OrderStatus = 2 + OrderStatus_FULFILLED OrderStatus = 3 +) + +var OrderStatus_name = map[int32]string{ + 0: "PLACED", + 1: "FAILED_TO_PLACE", + 2: "CANCELLED", + 3: "FULFILLED", +} + +var OrderStatus_value = map[string]int32{ + "PLACED": 0, + "FAILED_TO_PLACE": 1, + "CANCELLED": 2, + "FULFILLED": 3, +} + +func (x OrderStatus) String() string { + return proto.EnumName(OrderStatus_name, int32(x)) +} + +func (OrderStatus) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_b8c5bb23c6eb0b88, []int{4} +} + +type CancellationInitiator int32 + +const ( + CancellationInitiator_USER CancellationInitiator = 0 + CancellationInitiator_LIQUIDATED CancellationInitiator = 1 +) + +var CancellationInitiator_name = map[int32]string{ + 0: "USER", + 1: "LIQUIDATED", +} + +var CancellationInitiator_value = map[string]int32{ + "USER": 0, + "LIQUIDATED": 1, +} + +func (x CancellationInitiator) String() string { + return proto.EnumName(CancellationInitiator_name, int32(x)) +} + +func (CancellationInitiator) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_b8c5bb23c6eb0b88, []int{5} +} + +func init() { + proto.RegisterEnum("seiprotocol.seichain.dex.PositionDirection", PositionDirection_name, PositionDirection_value) + proto.RegisterEnum("seiprotocol.seichain.dex.PositionEffect", PositionEffect_name, PositionEffect_value) + proto.RegisterEnum("seiprotocol.seichain.dex.OrderType", OrderType_name, OrderType_value) + proto.RegisterEnum("seiprotocol.seichain.dex.Unit", Unit_name, Unit_value) + proto.RegisterEnum("seiprotocol.seichain.dex.OrderStatus", OrderStatus_name, OrderStatus_value) + proto.RegisterEnum("seiprotocol.seichain.dex.CancellationInitiator", CancellationInitiator_name, CancellationInitiator_value) +} + +func init() { proto.RegisterFile("dex/enums.proto", fileDescriptor_b8c5bb23c6eb0b88) } + +var fileDescriptor_b8c5bb23c6eb0b88 = []byte{ + // 394 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x3c, 0x91, 0xdf, 0x6e, 0xd3, 0x30, + 0x18, 0xc5, 0xe3, 0xb5, 0xab, 0xd6, 0x0f, 0xd8, 0x8c, 0x01, 0x89, 0xab, 0xdc, 0x21, 0xa1, 0x48, + 0x6b, 0x84, 0xe0, 0x05, 0xbc, 0xc4, 0x1d, 0xd6, 0xdc, 0x38, 0xe4, 0x0f, 0x12, 0xdc, 0x4c, 0x59, + 0xe2, 0x31, 0x4b, 0x5d, 0x52, 0x25, 0xae, 0xd4, 0xbd, 0x05, 0x8f, 0xc5, 0xe5, 0x2e, 0xb9, 0x44, + 0xed, 0x8b, 0x20, 0x3b, 0x8c, 0xbb, 0x73, 0x3e, 0x9f, 0xcf, 0xfe, 0xc9, 0x07, 0xce, 0x1a, 0xb5, + 0x0b, 0x55, 0xbb, 0xbd, 0x1f, 0x16, 0x9b, 0xbe, 0x33, 0x1d, 0x79, 0x3b, 0x28, 0xed, 0x54, 0xdd, + 0xad, 0x17, 0x83, 0xd2, 0xf5, 0x5d, 0xa5, 0xdb, 0x45, 0xa3, 0x76, 0xc1, 0x7b, 0x78, 0x99, 0x76, + 0x83, 0x36, 0xba, 0x6b, 0x63, 0xdd, 0xab, 0xda, 0x0a, 0x72, 0x02, 0x53, 0x21, 0x93, 0x4b, 0xec, + 0x91, 0x39, 0x1c, 0xe7, 0x9f, 0x65, 0x56, 0x60, 0x14, 0xbc, 0x83, 0xd3, 0xa7, 0x24, 0xbb, 0xbd, + 0x55, 0xb5, 0xb1, 0x31, 0x99, 0xb2, 0x64, 0x8c, 0x45, 0x42, 0xe6, 0x0c, 0xa3, 0xa0, 0x81, 0xb9, + 0xec, 0x1b, 0xd5, 0x17, 0x0f, 0x1b, 0x65, 0xe7, 0x82, 0xaf, 0x78, 0x81, 0x3d, 0x02, 0x30, 0x5b, + 0xd1, 0xec, 0x8a, 0x15, 0x18, 0x91, 0x17, 0x30, 0x5f, 0xca, 0xab, 0x7f, 0x76, 0x42, 0x5e, 0x03, + 0xfe, 0x6f, 0x2f, 0xbe, 0x7d, 0xa5, 0xa2, 0x64, 0x78, 0x4a, 0x9e, 0xc3, 0x49, 0x5e, 0xc8, 0x54, + 0xc8, 0x3c, 0xc7, 0xc7, 0x76, 0xc5, 0x39, 0x77, 0xdb, 0x2c, 0xf8, 0x04, 0xd3, 0xb2, 0xd5, 0x66, + 0x0c, 0xd1, 0x24, 0xa6, 0x59, 0x3c, 0x62, 0xac, 0xb8, 0x10, 0x1c, 0xa3, 0x51, 0x46, 0x99, 0xc4, + 0x47, 0x16, 0x33, 0xa1, 0x89, 0xc4, 0x93, 0x40, 0xc0, 0x33, 0xc7, 0x96, 0x9b, 0xca, 0x6c, 0x07, + 0x8b, 0x94, 0x0a, 0x1a, 0x31, 0xbb, 0xfa, 0x0a, 0xce, 0x96, 0x94, 0x0b, 0x16, 0x5f, 0x17, 0xf2, + 0xda, 0x4d, 0x47, 0xce, 0x88, 0x26, 0x11, 0x13, 0x82, 0xc5, 0xf8, 0xc8, 0x61, 0x97, 0x62, 0xc9, + 0x9d, 0x9d, 0x04, 0x1f, 0xe0, 0x4d, 0x54, 0xb5, 0xb5, 0x5a, 0xaf, 0x2b, 0xfb, 0x29, 0xbc, 0xd5, + 0x46, 0x57, 0xa6, 0xeb, 0xed, 0x83, 0x65, 0xce, 0x32, 0xec, 0x91, 0x53, 0x00, 0xc1, 0xbf, 0x94, + 0x3c, 0xa6, 0x05, 0x8b, 0x31, 0xba, 0xb8, 0xfc, 0xb5, 0xf7, 0xd1, 0xe3, 0xde, 0x47, 0x7f, 0xf6, + 0x3e, 0xfa, 0x79, 0xf0, 0xbd, 0xc7, 0x83, 0xef, 0xfd, 0x3e, 0xf8, 0xde, 0xf7, 0xf3, 0x1f, 0xda, + 0xdc, 0x6d, 0x6f, 0x16, 0x75, 0x77, 0x1f, 0x0e, 0x4a, 0x9f, 0x3f, 0xb5, 0xe5, 0x8c, 0xab, 0x2b, + 0xdc, 0x85, 0xb6, 0x56, 0xf3, 0xb0, 0x51, 0xc3, 0xcd, 0xcc, 0x9d, 0x7f, 0xfc, 0x1b, 0x00, 0x00, + 0xff, 0xff, 0x40, 0x7d, 0x48, 0x4c, 0xea, 0x01, 0x00, 0x00, +} diff --git a/x/dex/types/enums_test.go b/x/dex/types/enums_test.go new file mode 100644 index 000000000..1f8d1515b --- /dev/null +++ b/x/dex/types/enums_test.go @@ -0,0 +1,53 @@ +package types_test + +import ( + "testing" + + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGetPositionEffectFromStr(t *testing.T) { + effect := "Close" + expected := types.PositionEffect_CLOSE + actual, err := types.GetPositionEffectFromStr(effect) + + require.Nil(t, err) + require.Equal(t, expected, actual) + + // unidentified effect + effect = "invalid_effect" + _, err = types.GetPositionEffectFromStr(effect) + + require.NotNil(t, err) +} + +func TestGetPositionDirectionFromStr(t *testing.T) { + direction := "Long" + expected := types.PositionDirection_LONG + actual, err := types.GetPositionDirectionFromStr(direction) + + require.Nil(t, err) + require.Equal(t, expected, actual) + + // unidentified direction + direction = "invalid_direction" + _, err = types.GetPositionEffectFromStr(direction) + + require.NotNil(t, err) +} + +func TestGetOrderTypeFromStr(t *testing.T) { + orderType := "Market" + expected := types.OrderType_MARKET + actual, err := types.GetOrderTypeFromStr(orderType) + + require.Nil(t, err) + require.Equal(t, expected, actual) + + // unidentified direction + orderType = "invalid" + _, err = types.GetPositionEffectFromStr(orderType) + + require.NotNil(t, err) +} diff --git a/x/dex/types/errors.go b/x/dex/types/errors.go new file mode 100644 index 000000000..ecdd0253d --- /dev/null +++ b/x/dex/types/errors.go @@ -0,0 +1,28 @@ +package types + +// DONTCOVER + +import ( + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +// x/dex module sentinel errors +var ( + ErrEncodeDexPlaceOrders = sdkerrors.Register(ModuleName, 2, "Error while encoding dex order placement msg in wasmd") + ErrEncodeDexCancelOrders = sdkerrors.Register(ModuleName, 3, "Error while encoding dex order cancellation msg in wasmd") + ErrParsingSeiDexQuery = sdkerrors.Register(ModuleName, 4, "Error parsing SeiDexQuery") + ErrEncodingDexTwaps = sdkerrors.Register(ModuleName, 6, "Error encoding dex twaps as JSON") + ErrEncodingOrders = sdkerrors.Register(ModuleName, 8, "Error encoding orders as JSON") + ErrEncodingOrder = sdkerrors.Register(ModuleName, 10, "Error encoding order as JSON") + ErrEncodingOrderSimulation = sdkerrors.Register(ModuleName, 12, "Error encoding order simulation as JSON") + ErrInvalidOrderID = sdkerrors.Register(ModuleName, 13, "Error order id not found") + ErrEncodingLatestPrice = sdkerrors.Register(ModuleName, 14, "Error encoding latest price as JSON") + ErrUnknownSeiDexQuery = sdkerrors.Register(ModuleName, 15, "Error unknown sei dex query") + ErrPairNotRegistered = sdkerrors.Register(ModuleName, 16, "pair is not registered") + ErrContractNotExists = sdkerrors.Register(ModuleName, 17, "Error finding contract info") + ErrParsingContractInfo = sdkerrors.Register(ModuleName, 18, "Error parsing contract info") + ErrInsufficientRent = sdkerrors.Register(ModuleName, 19, "Error contract does not have sufficient fee") + ErrCircularContractDependency = sdkerrors.Register(ModuleName, 1103, "circular contract dependency detected") + ErrContractSuspended = sdkerrors.Register(ModuleName, 1104, "contract suspended") + ErrContractNotSuspended = sdkerrors.Register(ModuleName, 1105, "contract not suspended") +) diff --git a/x/dex/types/events.go b/x/dex/types/events.go new file mode 100644 index 000000000..a4a34ae5d --- /dev/null +++ b/x/dex/types/events.go @@ -0,0 +1,21 @@ +package types + +const ( + EventTypePlaceOrder = "place_order" + EventTypeCancelOrder = "cancel_order" + EventTypeDepositRent = "deposit_rent" + EventTypeRegisterContract = "register_contract" + EventTypeUnregisterContract = "unregister_contract" + EventTypeRegisterPair = "register_pair" + EventTypeSetQuantityTickSize = "set_quantity_tick_size" + EventTypeSetPriceTickSize = "set_price_tick_size" + + AttributeKeyOrderID = "order_id" + AttributeKeyCancellationID = "cancellation_id" + AttributeKeyContractAddress = "contract_address" + AttributeKeyRentBalance = "rent_balance" + AttributeKeyPriceDenom = "price_denom" + AttributeKeyAssetDenom = "asset_denom" + + AttributeValueCategory = ModuleName +) diff --git a/x/dex/types/expected_keepers.go b/x/dex/types/expected_keepers.go new file mode 100644 index 000000000..6aa6e9778 --- /dev/null +++ b/x/dex/types/expected_keepers.go @@ -0,0 +1,18 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth/types" +) + +// AccountKeeper defines the expected account keeper used for simulations (noalias) +type AccountKeeper interface { + GetAccount(ctx sdk.Context, addr sdk.AccAddress) types.AccountI + // Methods imported from account should be defined here +} + +// BankKeeper defines the expected interface needed to retrieve account balances. +type BankKeeper interface { + SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins + // Methods imported from bank should be defined here +} diff --git a/x/dex/types/genesis.go b/x/dex/types/genesis.go new file mode 100644 index 000000000..9c8f79642 --- /dev/null +++ b/x/dex/types/genesis.go @@ -0,0 +1,75 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// DefaultGenesis returns the default Capability genesis state +func DefaultGenesis() *GenesisState { + return &GenesisState{ + Params: DefaultParams(), + ContractState: []ContractState{}, + } +} + +// Validate performs basic genesis state validation returning an error upon any +// failure. +func (gs GenesisState) Validate() error { + paramErr := gs.Params.Validate() + if paramErr != nil { + return paramErr + } + for _, cs := range gs.ContractState { + csErr := cs.Validate() + if csErr != nil { + return csErr + } + } + return nil +} + +func (cs ContractState) Validate() error { + if len(cs.ContractInfo.ContractAddr) == 0 { + return fmt.Errorf("empty contract addr") + } + if _, err := sdk.AccAddressFromBech32(cs.ContractInfo.ContractAddr); err != nil { + return fmt.Errorf("contract address is invalid") + } + // Check for duplicated price in a single market + // Can only be a one price per pair per contract + type MarketPrice struct { + priceDenom string + assetDenom string + price uint64 + } + + // Check for duplication in longbook + longBookPriceMap := make(map[MarketPrice]struct{}) + for _, elem := range cs.LongBookList { + priceElem := MarketPrice{ + priceDenom: elem.Entry.PriceDenom, + assetDenom: elem.Entry.AssetDenom, + price: elem.Price.BigInt().Uint64(), + } + if _, ok := longBookPriceMap[priceElem]; ok { + return fmt.Errorf("duplicated price for longBook") + } + longBookPriceMap[priceElem] = struct{}{} + } + // Check for duplication in shortbook + shortBookPriceMap := make(map[MarketPrice]struct{}) + for _, elem := range cs.ShortBookList { + priceElem := MarketPrice{ + priceDenom: elem.Entry.PriceDenom, + assetDenom: elem.Entry.AssetDenom, + price: elem.Price.BigInt().Uint64(), + } + if _, ok := shortBookPriceMap[priceElem]; ok { + return fmt.Errorf("duplicated price for shortBook") + } + shortBookPriceMap[priceElem] = struct{}{} + } + return nil +} diff --git a/x/dex/types/genesis.pb.go b/x/dex/types/genesis.pb.go new file mode 100644 index 000000000..4bd5241f6 --- /dev/null +++ b/x/dex/types/genesis.pb.go @@ -0,0 +1,1188 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/genesis.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 + +// GenesisState defines the dex module's genesis state. +type GenesisState struct { + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` + ContractState []ContractState `protobuf:"bytes,2,rep,name=contractState,proto3" json:"contractState"` + LastEpoch uint64 `protobuf:"varint,3,opt,name=lastEpoch,proto3" json:"lastEpoch,omitempty"` +} + +func (m *GenesisState) Reset() { *m = GenesisState{} } +func (m *GenesisState) String() string { return proto.CompactTextString(m) } +func (*GenesisState) ProtoMessage() {} +func (*GenesisState) Descriptor() ([]byte, []int) { + return fileDescriptor_a803aaabd08db59d, []int{0} +} +func (m *GenesisState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GenesisState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_GenesisState.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 *GenesisState) XXX_Merge(src proto.Message) { + xxx_messageInfo_GenesisState.Merge(m, src) +} +func (m *GenesisState) XXX_Size() int { + return m.Size() +} +func (m *GenesisState) XXX_DiscardUnknown() { + xxx_messageInfo_GenesisState.DiscardUnknown(m) +} + +var xxx_messageInfo_GenesisState proto.InternalMessageInfo + +func (m *GenesisState) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +func (m *GenesisState) GetContractState() []ContractState { + if m != nil { + return m.ContractState + } + return nil +} + +func (m *GenesisState) GetLastEpoch() uint64 { + if m != nil { + return m.LastEpoch + } + return 0 +} + +type ContractState struct { + ContractInfo ContractInfoV2 `protobuf:"bytes,1,opt,name=contractInfo,proto3" json:"contractInfo"` + LongBookList []LongBook `protobuf:"bytes,2,rep,name=longBookList,proto3" json:"longBookList"` + ShortBookList []ShortBook `protobuf:"bytes,3,rep,name=shortBookList,proto3" json:"shortBookList"` + TriggeredOrdersList []Order `protobuf:"bytes,4,rep,name=triggeredOrdersList,proto3" json:"triggeredOrdersList"` + PairList []Pair `protobuf:"bytes,5,rep,name=pairList,proto3" json:"pairList"` + PriceList []ContractPairPrices `protobuf:"bytes,6,rep,name=priceList,proto3" json:"priceList"` + NextOrderId uint64 `protobuf:"varint,7,opt,name=nextOrderId,proto3" json:"nextOrderId,omitempty"` +} + +func (m *ContractState) Reset() { *m = ContractState{} } +func (m *ContractState) String() string { return proto.CompactTextString(m) } +func (*ContractState) ProtoMessage() {} +func (*ContractState) Descriptor() ([]byte, []int) { + return fileDescriptor_a803aaabd08db59d, []int{1} +} +func (m *ContractState) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContractState) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractState.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 *ContractState) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractState.Merge(m, src) +} +func (m *ContractState) XXX_Size() int { + return m.Size() +} +func (m *ContractState) XXX_DiscardUnknown() { + xxx_messageInfo_ContractState.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractState proto.InternalMessageInfo + +func (m *ContractState) GetContractInfo() ContractInfoV2 { + if m != nil { + return m.ContractInfo + } + return ContractInfoV2{} +} + +func (m *ContractState) GetLongBookList() []LongBook { + if m != nil { + return m.LongBookList + } + return nil +} + +func (m *ContractState) GetShortBookList() []ShortBook { + if m != nil { + return m.ShortBookList + } + return nil +} + +func (m *ContractState) GetTriggeredOrdersList() []Order { + if m != nil { + return m.TriggeredOrdersList + } + return nil +} + +func (m *ContractState) GetPairList() []Pair { + if m != nil { + return m.PairList + } + return nil +} + +func (m *ContractState) GetPriceList() []ContractPairPrices { + if m != nil { + return m.PriceList + } + return nil +} + +func (m *ContractState) GetNextOrderId() uint64 { + if m != nil { + return m.NextOrderId + } + return 0 +} + +type ContractPairPrices struct { + PricePair Pair `protobuf:"bytes,1,opt,name=pricePair,proto3" json:"pricePair"` + Prices []*Price `protobuf:"bytes,2,rep,name=prices,proto3" json:"prices,omitempty"` +} + +func (m *ContractPairPrices) Reset() { *m = ContractPairPrices{} } +func (m *ContractPairPrices) String() string { return proto.CompactTextString(m) } +func (*ContractPairPrices) ProtoMessage() {} +func (*ContractPairPrices) Descriptor() ([]byte, []int) { + return fileDescriptor_a803aaabd08db59d, []int{2} +} +func (m *ContractPairPrices) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ContractPairPrices) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ContractPairPrices.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 *ContractPairPrices) XXX_Merge(src proto.Message) { + xxx_messageInfo_ContractPairPrices.Merge(m, src) +} +func (m *ContractPairPrices) XXX_Size() int { + return m.Size() +} +func (m *ContractPairPrices) XXX_DiscardUnknown() { + xxx_messageInfo_ContractPairPrices.DiscardUnknown(m) +} + +var xxx_messageInfo_ContractPairPrices proto.InternalMessageInfo + +func (m *ContractPairPrices) GetPricePair() Pair { + if m != nil { + return m.PricePair + } + return Pair{} +} + +func (m *ContractPairPrices) GetPrices() []*Price { + if m != nil { + return m.Prices + } + return nil +} + +func init() { + proto.RegisterType((*GenesisState)(nil), "seiprotocol.seichain.dex.GenesisState") + proto.RegisterType((*ContractState)(nil), "seiprotocol.seichain.dex.ContractState") + proto.RegisterType((*ContractPairPrices)(nil), "seiprotocol.seichain.dex.ContractPairPrices") +} + +func init() { proto.RegisterFile("dex/genesis.proto", fileDescriptor_a803aaabd08db59d) } + +var fileDescriptor_a803aaabd08db59d = []byte{ + // 497 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x93, 0x4f, 0x6f, 0xd3, 0x30, + 0x18, 0xc6, 0x1b, 0x5a, 0x0a, 0x73, 0x5b, 0xfe, 0x78, 0x3b, 0x44, 0x15, 0xca, 0xa2, 0x72, 0xa0, + 0x07, 0x96, 0x48, 0xe5, 0xc0, 0x0d, 0xa1, 0x22, 0x34, 0x4d, 0xaa, 0xb4, 0xaa, 0x95, 0x40, 0xe2, + 0x82, 0xd2, 0xc4, 0xa4, 0xd6, 0xba, 0xbc, 0x91, 0x6d, 0xa4, 0xf2, 0x2d, 0xd8, 0x47, 0xe2, 0xb6, + 0xe3, 0x8e, 0x9c, 0x10, 0x6a, 0xbf, 0x08, 0xf2, 0x1b, 0x7b, 0x4d, 0x04, 0x59, 0xb9, 0xc5, 0x8f, + 0x9f, 0xf7, 0xe7, 0xf7, 0xb5, 0x9f, 0x90, 0xa7, 0x09, 0x5b, 0x87, 0x29, 0xcb, 0x98, 0xe4, 0x32, + 0xc8, 0x05, 0x28, 0xa0, 0xae, 0x64, 0x1c, 0xbf, 0x62, 0x58, 0x05, 0x92, 0xf1, 0x78, 0x19, 0xf1, + 0x2c, 0x48, 0xd8, 0xba, 0x7f, 0x94, 0x42, 0x0a, 0xb8, 0x15, 0xea, 0xaf, 0xc2, 0xdf, 0x7f, 0xa2, + 0x11, 0x79, 0x24, 0xa2, 0x4b, 0x43, 0xe8, 0x1f, 0x6a, 0x65, 0x05, 0x59, 0xfa, 0x79, 0x01, 0x70, + 0x61, 0xc4, 0x23, 0x2d, 0xca, 0x25, 0x08, 0x55, 0x56, 0x1f, 0x6b, 0x15, 0x44, 0xc2, 0x84, 0x11, + 0xa8, 0x16, 0x62, 0xc8, 0x94, 0x88, 0x62, 0x65, 0xb4, 0x47, 0xc5, 0x09, 0x5c, 0x94, 0x8b, 0x72, + 0xc1, 0x63, 0x56, 0x08, 0x83, 0x1f, 0x0e, 0xe9, 0x9e, 0x16, 0x43, 0xcc, 0x55, 0xa4, 0x18, 0x7d, + 0x43, 0xda, 0x45, 0x47, 0xae, 0xe3, 0x3b, 0xc3, 0xce, 0xc8, 0x0f, 0xea, 0x86, 0x0a, 0xa6, 0xe8, + 0x1b, 0xb7, 0xae, 0x7f, 0x1d, 0x37, 0x66, 0xa6, 0x8a, 0xce, 0x49, 0xcf, 0xf6, 0x80, 0x40, 0xf7, + 0x9e, 0xdf, 0x1c, 0x76, 0x46, 0x2f, 0xea, 0x31, 0xef, 0xca, 0x76, 0x43, 0xab, 0x32, 0xe8, 0x33, + 0x72, 0xb0, 0x8a, 0xa4, 0x7a, 0x9f, 0x43, 0xbc, 0x74, 0x9b, 0xbe, 0x33, 0x6c, 0xcd, 0x76, 0xc2, + 0xe0, 0xaa, 0x45, 0x7a, 0x15, 0x08, 0x9d, 0x91, 0xae, 0x05, 0x9c, 0x65, 0x5f, 0xc0, 0x8c, 0x32, + 0xdc, 0xdf, 0x83, 0x76, 0x7f, 0x18, 0x99, 0x26, 0x2a, 0x0c, 0x3a, 0x21, 0x5d, 0xfd, 0x30, 0x63, + 0x80, 0x8b, 0x09, 0x97, 0xca, 0xcc, 0x35, 0xa8, 0x67, 0x4e, 0x8c, 0xdb, 0xd2, 0xca, 0xd5, 0xf4, + 0x9c, 0xf4, 0xf0, 0x45, 0x6f, 0x71, 0x4d, 0xc4, 0x3d, 0xaf, 0xc7, 0xcd, 0xad, 0xdd, 0x5e, 0x51, + 0xa5, 0x9e, 0x7e, 0x24, 0x87, 0x4a, 0xf0, 0x34, 0x65, 0x82, 0x25, 0xe7, 0x3a, 0x15, 0x12, 0xb1, + 0x2d, 0xc4, 0x1e, 0xd7, 0x63, 0xd1, 0x6b, 0x90, 0xff, 0x22, 0xd0, 0xb7, 0xe4, 0xa1, 0x0e, 0x10, + 0xd2, 0xee, 0x23, 0xcd, 0xbb, 0x2b, 0x12, 0xdc, 0xc2, 0x6e, 0xab, 0xe8, 0x94, 0x1c, 0x60, 0xe4, + 0x10, 0xd1, 0x46, 0xc4, 0xcb, 0xfd, 0x4f, 0xa1, 0x51, 0x53, 0x5d, 0x66, 0x13, 0xb6, 0x83, 0x50, + 0x9f, 0x74, 0x32, 0xb6, 0x56, 0xd8, 0xe5, 0x59, 0xe2, 0x3e, 0xc0, 0x44, 0x94, 0xa5, 0xc1, 0x95, + 0x43, 0xe8, 0xdf, 0x24, 0x3a, 0x36, 0xad, 0x68, 0xc9, 0xa4, 0xe2, 0xff, 0xa6, 0xd9, 0x95, 0xd1, + 0xd7, 0xa4, 0x8d, 0x0b, 0x69, 0x22, 0x70, 0xc7, 0xe5, 0xe2, 0xa9, 0x33, 0x63, 0x1f, 0x9f, 0x5e, + 0x6f, 0x3c, 0xe7, 0x66, 0xe3, 0x39, 0xbf, 0x37, 0x9e, 0xf3, 0x7d, 0xeb, 0x35, 0x6e, 0xb6, 0x5e, + 0xe3, 0xe7, 0xd6, 0x6b, 0x7c, 0x3a, 0x49, 0xb9, 0x5a, 0x7e, 0x5d, 0x04, 0x31, 0x5c, 0x86, 0x92, + 0xf1, 0x13, 0x4b, 0xc3, 0x05, 0xe2, 0xc2, 0x75, 0xa8, 0x7f, 0x5d, 0xf5, 0x2d, 0x67, 0x72, 0xd1, + 0xc6, 0xfd, 0x57, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x8f, 0x4d, 0x7c, 0x7f, 0x83, 0x04, 0x00, + 0x00, +} + +func (m *GenesisState) 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 *GenesisState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.LastEpoch != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.LastEpoch)) + i-- + dAtA[i] = 0x18 + } + if len(m.ContractState) > 0 { + for iNdEx := len(m.ContractState) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ContractState[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ContractState) 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 *ContractState) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractState) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.NextOrderId != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.NextOrderId)) + i-- + dAtA[i] = 0x38 + } + if len(m.PriceList) > 0 { + for iNdEx := len(m.PriceList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PriceList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.PairList) > 0 { + for iNdEx := len(m.PairList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.PairList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if len(m.TriggeredOrdersList) > 0 { + for iNdEx := len(m.TriggeredOrdersList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.TriggeredOrdersList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.ShortBookList) > 0 { + for iNdEx := len(m.ShortBookList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ShortBookList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.LongBookList) > 0 { + for iNdEx := len(m.LongBookList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.LongBookList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.ContractInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *ContractPairPrices) 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 *ContractPairPrices) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ContractPairPrices) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Prices) > 0 { + for iNdEx := len(m.Prices) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Prices[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + { + size, err := m.PricePair.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenesis(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintGenesis(dAtA []byte, offset int, v uint64) int { + offset -= sovGenesis(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *GenesisState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.ContractState) > 0 { + for _, e := range m.ContractState { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if m.LastEpoch != 0 { + n += 1 + sovGenesis(uint64(m.LastEpoch)) + } + return n +} + +func (m *ContractState) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ContractInfo.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.LongBookList) > 0 { + for _, e := range m.LongBookList { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.ShortBookList) > 0 { + for _, e := range m.ShortBookList { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.TriggeredOrdersList) > 0 { + for _, e := range m.TriggeredOrdersList { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.PairList) > 0 { + for _, e := range m.PairList { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if len(m.PriceList) > 0 { + for _, e := range m.PriceList { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + if m.NextOrderId != 0 { + n += 1 + sovGenesis(uint64(m.NextOrderId)) + } + return n +} + +func (m *ContractPairPrices) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.PricePair.Size() + n += 1 + l + sovGenesis(uint64(l)) + if len(m.Prices) > 0 { + for _, e := range m.Prices { + l = e.Size() + n += 1 + l + sovGenesis(uint64(l)) + } + } + return n +} + +func sovGenesis(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGenesis(x uint64) (n int) { + return sovGenesis(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *GenesisState) 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 ErrIntOverflowGenesis + } + 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: GenesisState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GenesisState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", 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 + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractState", 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.ContractState = append(m.ContractState, ContractState{}) + if err := m.ContractState[len(m.ContractState)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LastEpoch", wireType) + } + m.LastEpoch = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LastEpoch |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ContractState) 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 ErrIntOverflowGenesis + } + 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: ContractState: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractState: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractInfo", 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 + } + if err := m.ContractInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LongBookList", 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.LongBookList = append(m.LongBookList, LongBook{}) + if err := m.LongBookList[len(m.LongBookList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShortBookList", 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.ShortBookList = append(m.ShortBookList, ShortBook{}) + if err := m.ShortBookList[len(m.ShortBookList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TriggeredOrdersList", 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.TriggeredOrdersList = append(m.TriggeredOrdersList, Order{}) + if err := m.TriggeredOrdersList[len(m.TriggeredOrdersList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PairList", 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.PairList = append(m.PairList, Pair{}) + if err := m.PairList[len(m.PairList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PriceList", 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.PriceList = append(m.PriceList, ContractPairPrices{}) + if err := m.PriceList[len(m.PriceList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NextOrderId", wireType) + } + m.NextOrderId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NextOrderId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ContractPairPrices) 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 ErrIntOverflowGenesis + } + 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: ContractPairPrices: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ContractPairPrices: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PricePair", 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 + } + if err := m.PricePair.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Prices", 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.Prices = append(m.Prices, &Price{}) + if err := m.Prices[len(m.Prices)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenesis(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenesis + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGenesis(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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrIntOverflowGenesis + } + 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, ErrInvalidLengthGenesis + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGenesis + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGenesis + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGenesis = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGenesis = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGenesis = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/genesis_test.go b/x/dex/types/genesis_test.go new file mode 100644 index 000000000..49384da41 --- /dev/null +++ b/x/dex/types/genesis_test.go @@ -0,0 +1,228 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestGenesisState_Validate(t *testing.T) { + for _, tc := range []struct { + desc string + genState *types.GenesisState + valid bool + }{ + { + desc: "default is valid", + genState: types.DefaultGenesis(), + valid: true, + }, + { + desc: "valid genesis state", + genState: &types.GenesisState{ + Params: types.DefaultParams(), + ContractState: []types.ContractState{ + { + LongBookList: []types.LongBook{ + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + { + Price: sdk.NewDec(1), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + }, + ShortBookList: []types.ShortBook{ + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + { + Price: sdk.NewDec(1), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + }, + ContractInfo: types.ContractInfoV2{ + CodeId: uint64(1), + ContractAddr: "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m", + }, + }, + }, + // this line is used by starport scaffolding # types/genesis/validField + }, + valid: true, + }, + { + desc: "same price multiple markets", + genState: &types.GenesisState{ + Params: types.DefaultParams(), + ContractState: []types.ContractState{ + { + LongBookList: []types.LongBook{ + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "USDC", + AssetDenom: "ATOM", + }, + }, + }, + ShortBookList: []types.ShortBook{ + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + { + Price: sdk.NewDec(1), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + }, + ContractInfo: types.ContractInfoV2{ + CodeId: uint64(1), + ContractAddr: "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m", + }, + }, + }, + // this line is used by starport scaffolding # types/genesis/validField + }, + valid: true, + }, + { + desc: "duplicated longBook", + genState: &types.GenesisState{ + Params: types.DefaultParams(), + ContractState: []types.ContractState{ + { + LongBookList: []types.LongBook{ + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + }, + ContractInfo: types.ContractInfoV2{ + CodeId: uint64(1), + ContractAddr: "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m", + }, + }, + }, + }, + valid: false, + }, + { + desc: "duplicated shortBook", + genState: &types.GenesisState{ + Params: types.DefaultParams(), + ContractState: []types.ContractState{ + { + ShortBookList: []types.ShortBook{ + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + }, + ContractInfo: types.ContractInfoV2{ + CodeId: uint64(1), + ContractAddr: "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m", + }, + }, + }, + }, + valid: false, + }, + { + desc: "invalid contract addr", + genState: &types.GenesisState{ + Params: types.DefaultParams(), + ContractState: []types.ContractState{ + { + ShortBookList: []types.ShortBook{ + { + Price: sdk.NewDec(0), + Entry: &types.OrderEntry{ + Price: sdk.NewDec(0), + PriceDenom: "SEI", + AssetDenom: "ATOM", + }, + }, + }, + ContractInfo: types.ContractInfoV2{ + CodeId: uint64(1), + ContractAddr: "invalid", + }, + }, + }, + }, + valid: false, + }, + // this line is used by starport scaffolding # types/genesis/testcase + } { + t.Run(tc.desc, func(t *testing.T) { + err := tc.genState.Validate() + if tc.valid { + require.NoError(t, err) + } else { + require.Error(t, err) + } + }) + } +} diff --git a/x/dex/types/gov.go b/x/dex/types/gov.go new file mode 100644 index 000000000..72cd85c4c --- /dev/null +++ b/x/dex/types/gov.go @@ -0,0 +1,57 @@ +package types + +import ( + "fmt" + "strings" + + sdk "github.com/cosmos/cosmos-sdk/types" + govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" +) + +const ( + ProposalTypeAddAssetMetadata = "AddAssetMetadata" +) + +func init() { + // for routing + govtypes.RegisterProposalType(ProposalTypeAddAssetMetadata) + // for marshal and unmarshal + govtypes.RegisterProposalTypeCodec(&AddAssetMetadataProposal{}, "dex/AddAssetMetadataProposal") +} + +func (p *AddAssetMetadataProposal) GetTitle() string { return p.Title } + +func (p *AddAssetMetadataProposal) GetDescription() string { return p.Description } + +func (p *AddAssetMetadataProposal) ProposalRoute() string { return RouterKey } + +func (p *AddAssetMetadataProposal) ProposalType() string { + return ProposalTypeAddAssetMetadata +} + +func (p *AddAssetMetadataProposal) ValidateBasic() error { + // Verify base denoms specified in proposal are well formed + for _, asset := range p.AssetList { + err := sdk.ValidateDenom(asset.Metadata.Base) + if err != nil { + return err + } + } + + err := govtypes.ValidateAbstract(p) + return err +} + +func (p AddAssetMetadataProposal) String() string { + assetRecords := "" + for _, asset := range p.AssetList { + assetRecords += asset.String() + } + var b strings.Builder + b.WriteString(fmt.Sprintf(`Add Asset Metadata Proposal: + Title: %s + Description: %s + Records: %s +`, p.Title, p.Description, assetRecords)) + return b.String() +} diff --git a/x/dex/types/gov.pb.go b/x/dex/types/gov.pb.go new file mode 100644 index 000000000..cbfe56b15 --- /dev/null +++ b/x/dex/types/gov.pb.go @@ -0,0 +1,418 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/gov.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 + +// AddAssetMetadataProposal is a gov Content type for adding a new asset +// to the dex module's asset list. +type AddAssetMetadataProposal struct { + Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty" yaml:"title"` + Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` + AssetList []AssetMetadata `protobuf:"bytes,3,rep,name=assetList,proto3" json:"assetList" yaml:"asset_list"` +} + +func (m *AddAssetMetadataProposal) Reset() { *m = AddAssetMetadataProposal{} } +func (*AddAssetMetadataProposal) ProtoMessage() {} +func (*AddAssetMetadataProposal) Descriptor() ([]byte, []int) { + return fileDescriptor_dab07ca1a96062d0, []int{0} +} +func (m *AddAssetMetadataProposal) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *AddAssetMetadataProposal) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_AddAssetMetadataProposal.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 *AddAssetMetadataProposal) XXX_Merge(src proto.Message) { + xxx_messageInfo_AddAssetMetadataProposal.Merge(m, src) +} +func (m *AddAssetMetadataProposal) XXX_Size() int { + return m.Size() +} +func (m *AddAssetMetadataProposal) XXX_DiscardUnknown() { + xxx_messageInfo_AddAssetMetadataProposal.DiscardUnknown(m) +} + +var xxx_messageInfo_AddAssetMetadataProposal proto.InternalMessageInfo + +func init() { + proto.RegisterType((*AddAssetMetadataProposal)(nil), "seiprotocol.seichain.dex.AddAssetMetadataProposal") +} + +func init() { proto.RegisterFile("dex/gov.proto", fileDescriptor_dab07ca1a96062d0) } + +var fileDescriptor_dab07ca1a96062d0 = []byte{ + // 307 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4d, 0x49, 0xad, 0xd0, + 0x4f, 0xcf, 0x2f, 0xd3, 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, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x52, 0xfa, 0x20, 0x16, 0x44, 0xbd, 0x94, 0x08, 0x48, + 0x7b, 0x62, 0x71, 0x71, 0x6a, 0x49, 0x7c, 0x4e, 0x66, 0x71, 0x09, 0x44, 0x54, 0xe9, 0x0d, 0x23, + 0x97, 0x84, 0x63, 0x4a, 0x8a, 0x23, 0x48, 0xdc, 0x37, 0xb5, 0x24, 0x31, 0x25, 0xb1, 0x24, 0x31, + 0xa0, 0x28, 0xbf, 0x20, 0xbf, 0x38, 0x31, 0x47, 0x48, 0x8d, 0x8b, 0xb5, 0x24, 0xb3, 0x24, 0x27, + 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0xd3, 0x49, 0xe0, 0xd3, 0x3d, 0x79, 0x9e, 0xca, 0xc4, 0xdc, + 0x1c, 0x2b, 0x25, 0xb0, 0xb0, 0x52, 0x10, 0x44, 0x5a, 0xc8, 0x82, 0x8b, 0x3b, 0x25, 0xb5, 0x38, + 0xb9, 0x28, 0xb3, 0xa0, 0x24, 0x33, 0x3f, 0x4f, 0x82, 0x09, 0xac, 0x5a, 0xec, 0xd3, 0x3d, 0x79, + 0x21, 0x88, 0x6a, 0x24, 0x49, 0xa5, 0x20, 0x64, 0xa5, 0x42, 0x09, 0x5c, 0x9c, 0x60, 0x27, 0xf9, + 0x64, 0x16, 0x97, 0x48, 0x30, 0x2b, 0x30, 0x6b, 0x70, 0x1b, 0xa9, 0xeb, 0xe1, 0xf2, 0x98, 0x1e, + 0x8a, 0x2b, 0x9d, 0x24, 0x4f, 0xdc, 0x93, 0x67, 0xf8, 0x74, 0x4f, 0x5e, 0x10, 0x62, 0x09, 0xc2, + 0x6b, 0x4a, 0x41, 0x08, 0x43, 0xad, 0x78, 0x3a, 0x16, 0xc8, 0x33, 0xcc, 0x58, 0x20, 0xcf, 0xf0, + 0x62, 0x81, 0x3c, 0x83, 0x93, 0xfb, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, + 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, + 0xe9, 0xa6, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x17, 0xa7, 0x66, 0xea, + 0xc2, 0x5c, 0x00, 0xe6, 0x80, 0x9d, 0xa0, 0x5f, 0xa1, 0x0f, 0x0a, 0xc2, 0x92, 0xca, 0x82, 0xd4, + 0xe2, 0x24, 0x36, 0xb0, 0xbc, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xce, 0xe9, 0x08, 0x1a, 0x95, + 0x01, 0x00, 0x00, +} + +func (m *AddAssetMetadataProposal) 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 *AddAssetMetadataProposal) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *AddAssetMetadataProposal) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AssetList) > 0 { + for iNdEx := len(m.AssetList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AssetList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGov(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Description) > 0 { + i -= len(m.Description) + copy(dAtA[i:], m.Description) + i = encodeVarintGov(dAtA, i, uint64(len(m.Description))) + i-- + dAtA[i] = 0x12 + } + if len(m.Title) > 0 { + i -= len(m.Title) + copy(dAtA[i:], m.Title) + i = encodeVarintGov(dAtA, i, uint64(len(m.Title))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintGov(dAtA []byte, offset int, v uint64) int { + offset -= sovGov(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *AddAssetMetadataProposal) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Title) + if l > 0 { + n += 1 + l + sovGov(uint64(l)) + } + l = len(m.Description) + if l > 0 { + n += 1 + l + sovGov(uint64(l)) + } + if len(m.AssetList) > 0 { + for _, e := range m.AssetList { + l = e.Size() + n += 1 + l + sovGov(uint64(l)) + } + } + return n +} + +func sovGov(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozGov(x uint64) (n int) { + return sovGov(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *AddAssetMetadataProposal) 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 ErrIntOverflowGov + } + 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: AddAssetMetadataProposal: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: AddAssetMetadataProposal: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Title", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Title = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Description", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + 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 ErrInvalidLengthGov + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Description = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssetList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGov + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGov + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGov + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetList = append(m.AssetList, AssetMetadata{}) + if err := m.AssetList[len(m.AssetList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGov(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGov + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipGov(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, ErrIntOverflowGov + } + 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, ErrIntOverflowGov + } + 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, ErrIntOverflowGov + } + 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, ErrInvalidLengthGov + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupGov + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthGov + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthGov = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowGov = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupGov = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/keys.go b/x/dex/types/keys.go new file mode 100644 index 000000000..c56c1be90 --- /dev/null +++ b/x/dex/types/keys.go @@ -0,0 +1,190 @@ +package types + +import ( + "encoding/binary" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" +) + +const ( + // ModuleName defines the module name + ModuleName = "dex" + + // StoreKey defines the primary module store key + StoreKey = ModuleName + + // RouterKey is the message route for slashing + RouterKey = ModuleName + + // QuerierRoute defines the module's query routing key + QuerierRoute = ModuleName + + // MemStoreKey defines the in-memory store key + MemStoreKey = "mem_dex" +) + +func KeyPrefix(p string) []byte { + return []byte(p) +} + +func AddressKeyPrefix(contractAddr string) []byte { + addr, _ := sdk.AccAddressFromBech32(contractAddr) + return address.MustLengthPrefix(addr) +} + +func ContractKeyPrefix(p string, contractAddr string) []byte { + return append([]byte(p), AddressKeyPrefix(contractAddr)...) +} + +func DenomPrefix(denom string) []byte { + length := uint16(len(denom)) + bz := make([]byte, 2) + binary.BigEndian.PutUint16(bz, length) + return append(bz, []byte(denom)...) +} + +func PairPrefix(priceDenom string, assetDenom string) []byte { + return append(DenomPrefix(priceDenom), DenomPrefix(assetDenom)...) +} + +func OrderBookPrefix(long bool, contractAddr string, priceDenom string, assetDenom string) []byte { + return append( + OrderBookContractPrefix(long, contractAddr), + PairPrefix(priceDenom, assetDenom)..., + ) +} + +func OrderBookContractPrefix(long bool, contractAddr string) []byte { + var prefix []byte + if long { + prefix = KeyPrefix(LongBookKey) + } else { + prefix = KeyPrefix(ShortBookKey) + } + return append(prefix, AddressKeyPrefix(contractAddr)...) +} + +// `Price` constant + contract + price denom + asset denom +func PricePrefix(contractAddr string, priceDenom string, assetDenom string) []byte { + return append( + PriceContractPrefix(contractAddr), + PairPrefix(priceDenom, assetDenom)..., + ) +} + +func PriceContractPrefix(contractAddr string) []byte { + return append(KeyPrefix(PriceKey), AddressKeyPrefix(contractAddr)...) +} + +func RegisteredPairPrefix(contractAddr string) []byte { + return append(KeyPrefix(RegisteredPairKey), AddressKeyPrefix(contractAddr)...) +} + +func OrderPrefix(contractAddr string) []byte { + return append(KeyPrefix(OrderKey), AddressKeyPrefix(contractAddr)...) +} + +func AssetListPrefix(assetDenom string) []byte { + return append(KeyPrefix(AssetListKey), DenomPrefix(assetDenom)...) +} + +func NextOrderIDPrefix(contractAddr string) []byte { + return append(KeyPrefix(NextOrderIDKey), AddressKeyPrefix(contractAddr)...) +} + +func MatchResultPrefix(contractAddr string) []byte { + return append(KeyPrefix(MatchResultKey), AddressKeyPrefix(contractAddr)...) +} + +func GetSettlementOrderIDPrefix(orderID uint64, account string) []byte { + accountBytes := append([]byte(account), []byte("|")...) + orderIDBytes := make([]byte, 8) + binary.BigEndian.PutUint64(orderIDBytes, orderID) + return append(accountBytes, orderIDBytes...) +} + +func GetSettlementKey(orderID uint64, account string, settlementID uint64) []byte { + settlementIDBytes := make([]byte, 8) + binary.BigEndian.PutUint64(settlementIDBytes, settlementID) + return append(GetSettlementOrderIDPrefix(orderID, account), settlementIDBytes...) +} + +func MemOrderPrefixForPair(contractAddr string, priceDenom string, assetDenom string) []byte { + return append( + append(KeyPrefix(MemOrderKey), AddressKeyPrefix(contractAddr)...), + PairPrefix(priceDenom, assetDenom)..., + ) +} + +func MemCancelPrefixForPair(contractAddr string, priceDenom string, assetDenom string) []byte { + return append( + append(KeyPrefix(MemCancelKey), AddressKeyPrefix(contractAddr)...), + PairPrefix(priceDenom, assetDenom)..., + ) +} + +func MemOrderPrefix(contractAddr string) []byte { + return append(KeyPrefix(MemOrderKey), AddressKeyPrefix(contractAddr)...) +} + +func MemCancelPrefix(contractAddr string) []byte { + return append(KeyPrefix(MemCancelKey), AddressKeyPrefix(contractAddr)...) +} + +func MemDepositPrefix(contractAddr string) []byte { + return append(KeyPrefix(MemDepositKey), AddressKeyPrefix(contractAddr)...) +} + +func MemDepositSubprefix(creator, denom string) []byte { + return append([]byte(creator), DenomPrefix(denom)...) +} + +func MemContractsToProcessKey(contractAddr string) []byte { + return append(KeyPrefix(MemContractsToProcess), AddressKeyPrefix(contractAddr)...) +} + +func MemDownstreamContractsKey(contractAddr string) []byte { + return append(KeyPrefix(MemDownstreamContracts), AddressKeyPrefix(contractAddr)...) +} + +func ContractKey(contractAddr string) []byte { + return AddressKeyPrefix(contractAddr) +} + +func OrderCountPrefix(contractAddr string, priceDenom string, assetDenom string, long bool) []byte { + var prefix []byte + if long { + prefix = KeyPrefix(LongOrderCountKey) + } else { + prefix = KeyPrefix(ShortOrderCountKey) + } + return append(prefix, append(AddressKeyPrefix(contractAddr), PairPrefix(priceDenom, assetDenom)...)...) +} + +const ( + LongBookKey = "LongBook-value-" + + ShortBookKey = "ShortBook-value-" + + OrderKey = "order" + AccountActiveOrdersKey = "account-active-orders" + CancelKey = "cancel" + + TwapKey = "TWAP-" + PriceKey = "Price-" + SettlementEntryKey = "SettlementEntry-" + NextSettlementIDKey = "NextSettlementID-" + NextOrderIDKey = "noid" + RegisteredPairKey = "rp" + AssetListKey = "AssetList-" + MatchResultKey = "MatchResult-" + LongOrderCountKey = "loc-" + ShortOrderCountKey = "soc-" + + MemOrderKey = "MemOrder-" + MemDepositKey = "MemDeposit-" + MemCancelKey = "MemCancel-" + MemContractsToProcess = "MemContractsToProcess-" + MemDownstreamContracts = "MemDownstreamContracts-" +) diff --git a/x/dex/types/keys_test.go b/x/dex/types/keys_test.go new file mode 100644 index 000000000..a635435ba --- /dev/null +++ b/x/dex/types/keys_test.go @@ -0,0 +1,29 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/address" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestOrderPrefix(t *testing.T) { + testContract := "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m" + addr, _ := sdk.AccAddressFromBech32(testContract) + addr = address.MustLengthPrefix(addr) + expected := append([]byte(types.OrderKey), addr...) + require.Equal(t, expected, types.OrderPrefix(testContract)) +} + +func TestPricePrefix(t *testing.T) { + testContract := "sei14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sh9m79m" + testPriceDenom := "SEI" + testAssetDenom := "ATOM" + address := types.AddressKeyPrefix(testContract) + priceContractBytes := append([]byte(types.PriceKey), address...) + pairBytes := types.PairPrefix(testPriceDenom, testAssetDenom) + expectedKey := append(priceContractBytes, pairBytes...) + require.Equal(t, expectedKey, types.PricePrefix(testContract, testPriceDenom, testAssetDenom)) +} diff --git a/x/dex/types/long_book.pb.go b/x/dex/types/long_book.pb.go new file mode 100644 index 000000000..2f5167c99 --- /dev/null +++ b/x/dex/types/long_book.pb.go @@ -0,0 +1,380 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/long_book.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 LongBook struct { + Price github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=price,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price" yaml:"price"` + Entry *OrderEntry `protobuf:"bytes,2,opt,name=entry,proto3" json:"entry"` +} + +func (m *LongBook) Reset() { *m = LongBook{} } +func (m *LongBook) String() string { return proto.CompactTextString(m) } +func (*LongBook) ProtoMessage() {} +func (*LongBook) Descriptor() ([]byte, []int) { + return fileDescriptor_daa9d9e2359557c9, []int{0} +} +func (m *LongBook) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LongBook) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LongBook.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 *LongBook) XXX_Merge(src proto.Message) { + xxx_messageInfo_LongBook.Merge(m, src) +} +func (m *LongBook) XXX_Size() int { + return m.Size() +} +func (m *LongBook) XXX_DiscardUnknown() { + xxx_messageInfo_LongBook.DiscardUnknown(m) +} + +var xxx_messageInfo_LongBook proto.InternalMessageInfo + +func (m *LongBook) GetEntry() *OrderEntry { + if m != nil { + return m.Entry + } + return nil +} + +func init() { + proto.RegisterType((*LongBook)(nil), "seiprotocol.seichain.dex.LongBook") +} + +func init() { proto.RegisterFile("dex/long_book.proto", fileDescriptor_daa9d9e2359557c9) } + +var fileDescriptor_daa9d9e2359557c9 = []byte{ + // 278 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0x49, 0xad, 0xd0, + 0xcf, 0xc9, 0xcf, 0x4b, 0x8f, 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, 0x44, 0x41, 0xca, 0xf3, 0x8b, 0x52, 0x52, 0x8b, 0xe2, + 0x53, 0xf3, 0x4a, 0x8a, 0x2a, 0x21, 0x1a, 0xa4, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x4c, 0x7d, + 0x10, 0x0b, 0x22, 0xaa, 0xb4, 0x81, 0x91, 0x8b, 0xc3, 0x27, 0x3f, 0x2f, 0xdd, 0x29, 0x3f, 0x3f, + 0x5b, 0x28, 0x96, 0x8b, 0xb5, 0xa0, 0x28, 0x33, 0x39, 0x55, 0x82, 0x51, 0x81, 0x51, 0x83, 0xd3, + 0xc9, 0xfd, 0xc4, 0x3d, 0x79, 0x86, 0x5b, 0xf7, 0xe4, 0xd5, 0xd2, 0x33, 0x4b, 0x32, 0x4a, 0x93, + 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0x93, 0xf3, 0x8b, 0x73, 0xf3, 0x8b, 0xa1, 0x94, 0x6e, 0x71, 0x4a, + 0xb6, 0x7e, 0x49, 0x65, 0x41, 0x6a, 0xb1, 0x9e, 0x4b, 0x6a, 0xf2, 0xab, 0x7b, 0xf2, 0x10, 0xed, + 0x9f, 0xee, 0xc9, 0xf3, 0x54, 0x26, 0xe6, 0xe6, 0x58, 0x29, 0x81, 0xb9, 0x4a, 0x41, 0x10, 0x61, + 0x21, 0x57, 0x2e, 0x56, 0xb0, 0x83, 0x24, 0x98, 0x14, 0x18, 0x35, 0xb8, 0x8d, 0x54, 0xf4, 0x70, + 0x79, 0x41, 0xcf, 0x1f, 0xe4, 0x7a, 0x57, 0x90, 0x5a, 0x27, 0x4e, 0x90, 0xb1, 0x60, 0x6d, 0x41, + 0x10, 0xca, 0xc9, 0xfd, 0xc4, 0x23, 0x39, 0xc6, 0x0b, 0x8f, 0xe4, 0x18, 0x1f, 0x3c, 0x92, 0x63, + 0x9c, 0xf0, 0x58, 0x8e, 0xe1, 0xc2, 0x63, 0x39, 0x86, 0x1b, 0x8f, 0xe5, 0x18, 0xa2, 0x74, 0x91, + 0x1c, 0x5a, 0x9c, 0x9a, 0xa9, 0x0b, 0x33, 0x1c, 0xcc, 0x01, 0x9b, 0xae, 0x5f, 0xa1, 0x0f, 0x0a, + 0x1d, 0xb0, 0x9b, 0x93, 0xd8, 0xc0, 0xf2, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3e, 0xf1, + 0xb1, 0x25, 0x60, 0x01, 0x00, 0x00, +} + +func (m *LongBook) 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 *LongBook) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LongBook) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Entry != nil { + { + size, err := m.Entry.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintLongBook(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + { + size := m.Price.Size() + i -= size + if _, err := m.Price.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintLongBook(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintLongBook(dAtA []byte, offset int, v uint64) int { + offset -= sovLongBook(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *LongBook) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Price.Size() + n += 1 + l + sovLongBook(uint64(l)) + if m.Entry != nil { + l = m.Entry.Size() + n += 1 + l + sovLongBook(uint64(l)) + } + return n +} + +func sovLongBook(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozLongBook(x uint64) (n int) { + return sovLongBook(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *LongBook) 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 ErrIntOverflowLongBook + } + 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: LongBook: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LongBook: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLongBook + } + 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 ErrInvalidLengthLongBook + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthLongBook + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowLongBook + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthLongBook + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthLongBook + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Entry == nil { + m.Entry = &OrderEntry{} + } + if err := m.Entry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipLongBook(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthLongBook + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipLongBook(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, ErrIntOverflowLongBook + } + 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, ErrIntOverflowLongBook + } + 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, ErrIntOverflowLongBook + } + 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, ErrInvalidLengthLongBook + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupLongBook + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthLongBook + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthLongBook = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowLongBook = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupLongBook = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/match_result.go b/x/dex/types/match_result.go new file mode 100644 index 000000000..d77c3767d --- /dev/null +++ b/x/dex/types/match_result.go @@ -0,0 +1,28 @@ +package types + +import ( + "sort" +) + +func NewMatchResult( + orders []*Order, + cancellations []*Cancellation, + settlements []*SettlementEntry, +) *MatchResult { + // Note that we use string comparator since it is more robust. E.g. in the case that 2 orders match + // on the same orderId, we will then sort on the next field + sort.SliceStable(orders, func(i, j int) bool { + return orders[i].String() < orders[j].String() + }) + sort.SliceStable(cancellations, func(i, j int) bool { + return cancellations[i].String() < cancellations[j].String() + }) + sort.SliceStable(settlements, func(i, j int) bool { + return settlements[i].String() < settlements[j].String() + }) + return &MatchResult{ + Orders: orders, + Cancellations: cancellations, + Settlements: settlements, + } +} diff --git a/x/dex/types/match_result.pb.go b/x/dex/types/match_result.pb.go new file mode 100644 index 000000000..82966f289 --- /dev/null +++ b/x/dex/types/match_result.pb.go @@ -0,0 +1,548 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/match_result.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 MatchResult struct { + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contract_address"` + Orders []*Order `protobuf:"bytes,3,rep,name=orders,proto3" json:"orders"` + Settlements []*SettlementEntry `protobuf:"bytes,4,rep,name=settlements,proto3" json:"settlements"` + Cancellations []*Cancellation `protobuf:"bytes,5,rep,name=cancellations,proto3" json:"cancellations"` +} + +func (m *MatchResult) Reset() { *m = MatchResult{} } +func (m *MatchResult) String() string { return proto.CompactTextString(m) } +func (*MatchResult) ProtoMessage() {} +func (*MatchResult) Descriptor() ([]byte, []int) { + return fileDescriptor_9225b122096d4ce7, []int{0} +} +func (m *MatchResult) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MatchResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MatchResult.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 *MatchResult) XXX_Merge(src proto.Message) { + xxx_messageInfo_MatchResult.Merge(m, src) +} +func (m *MatchResult) XXX_Size() int { + return m.Size() +} +func (m *MatchResult) XXX_DiscardUnknown() { + xxx_messageInfo_MatchResult.DiscardUnknown(m) +} + +var xxx_messageInfo_MatchResult proto.InternalMessageInfo + +func (m *MatchResult) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *MatchResult) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *MatchResult) GetOrders() []*Order { + if m != nil { + return m.Orders + } + return nil +} + +func (m *MatchResult) GetSettlements() []*SettlementEntry { + if m != nil { + return m.Settlements + } + return nil +} + +func (m *MatchResult) GetCancellations() []*Cancellation { + if m != nil { + return m.Cancellations + } + return nil +} + +func init() { + proto.RegisterType((*MatchResult)(nil), "seiprotocol.seichain.dex.MatchResult") +} + +func init() { proto.RegisterFile("dex/match_result.proto", fileDescriptor_9225b122096d4ce7) } + +var fileDescriptor_9225b122096d4ce7 = []byte{ + // 345 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x91, 0xc1, 0x6a, 0xfa, 0x40, + 0x10, 0xc6, 0x8d, 0xfe, 0xff, 0x42, 0xd7, 0x16, 0xdb, 0x20, 0x25, 0x78, 0x48, 0xc4, 0x43, 0xb1, + 0x07, 0x13, 0x68, 0x2f, 0xbd, 0x36, 0x52, 0x7a, 0x2a, 0x85, 0xf4, 0x56, 0x0a, 0x12, 0x77, 0x87, + 0x64, 0x21, 0x66, 0x65, 0x77, 0x04, 0x7d, 0x8b, 0x3e, 0x56, 0x8f, 0x1e, 0x7b, 0x0a, 0x45, 0x6f, + 0xb9, 0xf4, 0x15, 0xca, 0x6e, 0xb4, 0xd5, 0x83, 0xa7, 0x99, 0xf9, 0xf2, 0xcd, 0xef, 0xcb, 0xb0, + 0xe4, 0x92, 0xc1, 0x22, 0x98, 0xc6, 0x48, 0xd3, 0xb1, 0x04, 0x35, 0xcf, 0xd0, 0x9f, 0x49, 0x81, + 0xc2, 0x76, 0x14, 0x70, 0xd3, 0x51, 0x91, 0xf9, 0x0a, 0x38, 0x4d, 0x63, 0x9e, 0xfb, 0x0c, 0x16, + 0xdd, 0xb6, 0xde, 0x10, 0x92, 0x81, 0xac, 0xac, 0xdd, 0x8e, 0x16, 0x14, 0x20, 0x66, 0x30, 0x85, + 0x1c, 0x77, 0x6a, 0x22, 0x12, 0x61, 0xda, 0x40, 0x77, 0x95, 0xda, 0xff, 0xae, 0x93, 0xd6, 0x93, + 0x4e, 0x8b, 0x4c, 0x98, 0xdd, 0x27, 0xcd, 0x14, 0x78, 0x92, 0xa2, 0x63, 0xf5, 0xac, 0x41, 0x23, + 0x24, 0x65, 0xe1, 0x6d, 0x95, 0x68, 0x5b, 0xed, 0x3b, 0x72, 0x4a, 0x45, 0x8e, 0x32, 0xa6, 0x78, + 0xcf, 0x98, 0x74, 0xea, 0x3d, 0x6b, 0x70, 0x12, 0x76, 0xca, 0xc2, 0x3b, 0xdf, 0xe9, 0xe3, 0x98, + 0x31, 0x09, 0x4a, 0x45, 0x07, 0x4e, 0x7b, 0x44, 0x9a, 0xe6, 0x47, 0x95, 0xd3, 0xe8, 0x35, 0x06, + 0xad, 0x1b, 0xcf, 0x3f, 0x76, 0x95, 0xff, 0xac, 0x7d, 0x55, 0x7c, 0xb5, 0x12, 0x6d, 0xab, 0xfd, + 0x46, 0x5a, 0x7f, 0xc7, 0x29, 0xe7, 0x9f, 0x21, 0x5d, 0x1f, 0x27, 0xbd, 0xfc, 0x9a, 0x1f, 0x72, + 0x94, 0xcb, 0xb0, 0x5d, 0x16, 0xde, 0x3e, 0x21, 0xda, 0x1f, 0xec, 0x31, 0x39, 0xa3, 0x71, 0x4e, + 0x21, 0xcb, 0x62, 0xe4, 0x22, 0x57, 0xce, 0x7f, 0xc3, 0xbf, 0x3a, 0xce, 0x1f, 0xed, 0xd9, 0xc3, + 0x8b, 0xb2, 0xf0, 0x0e, 0x01, 0xd1, 0xe1, 0x18, 0x3e, 0x7e, 0xac, 0x5d, 0x6b, 0xb5, 0x76, 0xad, + 0xaf, 0xb5, 0x6b, 0xbd, 0x6f, 0xdc, 0xda, 0x6a, 0xe3, 0xd6, 0x3e, 0x37, 0x6e, 0xed, 0x75, 0x98, + 0x70, 0x4c, 0xe7, 0x13, 0x9f, 0x8a, 0x69, 0xa0, 0x80, 0x0f, 0x77, 0x71, 0x66, 0x30, 0x79, 0xc1, + 0x22, 0xd0, 0x6f, 0x8b, 0xcb, 0x19, 0xa8, 0x49, 0xd3, 0x7c, 0xbf, 0xfd, 0x09, 0x00, 0x00, 0xff, + 0xff, 0x40, 0xd8, 0xfe, 0x79, 0x32, 0x02, 0x00, 0x00, +} + +func (m *MatchResult) 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 *MatchResult) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MatchResult) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Cancellations) > 0 { + for iNdEx := len(m.Cancellations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Cancellations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMatchResult(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if len(m.Settlements) > 0 { + for iNdEx := len(m.Settlements) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Settlements[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMatchResult(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.Orders) > 0 { + for iNdEx := len(m.Orders) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Orders[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMatchResult(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintMatchResult(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if m.Height != 0 { + i = encodeVarintMatchResult(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintMatchResult(dAtA []byte, offset int, v uint64) int { + offset -= sovMatchResult(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MatchResult) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Height != 0 { + n += 1 + sovMatchResult(uint64(m.Height)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovMatchResult(uint64(l)) + } + if len(m.Orders) > 0 { + for _, e := range m.Orders { + l = e.Size() + n += 1 + l + sovMatchResult(uint64(l)) + } + } + if len(m.Settlements) > 0 { + for _, e := range m.Settlements { + l = e.Size() + n += 1 + l + sovMatchResult(uint64(l)) + } + } + if len(m.Cancellations) > 0 { + for _, e := range m.Cancellations { + l = e.Size() + n += 1 + l + sovMatchResult(uint64(l)) + } + } + return n +} + +func sovMatchResult(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozMatchResult(x uint64) (n int) { + return sovMatchResult(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MatchResult) 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 ErrIntOverflowMatchResult + } + 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: MatchResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MatchResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMatchResult + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMatchResult + } + 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 ErrInvalidLengthMatchResult + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMatchResult + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Orders", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMatchResult + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMatchResult + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMatchResult + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Orders = append(m.Orders, &Order{}) + if err := m.Orders[len(m.Orders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Settlements", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMatchResult + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMatchResult + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMatchResult + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Settlements = append(m.Settlements, &SettlementEntry{}) + if err := m.Settlements[len(m.Settlements)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Cancellations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMatchResult + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMatchResult + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMatchResult + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Cancellations = append(m.Cancellations, &Cancellation{}) + if err := m.Cancellations[len(m.Cancellations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMatchResult(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMatchResult + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipMatchResult(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, ErrIntOverflowMatchResult + } + 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, ErrIntOverflowMatchResult + } + 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, ErrIntOverflowMatchResult + } + 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, ErrInvalidLengthMatchResult + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupMatchResult + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthMatchResult + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthMatchResult = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowMatchResult = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupMatchResult = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/match_result_test.go b/x/dex/types/match_result_test.go new file mode 100644 index 000000000..79da33ec3 --- /dev/null +++ b/x/dex/types/match_result_test.go @@ -0,0 +1,54 @@ +package types_test + +import ( + "testing" + + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestMatchResultSorted(t *testing.T) { + // Test stable sorting + order1 := &types.Order{ + Id: 1, + } + order2 := &types.Order{ + Id: 1, + } + order3 := &types.Order{ + Id: 2, + } + + // Test sort on different field + cancellation1 := &types.Cancellation{ + Id: 1, + AssetDenom: "a", + } + cancellation2 := &types.Cancellation{ + Id: 1, + AssetDenom: "b", + } + + // Test sort on string + settlement1 := &types.SettlementEntry{ + Account: "a", + } + settlement2 := &types.SettlementEntry{ + Account: "b", + } + + orders := []*types.Order{order3, order1, order2} + cancellations := []*types.Cancellation{cancellation2, cancellation1} + settlements := []*types.SettlementEntry{settlement2, settlement1} + + matchResult := types.NewMatchResult(orders, cancellations, settlements) + expectedOrders := []*types.Order{order1, order2, order3} + expectedCancellations := []*types.Cancellation{cancellation1, cancellation2} + expectedSettlements := []*types.SettlementEntry{settlement1, settlement2} + require.Equal(t, expectedOrders, matchResult.Orders) + // Check actual elements, since slice match above don't seem to capture if the orders point to different objects + require.True(t, order1 == matchResult.Orders[0]) + require.True(t, order2 == matchResult.Orders[1]) + require.Equal(t, expectedCancellations, matchResult.Cancellations) + require.Equal(t, expectedSettlements, matchResult.Settlements) +} diff --git a/x/dex/types/message_cancel_orders.go b/x/dex/types/message_cancel_orders.go new file mode 100644 index 000000000..e211e6b2c --- /dev/null +++ b/x/dex/types/message_cancel_orders.go @@ -0,0 +1,72 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgCancelOrders = "cancel_orders" + +var _ sdk.Msg = &MsgCancelOrders{} + +func NewMsgCancelOrders( + creator string, + cancellations []*Cancellation, + contractAddr string, +) *MsgCancelOrders { + return &MsgCancelOrders{ + Creator: creator, + Cancellations: cancellations, + ContractAddr: contractAddr, + } +} + +func (msg *MsgCancelOrders) Route() string { + return RouterKey +} + +func (msg *MsgCancelOrders) Type() string { + return TypeMsgCancelOrders +} + +func (msg *MsgCancelOrders) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgCancelOrders) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgCancelOrders) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + _, err = sdk.AccAddressFromBech32(msg.ContractAddr) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) + } + + for _, cancellation := range msg.Cancellations { + if cancellation.Price.IsNil() { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid cancellation price (%s)", err) + } + if cancellation.Price.IsNegative() { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid cancellation price (cannot be negative) (%s)", err) + } + if len(cancellation.AssetDenom) == 0 || sdk.ValidateDenom(cancellation.AssetDenom) != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid cancellation, asset denom is empty or invalid (%s)", err) + } + if len(cancellation.PriceDenom) == 0 || sdk.ValidateDenom(cancellation.PriceDenom) != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid cancellation, price denom is empty or invalid (%s)", err) + } + } + + return nil +} diff --git a/x/dex/types/message_cancel_orders_test.go b/x/dex/types/message_cancel_orders_test.go new file mode 100644 index 000000000..1dff4ec30 --- /dev/null +++ b/x/dex/types/message_cancel_orders_test.go @@ -0,0 +1,42 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestValidateMsgCancelOrder(t *testing.T) { + msg := &types.MsgCancelOrders{ + Creator: "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx", + ContractAddr: "sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc", + Cancellations: []*types.Cancellation{{ + Price: sdk.OneDec().Neg(), + AssetDenom: "denom1", + PriceDenom: "denom2", + }}, + } + require.Error(t, msg.ValidateBasic()) + msg = &types.MsgCancelOrders{ + Creator: "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx", + ContractAddr: "sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc", + Cancellations: []*types.Cancellation{{ + Price: sdk.OneDec(), + AssetDenom: "invalid denom", + PriceDenom: "denom2", + }}, + } + require.Error(t, msg.ValidateBasic()) + msg = &types.MsgCancelOrders{ + Creator: "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx", + ContractAddr: "sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc", + Cancellations: []*types.Cancellation{{ + Price: sdk.OneDec(), + AssetDenom: "denom1", + PriceDenom: "invalid denom", + }}, + } + require.Error(t, msg.ValidateBasic()) +} diff --git a/x/dex/types/message_contract_deposit_rent.go b/x/dex/types/message_contract_deposit_rent.go new file mode 100644 index 000000000..7b94c93bf --- /dev/null +++ b/x/dex/types/message_contract_deposit_rent.go @@ -0,0 +1,56 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgContractDepositRent = "contract_deposit_rent" + +var _ sdk.Msg = &MsgContractDepositRent{} + +func NewMsgContractDepositRent( + contractAddr string, + amount uint64, + sender string, +) *MsgContractDepositRent { + return &MsgContractDepositRent{ + Sender: sender, + ContractAddr: contractAddr, + Amount: amount, + } +} + +func (msg *MsgContractDepositRent) Route() string { + return RouterKey +} + +func (msg *MsgContractDepositRent) Type() string { + return TypeMsgContractDepositRent +} + +func (msg *MsgContractDepositRent) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgContractDepositRent) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgContractDepositRent) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Sender) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + _, err = sdk.AccAddressFromBech32(msg.ContractAddr) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) + } + return nil +} diff --git a/x/dex/types/message_place_orders.go b/x/dex/types/message_place_orders.go new file mode 100644 index 000000000..839dad45a --- /dev/null +++ b/x/dex/types/message_place_orders.go @@ -0,0 +1,85 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgPlaceOrders = "place_orders" + +var _ sdk.Msg = &MsgPlaceOrders{} + +func NewMsgPlaceOrders( + creator string, + orders []*Order, + contractAddr string, + fund sdk.Coins, +) *MsgPlaceOrders { + return &MsgPlaceOrders{ + Creator: creator, + Orders: orders, + ContractAddr: contractAddr, + Funds: fund, + } +} + +func (msg *MsgPlaceOrders) Route() string { + return RouterKey +} + +func (msg *MsgPlaceOrders) Type() string { + return TypeMsgPlaceOrders +} + +func (msg *MsgPlaceOrders) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgPlaceOrders) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +// perform statelss check on basic property of msg like sig verification +func (msg *MsgPlaceOrders) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + _, err = sdk.AccAddressFromBech32(msg.ContractAddr) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) + } + + if len(msg.Orders) == 0 { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "at least one order needs to be placed (%s)", err) + } + + for _, order := range msg.Orders { + if order.Quantity.IsNil() || order.Quantity.IsNegative() { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid order quantity (%s)", err) + } + if order.Price.IsNil() || order.Price.IsNegative() { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid order price (%s)", err) + } + if len(order.AssetDenom) == 0 || sdk.ValidateDenom(order.AssetDenom) != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid order, asset denom is empty or invalid (%s)", err) + } + if len(order.PriceDenom) == 0 || sdk.ValidateDenom(order.PriceDenom) != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid order, price denom is empty or invalid (%s)", err) + } + if order.OrderType == OrderType_FOKMARKETBYVALUE || order.OrderType == OrderType_FOKMARKET { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "FOK orders are temporarily disabled") + } + if order.OrderType == OrderType_STOPLIMIT || order.OrderType == OrderType_STOPLOSS { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "stop loss/limit order (%s) are not supported yet", err) + } + } + + return nil +} diff --git a/x/dex/types/message_place_orders_test.go b/x/dex/types/message_place_orders_test.go new file mode 100644 index 000000000..470de9cd1 --- /dev/null +++ b/x/dex/types/message_place_orders_test.go @@ -0,0 +1,102 @@ +package types_test + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "testing" + + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestValidateMsgPlaceOrder(t *testing.T) { + TEST_CONTRACT := "sei1ghd753shjuwexxywmgs4xz7x2q732vcnkm6h2pyv9s6ah3hylvrqladqwc" + msg := &types.MsgPlaceOrders{ + Creator: "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx", + ContractAddr: TEST_CONTRACT, + Orders: []*types.Order{ + { + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + Quantity: sdk.OneDec(), + Price: sdk.OneDec(), + AssetDenom: "denom1", + PriceDenom: "denom2", + }, + }, + } + require.NoError(t, msg.ValidateBasic()) + + // Empty orders + msg = &types.MsgPlaceOrders{ + Creator: "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx", + ContractAddr: TEST_CONTRACT, + Orders: []*types.Order{}, + } + require.Error(t, msg.ValidateBasic()) + + // Test various invalid orders field + msg = &types.MsgPlaceOrders{ + Creator: "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx", + ContractAddr: TEST_CONTRACT, + Orders: []*types.Order{ + { + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + Quantity: sdk.OneDec().Neg(), + Price: sdk.OneDec(), + AssetDenom: "denom1", + PriceDenom: "denom2", + }, + }, + } + require.Error(t, msg.ValidateBasic()) + msg = &types.MsgPlaceOrders{ + Creator: "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx", + ContractAddr: TEST_CONTRACT, + Orders: []*types.Order{ + { + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + Quantity: sdk.OneDec(), + AssetDenom: "denom1", + PriceDenom: "denom2", + }, + }, + } + require.Error(t, msg.ValidateBasic()) + msg = &types.MsgPlaceOrders{ + Creator: "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx", + ContractAddr: TEST_CONTRACT, + Orders: []*types.Order{ + { + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + Quantity: sdk.OneDec(), + Price: sdk.OneDec(), + AssetDenom: "invalid denom", + PriceDenom: "denom2", + }, + }, + } + require.Error(t, msg.ValidateBasic()) + msg = &types.MsgPlaceOrders{ + Creator: "sei1yezq49upxhunjjhudql2fnj5dgvcwjj87pn2wx", + ContractAddr: TEST_CONTRACT, + Orders: []*types.Order{ + { + Id: 1, + Account: "test", + ContractAddr: TEST_CONTRACT, + Quantity: sdk.OneDec().Neg(), + Price: sdk.OneDec(), + AssetDenom: "denom1", + PriceDenom: "invalid denom", + }, + }, + } + require.Error(t, msg.ValidateBasic()) +} diff --git a/x/dex/types/message_register_contract.go b/x/dex/types/message_register_contract.go new file mode 100644 index 000000000..2ac7240ea --- /dev/null +++ b/x/dex/types/message_register_contract.go @@ -0,0 +1,75 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgRegisterContract = "register_contract" + +var _ sdk.Msg = &MsgRegisterContract{} + +func NewMsgRegisterContract( + creator string, + codeID uint64, + contractAddr string, + needOrderMatching bool, + dependencies []*ContractDependencyInfo, + deposit uint64, +) *MsgRegisterContract { + return &MsgRegisterContract{ + Creator: creator, + Contract: &ContractInfoV2{ + CodeId: codeID, + ContractAddr: contractAddr, + NeedOrderMatching: needOrderMatching, + Dependencies: dependencies, + Creator: creator, + RentBalance: deposit, + }, + } +} + +func (msg *MsgRegisterContract) Route() string { + return RouterKey +} + +func (msg *MsgRegisterContract) Type() string { + return TypeMsgRegisterContract +} + +func (msg *MsgRegisterContract) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgRegisterContract) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgRegisterContract) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + _, err = sdk.AccAddressFromBech32(msg.Contract.ContractAddr) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) + } + + for _, dependency := range msg.Contract.Dependencies { + contractAddress := dependency.Dependency + + _, err = sdk.AccAddressFromBech32(contractAddress) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid dependency contract address (%s)", err) + } + } + + return nil +} diff --git a/x/dex/types/message_register_pairs.go b/x/dex/types/message_register_pairs.go new file mode 100644 index 000000000..47fb42af1 --- /dev/null +++ b/x/dex/types/message_register_pairs.go @@ -0,0 +1,83 @@ +package types + +import ( + "errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgRegisterPairs = "register_pairs" + +var _ sdk.Msg = &MsgRegisterPairs{} + +func NewMsgRegisterPairs( + creator string, + contractPairs []BatchContractPair, +) *MsgRegisterPairs { + return &MsgRegisterPairs{ + Creator: creator, + Batchcontractpair: contractPairs, + } +} + +func (msg *MsgRegisterPairs) Route() string { + return RouterKey +} + +func (msg *MsgRegisterPairs) Type() string { + return TypeMsgRegisterPairs +} + +func (msg *MsgRegisterPairs) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgRegisterPairs) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgRegisterPairs) ValidateBasic() error { + if msg.Creator == "" { + return errors.New("creator address is empty") + } + + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + if len(msg.Batchcontractpair) == 0 { + return errors.New("no data provided in register pairs transaction") + } + + for _, batchContractPair := range msg.Batchcontractpair { + contractAddress := batchContractPair.ContractAddr + + if contractAddress == "" { + return errors.New("contract address is empty") + } + + _, err = sdk.AccAddressFromBech32(contractAddress) + if err != nil { + return errors.New("contract address format is not bech32") + } + + if len(batchContractPair.Pairs) == 0 { + return errors.New("no pairs provided in register pairs transaction") + } + + for _, pair := range batchContractPair.Pairs { + if pair == nil { + return errors.New("empty pair info") + } + } + } + + return nil +} diff --git a/x/dex/types/message_unregister_contract.go b/x/dex/types/message_unregister_contract.go new file mode 100644 index 000000000..667805c66 --- /dev/null +++ b/x/dex/types/message_unregister_contract.go @@ -0,0 +1,55 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgUnregisterContract = "unregister_contract" + +var _ sdk.Msg = &MsgUnregisterContract{} + +func NewMsgUnregisterContract( + creator string, + contractAddr string, +) *MsgUnregisterContract { + return &MsgUnregisterContract{ + Creator: creator, + ContractAddr: contractAddr, + } +} + +func (msg *MsgUnregisterContract) Route() string { + return RouterKey +} + +func (msg *MsgUnregisterContract) Type() string { + return TypeMsgUnregisterContract +} + +func (msg *MsgUnregisterContract) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgUnregisterContract) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgUnregisterContract) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + _, err = sdk.AccAddressFromBech32(msg.ContractAddr) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) + } + + return nil +} diff --git a/x/dex/types/message_unsuspend_contract.go b/x/dex/types/message_unsuspend_contract.go new file mode 100644 index 000000000..75581625e --- /dev/null +++ b/x/dex/types/message_unsuspend_contract.go @@ -0,0 +1,55 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgUnsuspendContract = "unsuspend_contract" + +var _ sdk.Msg = &MsgUnsuspendContract{} + +func NewMsgUnsuspendContract( + creator string, + contractAddr string, +) *MsgUnsuspendContract { + return &MsgUnsuspendContract{ + Creator: creator, + ContractAddr: contractAddr, + } +} + +func (msg *MsgUnsuspendContract) Route() string { + return RouterKey +} + +func (msg *MsgUnsuspendContract) Type() string { + return TypeMsgUnsuspendContract +} + +func (msg *MsgUnsuspendContract) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgUnsuspendContract) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgUnsuspendContract) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + _, err = sdk.AccAddressFromBech32(msg.ContractAddr) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid contract address (%s)", err) + } + + return nil +} diff --git a/x/dex/types/message_update_price_tick_size.go b/x/dex/types/message_update_price_tick_size.go new file mode 100644 index 000000000..1594bcffb --- /dev/null +++ b/x/dex/types/message_update_price_tick_size.go @@ -0,0 +1,69 @@ +package types + +import ( + "errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgUpdatePriceTickSize = "update_price_tick_size" + +var _ sdk.Msg = &MsgUpdatePriceTickSize{} + +func NewMsgUpdatePriceTickSize( + creator string, + tickSizeList []TickSize, +) *MsgUpdatePriceTickSize { + return &MsgUpdatePriceTickSize{ + Creator: creator, + TickSizeList: tickSizeList, + } +} + +func (msg *MsgUpdatePriceTickSize) Route() string { + return RouterKey +} + +func (msg *MsgUpdatePriceTickSize) Type() string { + return TypeMsgUpdatePriceTickSize +} + +func (msg *MsgUpdatePriceTickSize) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgUpdatePriceTickSize) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgUpdatePriceTickSize) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + if len(msg.TickSizeList) == 0 { + return errors.New("no data provided in update price tick size transaction") + } + + for _, tickSize := range msg.TickSizeList { + contractAddress := tickSize.ContractAddr + + _, err = sdk.AccAddressFromBech32(contractAddress) + if err != nil { + return errors.New("contract address format is not bech32") + } + + if tickSize.Pair == nil { + return errors.New("empty pair info") + } + } + + return nil +} diff --git a/x/dex/types/message_update_quantity_tick_size.go b/x/dex/types/message_update_quantity_tick_size.go new file mode 100644 index 000000000..7beafec5d --- /dev/null +++ b/x/dex/types/message_update_quantity_tick_size.go @@ -0,0 +1,69 @@ +package types + +import ( + "errors" + + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" +) + +const TypeMsgUpdateQuantityTickSize = "update_quantity_tick_size" + +var _ sdk.Msg = &MsgUpdateQuantityTickSize{} + +func NewMsgUpdateQuantityTickSize( + creator string, + tickSizeList []TickSize, +) *MsgUpdateQuantityTickSize { + return &MsgUpdateQuantityTickSize{ + Creator: creator, + TickSizeList: tickSizeList, + } +} + +func (msg *MsgUpdateQuantityTickSize) Route() string { + return RouterKey +} + +func (msg *MsgUpdateQuantityTickSize) Type() string { + return TypeMsgUpdateQuantityTickSize +} + +func (msg *MsgUpdateQuantityTickSize) GetSigners() []sdk.AccAddress { + creator, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + panic(err) + } + return []sdk.AccAddress{creator} +} + +func (msg *MsgUpdateQuantityTickSize) GetSignBytes() []byte { + bz := ModuleCdc.MustMarshalJSON(msg) + return sdk.MustSortJSON(bz) +} + +func (msg *MsgUpdateQuantityTickSize) ValidateBasic() error { + _, err := sdk.AccAddressFromBech32(msg.Creator) + if err != nil { + return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid creator address (%s)", err) + } + + if len(msg.TickSizeList) == 0 { + return errors.New("no data provided in update quantity tick size transaction") + } + + for _, tickSize := range msg.TickSizeList { + contractAddress := tickSize.ContractAddr + + _, err = sdk.AccAddressFromBech32(contractAddress) + if err != nil { + return errors.New("contract address format is not bech32") + } + + if tickSize.Pair == nil { + return errors.New("empty pair info") + } + } + + return nil +} diff --git a/x/dex/types/order.pb.go b/x/dex/types/order.pb.go new file mode 100644 index 000000000..69c89707d --- /dev/null +++ b/x/dex/types/order.pb.go @@ -0,0 +1,1680 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/order.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 Order struct { + Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id"` + Status OrderStatus `protobuf:"varint,2,opt,name=status,proto3,enum=seiprotocol.seichain.dex.OrderStatus" json:"status"` + Account string `protobuf:"bytes,3,opt,name=account,proto3" json:"account"` + ContractAddr string `protobuf:"bytes,4,opt,name=contractAddr,proto3" json:"contract_address"` + Price github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=price,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price" yaml:"price"` + Quantity github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,6,opt,name=quantity,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"quantity" yaml:"quantity"` + PriceDenom string `protobuf:"bytes,7,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,8,opt,name=assetDenom,proto3" json:"asset_denom"` + OrderType OrderType `protobuf:"varint,9,opt,name=orderType,proto3,enum=seiprotocol.seichain.dex.OrderType" json:"order_type"` + PositionDirection PositionDirection `protobuf:"varint,10,opt,name=positionDirection,proto3,enum=seiprotocol.seichain.dex.PositionDirection" json:"position_direction"` + 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{} } +func (m *Order) String() string { return proto.CompactTextString(m) } +func (*Order) ProtoMessage() {} +func (*Order) Descriptor() ([]byte, []int) { + return fileDescriptor_c2d5fab85368797d, []int{0} +} +func (m *Order) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Order) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Order.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 *Order) XXX_Merge(src proto.Message) { + xxx_messageInfo_Order.Merge(m, src) +} +func (m *Order) XXX_Size() int { + return m.Size() +} +func (m *Order) XXX_DiscardUnknown() { + xxx_messageInfo_Order.DiscardUnknown(m) +} + +var xxx_messageInfo_Order proto.InternalMessageInfo + +func (m *Order) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *Order) GetStatus() OrderStatus { + if m != nil { + return m.Status + } + return OrderStatus_PLACED +} + +func (m *Order) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +func (m *Order) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *Order) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *Order) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *Order) GetOrderType() OrderType { + if m != nil { + return m.OrderType + } + return OrderType_LIMIT +} + +func (m *Order) GetPositionDirection() PositionDirection { + if m != nil { + return m.PositionDirection + } + return PositionDirection_LONG +} + +func (m *Order) GetData() string { + if m != nil { + return m.Data + } + return "" +} + +func (m *Order) GetStatusDescription() string { + if m != nil { + return m.StatusDescription + } + 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"` + Creator string `protobuf:"bytes,3,opt,name=creator,proto3" json:"creator"` + ContractAddr string `protobuf:"bytes,4,opt,name=contractAddr,proto3" json:"contract_address"` + PriceDenom string `protobuf:"bytes,5,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,6,opt,name=assetDenom,proto3" json:"asset_denom"` + PositionDirection PositionDirection `protobuf:"varint,7,opt,name=positionDirection,proto3,enum=seiprotocol.seichain.dex.PositionDirection" json:"position_direction"` + Price github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,8,opt,name=price,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price" yaml:"price"` +} + +func (m *Cancellation) Reset() { *m = Cancellation{} } +func (m *Cancellation) String() string { return proto.CompactTextString(m) } +func (*Cancellation) ProtoMessage() {} +func (*Cancellation) Descriptor() ([]byte, []int) { + return fileDescriptor_c2d5fab85368797d, []int{1} +} +func (m *Cancellation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Cancellation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Cancellation.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 *Cancellation) XXX_Merge(src proto.Message) { + xxx_messageInfo_Cancellation.Merge(m, src) +} +func (m *Cancellation) XXX_Size() int { + return m.Size() +} +func (m *Cancellation) XXX_DiscardUnknown() { + xxx_messageInfo_Cancellation.DiscardUnknown(m) +} + +var xxx_messageInfo_Cancellation proto.InternalMessageInfo + +func (m *Cancellation) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +func (m *Cancellation) GetInitiator() CancellationInitiator { + if m != nil { + return m.Initiator + } + return CancellationInitiator_USER +} + +func (m *Cancellation) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *Cancellation) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *Cancellation) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *Cancellation) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *Cancellation) GetPositionDirection() PositionDirection { + if m != nil { + return m.PositionDirection + } + return PositionDirection_LONG +} + +type ActiveOrders struct { + Ids []uint64 `protobuf:"varint,1,rep,packed,name=ids,proto3" json:"ids"` +} + +func (m *ActiveOrders) Reset() { *m = ActiveOrders{} } +func (m *ActiveOrders) String() string { return proto.CompactTextString(m) } +func (*ActiveOrders) ProtoMessage() {} +func (*ActiveOrders) Descriptor() ([]byte, []int) { + return fileDescriptor_c2d5fab85368797d, []int{2} +} +func (m *ActiveOrders) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ActiveOrders) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ActiveOrders.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 *ActiveOrders) XXX_Merge(src proto.Message) { + xxx_messageInfo_ActiveOrders.Merge(m, src) +} +func (m *ActiveOrders) XXX_Size() int { + return m.Size() +} +func (m *ActiveOrders) XXX_DiscardUnknown() { + xxx_messageInfo_ActiveOrders.DiscardUnknown(m) +} + +var xxx_messageInfo_ActiveOrders proto.InternalMessageInfo + +func (m *ActiveOrders) GetIds() []uint64 { + if m != nil { + return m.Ids + } + return nil +} + +func init() { + proto.RegisterType((*Order)(nil), "seiprotocol.seichain.dex.Order") + proto.RegisterType((*Cancellation)(nil), "seiprotocol.seichain.dex.Cancellation") + proto.RegisterType((*ActiveOrders)(nil), "seiprotocol.seichain.dex.ActiveOrders") +} + +func init() { proto.RegisterFile("dex/order.proto", fileDescriptor_c2d5fab85368797d) } + +var fileDescriptor_c2d5fab85368797d = []byte{ + // 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) { + 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 *Order) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Order) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = 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 + if _, err := m.Nominal.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOrder(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x6a + if len(m.StatusDescription) > 0 { + i -= len(m.StatusDescription) + copy(dAtA[i:], m.StatusDescription) + i = encodeVarintOrder(dAtA, i, uint64(len(m.StatusDescription))) + i-- + dAtA[i] = 0x62 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintOrder(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x5a + } + if m.PositionDirection != 0 { + i = encodeVarintOrder(dAtA, i, uint64(m.PositionDirection)) + i-- + dAtA[i] = 0x50 + } + if m.OrderType != 0 { + i = encodeVarintOrder(dAtA, i, uint64(m.OrderType)) + i-- + dAtA[i] = 0x48 + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintOrder(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x42 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintOrder(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x3a + } + { + size := m.Quantity.Size() + i -= size + if _, err := m.Quantity.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOrder(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + { + size := m.Price.Size() + i -= size + if _, err := m.Price.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOrder(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintOrder(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x22 + } + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintOrder(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0x1a + } + if m.Status != 0 { + i = encodeVarintOrder(dAtA, i, uint64(m.Status)) + i-- + dAtA[i] = 0x10 + } + if m.Id != 0 { + i = encodeVarintOrder(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Cancellation) 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 *Cancellation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Cancellation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size := m.Price.Size() + i -= size + if _, err := m.Price.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOrder(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + if m.PositionDirection != 0 { + i = encodeVarintOrder(dAtA, i, uint64(m.PositionDirection)) + i-- + dAtA[i] = 0x38 + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintOrder(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x32 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintOrder(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x2a + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintOrder(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x22 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintOrder(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0x1a + } + if m.Initiator != 0 { + i = encodeVarintOrder(dAtA, i, uint64(m.Initiator)) + i-- + dAtA[i] = 0x10 + } + if m.Id != 0 { + i = encodeVarintOrder(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ActiveOrders) 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 *ActiveOrders) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ActiveOrders) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Ids) > 0 { + dAtA2 := make([]byte, len(m.Ids)*10) + var j1 int + for _, num := range m.Ids { + for num >= 1<<7 { + dAtA2[j1] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j1++ + } + dAtA2[j1] = uint8(num) + j1++ + } + i -= j1 + copy(dAtA[i:], dAtA2[:j1]) + i = encodeVarintOrder(dAtA, i, uint64(j1)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintOrder(dAtA []byte, offset int, v uint64) int { + offset -= sovOrder(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Order) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovOrder(uint64(m.Id)) + } + if m.Status != 0 { + n += 1 + sovOrder(uint64(m.Status)) + } + l = len(m.Account) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + l = m.Price.Size() + n += 1 + l + sovOrder(uint64(l)) + l = m.Quantity.Size() + n += 1 + l + sovOrder(uint64(l)) + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + if m.OrderType != 0 { + n += 1 + sovOrder(uint64(m.OrderType)) + } + if m.PositionDirection != 0 { + n += 1 + sovOrder(uint64(m.PositionDirection)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + l = len(m.StatusDescription) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + 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 +} + +func (m *Cancellation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + sovOrder(uint64(m.Id)) + } + if m.Initiator != 0 { + n += 1 + sovOrder(uint64(m.Initiator)) + } + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovOrder(uint64(l)) + } + if m.PositionDirection != 0 { + n += 1 + sovOrder(uint64(m.PositionDirection)) + } + l = m.Price.Size() + n += 1 + l + sovOrder(uint64(l)) + return n +} + +func (m *ActiveOrders) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Ids) > 0 { + l = 0 + for _, e := range m.Ids { + l += sovOrder(uint64(e)) + } + n += 1 + sovOrder(uint64(l)) + l + } + return n +} + +func sovOrder(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozOrder(x uint64) (n int) { + return sovOrder(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Order) 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 ErrIntOverflowOrder + } + 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: Order: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Order: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Status", wireType) + } + m.Status = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Status |= OrderStatus(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", 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 + } + m.Account = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", 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 + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", 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.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Quantity", 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.Quantity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + 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 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 + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + 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 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 + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OrderType", wireType) + } + m.OrderType = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OrderType |= OrderType(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PositionDirection", wireType) + } + m.PositionDirection = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PositionDirection |= PositionDirection(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", 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 + } + m.Data = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field StatusDescription", 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 + } + m.StatusDescription = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Nominal", 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.Nominal.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + 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:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOrder + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Cancellation) 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 ErrIntOverflowOrder + } + 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: Cancellation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Cancellation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Initiator", wireType) + } + m.Initiator = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Initiator |= CancellationInitiator(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", 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 + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", 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 + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + 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 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 + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + 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 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 + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PositionDirection", wireType) + } + m.PositionDirection = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PositionDirection |= PositionDirection(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", 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.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipOrder(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOrder + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ActiveOrders) 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 ErrIntOverflowOrder + } + 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: ActiveOrders: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ActiveOrders: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Ids = append(m.Ids, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthOrder + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthOrder + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.Ids) == 0 { + m.Ids = make([]uint64, 0, elementCount) + } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrder + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Ids = append(m.Ids, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field Ids", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipOrder(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOrder + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipOrder(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, ErrIntOverflowOrder + } + 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, ErrIntOverflowOrder + } + 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, ErrIntOverflowOrder + } + 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, ErrInvalidLengthOrder + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupOrder + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthOrder + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthOrder = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowOrder = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupOrder = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/order_cancellation.go b/x/dex/types/order_cancellation.go new file mode 100644 index 000000000..7067b98f6 --- /dev/null +++ b/x/dex/types/order_cancellation.go @@ -0,0 +1,9 @@ +package types + +type SudoOrderCancellationMsg struct { + OrderCancellations OrderCancellationMsgDetails `json:"bulk_order_cancellations"` +} + +type OrderCancellationMsgDetails struct { + IdsToCancel []uint64 `json:"ids"` +} diff --git a/x/dex/types/order_entry.pb.go b/x/dex/types/order_entry.pb.go new file mode 100644 index 000000000..dafbc63fc --- /dev/null +++ b/x/dex/types/order_entry.pb.go @@ -0,0 +1,790 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/order_entry.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 OrderEntry struct { + Price github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=price,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price" yaml:"price"` + Quantity github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=quantity,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"quantity" yaml:"quantity"` + Allocations []*Allocation `protobuf:"bytes,3,rep,name=allocations,proto3" json:"allocations"` + PriceDenom string `protobuf:"bytes,4,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,5,opt,name=assetDenom,proto3" json:"asset_denom"` +} + +func (m *OrderEntry) Reset() { *m = OrderEntry{} } +func (m *OrderEntry) String() string { return proto.CompactTextString(m) } +func (*OrderEntry) ProtoMessage() {} +func (*OrderEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_25878922effe12c2, []int{0} +} +func (m *OrderEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OrderEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OrderEntry.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 *OrderEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_OrderEntry.Merge(m, src) +} +func (m *OrderEntry) XXX_Size() int { + return m.Size() +} +func (m *OrderEntry) XXX_DiscardUnknown() { + xxx_messageInfo_OrderEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_OrderEntry proto.InternalMessageInfo + +func (m *OrderEntry) GetAllocations() []*Allocation { + if m != nil { + return m.Allocations + } + return nil +} + +func (m *OrderEntry) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *OrderEntry) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +type Allocation struct { + OrderId uint64 `protobuf:"varint,1,opt,name=orderId,proto3" json:"order_id"` + Quantity github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=quantity,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"quantity" yaml:"quantity"` + Account string `protobuf:"bytes,3,opt,name=account,proto3" json:"account"` +} + +func (m *Allocation) Reset() { *m = Allocation{} } +func (m *Allocation) String() string { return proto.CompactTextString(m) } +func (*Allocation) ProtoMessage() {} +func (*Allocation) Descriptor() ([]byte, []int) { + return fileDescriptor_25878922effe12c2, []int{1} +} +func (m *Allocation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Allocation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Allocation.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 *Allocation) XXX_Merge(src proto.Message) { + xxx_messageInfo_Allocation.Merge(m, src) +} +func (m *Allocation) XXX_Size() int { + return m.Size() +} +func (m *Allocation) XXX_DiscardUnknown() { + xxx_messageInfo_Allocation.DiscardUnknown(m) +} + +var xxx_messageInfo_Allocation proto.InternalMessageInfo + +func (m *Allocation) GetOrderId() uint64 { + if m != nil { + return m.OrderId + } + return 0 +} + +func (m *Allocation) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +func init() { + proto.RegisterType((*OrderEntry)(nil), "seiprotocol.seichain.dex.OrderEntry") + proto.RegisterType((*Allocation)(nil), "seiprotocol.seichain.dex.Allocation") +} + +func init() { proto.RegisterFile("dex/order_entry.proto", fileDescriptor_25878922effe12c2) } + +var fileDescriptor_25878922effe12c2 = []byte{ + // 395 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x52, 0xb1, 0x6a, 0xe3, 0x40, + 0x10, 0x95, 0x4e, 0xf6, 0xf9, 0x6e, 0x6d, 0x30, 0x88, 0x3b, 0x10, 0x29, 0x24, 0x23, 0x12, 0xe3, + 0xc6, 0x12, 0x24, 0x5d, 0xba, 0x08, 0x07, 0x93, 0x22, 0x04, 0xd4, 0x04, 0x02, 0xc1, 0xc8, 0xab, + 0xc5, 0x5e, 0x22, 0x69, 0x1d, 0xed, 0x1a, 0xac, 0xbf, 0x48, 0x7e, 0x2a, 0xb8, 0x74, 0x19, 0x52, + 0x88, 0x60, 0x77, 0x2e, 0xfd, 0x05, 0x61, 0x47, 0x91, 0xad, 0x26, 0x45, 0x9a, 0x54, 0x9a, 0x79, + 0x33, 0x6f, 0xde, 0xec, 0x3c, 0xa1, 0xff, 0x21, 0x59, 0xb8, 0x2c, 0x0d, 0x49, 0x3a, 0x22, 0x89, + 0x48, 0x33, 0x67, 0x96, 0x32, 0xc1, 0x74, 0x83, 0x13, 0x0a, 0x11, 0x66, 0x91, 0xc3, 0x09, 0xc5, + 0xd3, 0x80, 0x26, 0x4e, 0x48, 0x16, 0x47, 0xff, 0x26, 0x6c, 0xc2, 0xa0, 0xe4, 0xca, 0xa8, 0xe8, + 0xb7, 0x9f, 0x35, 0x84, 0x6e, 0xe4, 0x94, 0x4b, 0x39, 0x44, 0xbf, 0x47, 0xf5, 0x59, 0x4a, 0x31, + 0x31, 0xd4, 0x8e, 0xda, 0xfb, 0xeb, 0x0d, 0x97, 0xb9, 0xa5, 0xbc, 0xe5, 0x56, 0x77, 0x42, 0xc5, + 0x74, 0x3e, 0x76, 0x30, 0x8b, 0x5d, 0xcc, 0x78, 0xcc, 0xf8, 0xe7, 0xa7, 0xcf, 0xc3, 0x07, 0x57, + 0x64, 0x33, 0xc2, 0x9d, 0x01, 0xc1, 0xdb, 0xdc, 0x2a, 0xe8, 0xbb, 0xdc, 0x6a, 0x65, 0x41, 0x1c, + 0x9d, 0xdb, 0x90, 0xda, 0x7e, 0x01, 0xeb, 0x14, 0xfd, 0x79, 0x9c, 0x07, 0x89, 0xa0, 0x22, 0x33, + 0x7e, 0x81, 0xc2, 0xf5, 0xb7, 0x15, 0xf6, 0x13, 0x76, 0xb9, 0xd5, 0x2e, 0x44, 0x4a, 0xc4, 0xf6, + 0xf7, 0x45, 0xfd, 0x16, 0x35, 0x83, 0x28, 0x62, 0x38, 0x10, 0x94, 0x25, 0xdc, 0xd0, 0x3a, 0x5a, + 0xaf, 0x79, 0x7a, 0xec, 0x7c, 0x75, 0x1e, 0xe7, 0x62, 0xdf, 0xec, 0xb5, 0xb7, 0xb9, 0x55, 0x25, + 0xfb, 0xd5, 0x44, 0x77, 0x11, 0x82, 0xc7, 0x0c, 0x48, 0xc2, 0x62, 0xa3, 0x06, 0xaf, 0x00, 0x06, + 0xa0, 0xa3, 0x50, 0xc2, 0x7e, 0xa5, 0x45, 0x12, 0x02, 0xce, 0x89, 0x28, 0x08, 0xf5, 0x03, 0x01, + 0xd0, 0x92, 0x70, 0x68, 0xb1, 0x5f, 0x54, 0x84, 0x0e, 0xeb, 0xe8, 0x5d, 0xd4, 0x00, 0x9f, 0xaf, + 0x42, 0x70, 0xa5, 0xe6, 0xb5, 0xe4, 0x15, 0x0a, 0xeb, 0x69, 0xe8, 0x97, 0xc5, 0x9f, 0x3c, 0xee, + 0x09, 0x6a, 0x04, 0x18, 0xb3, 0x79, 0x22, 0x0c, 0x0d, 0x94, 0x9a, 0xdb, 0xdc, 0x2a, 0x21, 0xbf, + 0x0c, 0xbc, 0xe1, 0x72, 0x6d, 0xaa, 0xab, 0xb5, 0xa9, 0xbe, 0xaf, 0x4d, 0xf5, 0x69, 0x63, 0x2a, + 0xab, 0x8d, 0xa9, 0xbc, 0x6e, 0x4c, 0xe5, 0xae, 0x5f, 0xd9, 0x88, 0x13, 0xda, 0x2f, 0x3d, 0x81, + 0x04, 0x4c, 0x71, 0x17, 0xae, 0xfc, 0xc3, 0x61, 0xb9, 0xf1, 0x6f, 0xa8, 0x9f, 0x7d, 0x04, 0x00, + 0x00, 0xff, 0xff, 0x59, 0x65, 0xd6, 0x5e, 0xf5, 0x02, 0x00, 0x00, +} + +func (m *OrderEntry) 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 *OrderEntry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OrderEntry) 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 = encodeVarintOrderEntry(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x2a + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintOrderEntry(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x22 + } + if len(m.Allocations) > 0 { + for iNdEx := len(m.Allocations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Allocations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintOrderEntry(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + { + size := m.Quantity.Size() + i -= size + if _, err := m.Quantity.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOrderEntry(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + { + size := m.Price.Size() + i -= size + if _, err := m.Price.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOrderEntry(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *Allocation) 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 *Allocation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Allocation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintOrderEntry(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0x1a + } + { + size := m.Quantity.Size() + i -= size + if _, err := m.Quantity.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintOrderEntry(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.OrderId != 0 { + i = encodeVarintOrderEntry(dAtA, i, uint64(m.OrderId)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintOrderEntry(dAtA []byte, offset int, v uint64) int { + offset -= sovOrderEntry(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *OrderEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Price.Size() + n += 1 + l + sovOrderEntry(uint64(l)) + l = m.Quantity.Size() + n += 1 + l + sovOrderEntry(uint64(l)) + if len(m.Allocations) > 0 { + for _, e := range m.Allocations { + l = e.Size() + n += 1 + l + sovOrderEntry(uint64(l)) + } + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovOrderEntry(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovOrderEntry(uint64(l)) + } + return n +} + +func (m *Allocation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.OrderId != 0 { + n += 1 + sovOrderEntry(uint64(m.OrderId)) + } + l = m.Quantity.Size() + n += 1 + l + sovOrderEntry(uint64(l)) + l = len(m.Account) + if l > 0 { + n += 1 + l + sovOrderEntry(uint64(l)) + } + return n +} + +func sovOrderEntry(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozOrderEntry(x uint64) (n int) { + return sovOrderEntry(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *OrderEntry) 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 ErrIntOverflowOrderEntry + } + 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: OrderEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OrderEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrderEntry + } + 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 ErrInvalidLengthOrderEntry + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOrderEntry + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Quantity", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrderEntry + } + 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 ErrInvalidLengthOrderEntry + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOrderEntry + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Quantity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Allocations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrderEntry + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthOrderEntry + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthOrderEntry + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Allocations = append(m.Allocations, &Allocation{}) + if err := m.Allocations[len(m.Allocations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + 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 ErrIntOverflowOrderEntry + } + 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 ErrInvalidLengthOrderEntry + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOrderEntry + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + 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 ErrIntOverflowOrderEntry + } + 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 ErrInvalidLengthOrderEntry + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOrderEntry + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipOrderEntry(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOrderEntry + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Allocation) 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 ErrIntOverflowOrderEntry + } + 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: Allocation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Allocation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OrderId", wireType) + } + m.OrderId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrderEntry + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OrderId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Quantity", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrderEntry + } + 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 ErrInvalidLengthOrderEntry + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOrderEntry + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Quantity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowOrderEntry + } + 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 ErrInvalidLengthOrderEntry + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthOrderEntry + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipOrderEntry(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthOrderEntry + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipOrderEntry(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, ErrIntOverflowOrderEntry + } + 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, ErrIntOverflowOrderEntry + } + 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, ErrIntOverflowOrderEntry + } + 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, ErrInvalidLengthOrderEntry + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupOrderEntry + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthOrderEntry + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthOrderEntry = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowOrderEntry = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupOrderEntry = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/order_placement.go b/x/dex/types/order_placement.go new file mode 100644 index 000000000..1104e1e01 --- /dev/null +++ b/x/dex/types/order_placement.go @@ -0,0 +1,31 @@ +package types + +import ( + "fmt" +) + +type SudoOrderPlacementMsg struct { + OrderPlacements OrderPlacementMsgDetails `json:"bulk_order_placements"` +} + +type OrderPlacementMsgDetails struct { + Orders []Order `json:"orders"` + Deposits []ContractDepositInfo `json:"deposits"` +} + +func (m *SudoOrderPlacementMsg) IsEmpty() bool { + return len(m.OrderPlacements.Deposits) == 0 && len(m.OrderPlacements.Orders) == 0 +} + +type SudoOrderPlacementResponse struct { + UnsuccessfulOrders []UnsuccessfulOrder `json:"unsuccessful_orders"` +} + +type UnsuccessfulOrder struct { + ID uint64 `json:"id"` + Reason string `json:"reason"` +} + +func (r SudoOrderPlacementResponse) String() string { + return fmt.Sprintf("Unsuccessful orders count: %d", len(r.UnsuccessfulOrders)) +} diff --git a/x/dex/types/orders.go b/x/dex/types/orders.go new file mode 100644 index 000000000..54c0eaf77 --- /dev/null +++ b/x/dex/types/orders.go @@ -0,0 +1,244 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/store/prefix" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/utils" +) + +type OrderBook struct { + Contract ContractAddress + Pair Pair + Longs *CachedSortedOrderBookEntries + Shorts *CachedSortedOrderBookEntries +} + +// entries are always sorted by prices in ascending order, regardless of side +type CachedSortedOrderBookEntries struct { + CachedEntries []OrderBookEntry + currentPtr int + currentChanged bool + + loader func(ctx sdk.Context, startingPriceExclusive sdk.Dec, withLimit bool) []OrderBookEntry + setter func(sdk.Context, OrderBookEntry) + deleter func(sdk.Context, OrderBookEntry) +} + +func NewCachedSortedOrderBookEntries( + loader func(ctx sdk.Context, startingPriceExclusive sdk.Dec, withLimit bool) []OrderBookEntry, + setter func(sdk.Context, OrderBookEntry), + deleter func(sdk.Context, OrderBookEntry), +) *CachedSortedOrderBookEntries { + return &CachedSortedOrderBookEntries{ + CachedEntries: []OrderBookEntry{}, + currentPtr: 0, + currentChanged: false, + loader: loader, + setter: setter, + deleter: deleter, + } +} + +func (c *CachedSortedOrderBookEntries) load(ctx sdk.Context) { + var loaded []OrderBookEntry + if len(c.CachedEntries) == 0 { + loaded = c.loader(ctx, sdk.ZeroDec(), false) + } else { + loaded = c.loader(ctx, c.CachedEntries[len(c.CachedEntries)-1].GetOrderEntry().Price, true) + } + c.CachedEntries = append(c.CachedEntries, loaded...) +} + +// Reduce quantity of the order book entry currently being pointed at by the specified quantity. +// Also remove/reduce allocations of the order book entry in FIFO order. If the order book entry +// does not have enough quantity to settle against, the returned `settled` value will equal to +// the quantity of the order book entry; otherwise it will equal to the specified quantity. +func (c *CachedSortedOrderBookEntries) SettleQuantity(_ sdk.Context, quantity sdk.Dec) (res []ToSettle, settled sdk.Dec) { + if quantity.IsZero() { + return []ToSettle{}, quantity + } + currentEntry := c.CachedEntries[c.currentPtr].GetOrderEntry() + c.currentChanged = true + + if quantity.GTE(currentEntry.Quantity) { + res = utils.Map(currentEntry.Allocations, AllocationToSettle) + settled = currentEntry.Quantity + currentEntry.Quantity = sdk.ZeroDec() + currentEntry.Allocations = []*Allocation{} + return res, settled + } + + settled = sdk.ZeroDec() + newFirstAllocationIdx := 0 + for idx, a := range currentEntry.Allocations { + postSettle := settled.Add(a.Quantity) + if postSettle.LTE(quantity) { + settled = postSettle + res = append(res, AllocationToSettle(a)) + } else { + newFirstAllocationIdx = idx + if settled.Equal(quantity) { + break + } + res = append(res, ToSettle{ + OrderID: a.OrderId, + Account: a.Account, + Amount: quantity.Sub(settled), + }) + a.Quantity = a.Quantity.Sub(quantity.Sub(settled)) + settled = quantity + break + } + } + currentEntry.Quantity = currentEntry.Quantity.Sub(quantity) + currentEntry.Allocations = currentEntry.Allocations[newFirstAllocationIdx:] + return res, settled +} + +// Discard all dirty changes and reload +func (c *CachedSortedOrderBookEntries) Refresh(ctx sdk.Context) { + c.CachedEntries = c.loader(ctx, sdk.ZeroDec(), false) + c.currentPtr = 0 + c.currentChanged = false +} + +func (c *CachedSortedOrderBookEntries) Flush(ctx sdk.Context) { + stop := c.currentPtr + if !c.currentChanged { + stop-- + } + for i := 0; i <= stop; i++ { + if i >= len(c.CachedEntries) { + break + } + entry := c.CachedEntries[i] + if entry.GetOrderEntry().Quantity.IsZero() { + c.deleter(ctx, entry) + } else { + c.setter(ctx, entry) + } + } + c.CachedEntries = c.CachedEntries[c.currentPtr:] + c.currentPtr = 0 + c.currentChanged = false +} + +// Next will only move on to the next order if the current order quantity hits zero. +// So it should not be used for read-only iteration +func (c *CachedSortedOrderBookEntries) Next(ctx sdk.Context) OrderBookEntry { + for c.currentPtr < len(c.CachedEntries) && c.CachedEntries[c.currentPtr].GetOrderEntry().Quantity.IsZero() { + c.currentPtr++ + c.currentChanged = false + } + if c.currentPtr >= len(c.CachedEntries) { + c.load(ctx) + // if nothing is loaded, we've reached the end + if c.currentPtr >= len(c.CachedEntries) { + return nil + } + } + return c.CachedEntries[c.currentPtr] +} + +type OrderBookEntry interface { + GetPrice() sdk.Dec + GetOrderEntry() *OrderEntry + DeepCopy() OrderBookEntry + SetEntry(*OrderEntry) + SetPrice(sdk.Dec) +} + +func (m *LongBook) SetPrice(p sdk.Dec) { + m.Price = p +} + +type PriceStore struct { + Store prefix.Store + PriceKeys [][]byte +} + +func (m *LongBook) GetPrice() sdk.Dec { + return m.Price +} + +func (m *LongBook) GetOrderEntry() *OrderEntry { + return m.Entry +} + +func (m *LongBook) SetEntry(newEntry *OrderEntry) { + m.Entry = newEntry +} + +func (m *LongBook) DeepCopy() OrderBookEntry { + allocations := []*Allocation{} + for _, allo := range m.Entry.Allocations { + allocations = append(allocations, &Allocation{ + OrderId: allo.OrderId, + Quantity: allo.Quantity, + Account: allo.Account, + }) + } + newOrderEntry := OrderEntry{ + Price: m.Entry.Price, + Quantity: m.Entry.Quantity, + PriceDenom: m.Entry.PriceDenom, + AssetDenom: m.Entry.AssetDenom, + Allocations: allocations, + } + return &LongBook{ + Price: m.Price, + Entry: &newOrderEntry, + } +} + +func (m *ShortBook) SetPrice(p sdk.Dec) { + m.Price = p +} + +func (m *ShortBook) GetPrice() sdk.Dec { + return m.Price +} + +func (m *ShortBook) GetOrderEntry() *OrderEntry { + return m.Entry +} + +func (m *ShortBook) SetEntry(newEntry *OrderEntry) { + m.Entry = newEntry +} + +func (m *ShortBook) DeepCopy() OrderBookEntry { + allocations := []*Allocation{} + for _, allo := range m.Entry.Allocations { + allocations = append(allocations, &Allocation{ + OrderId: allo.OrderId, + Quantity: allo.Quantity, + Account: allo.Account, + }) + } + newOrderEntry := OrderEntry{ + Price: m.Entry.Price, + Quantity: m.Entry.Quantity, + PriceDenom: m.Entry.PriceDenom, + AssetDenom: m.Entry.AssetDenom, + Allocations: allocations, + } + return &ShortBook{ + Price: m.Price, + Entry: &newOrderEntry, + } +} + +type ToSettle struct { + OrderID uint64 + Amount sdk.Dec + Account string +} + +func AllocationToSettle(a *Allocation) ToSettle { + return ToSettle{ + OrderID: a.OrderId, + Amount: a.Quantity, + Account: a.Account, + } +} diff --git a/x/dex/types/orders_test.go b/x/dex/types/orders_test.go new file mode 100644 index 000000000..65439dfc4 --- /dev/null +++ b/x/dex/types/orders_test.go @@ -0,0 +1,166 @@ +package types_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/x/dex/keeper" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +var TestEntryOne = types.OrderEntry{ + Price: sdk.MustNewDecFromStr("10"), + Quantity: sdk.MustNewDecFromStr("3"), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Allocations: []*types.Allocation{ + { + Quantity: sdk.MustNewDecFromStr("2"), + Account: "abc", + OrderId: 1, + }, { + Quantity: sdk.MustNewDecFromStr("1"), + Account: "def", + OrderId: 2, + }, + }, +} + +var TestEntryTwo = types.OrderEntry{ + Price: sdk.MustNewDecFromStr("11"), + Quantity: sdk.MustNewDecFromStr("2"), + PriceDenom: keepertest.TestPriceDenom, + AssetDenom: keepertest.TestAssetDenom, + Allocations: []*types.Allocation{ + { + Quantity: sdk.MustNewDecFromStr("2"), + Account: "ghi", + OrderId: 3, + }, + }, +} + +func getCachedSortedOrderBookEntries(keeper *keeper.Keeper) *types.CachedSortedOrderBookEntries { + loader := func(lctx sdk.Context, startExclusive sdk.Dec, withLimit bool) []types.OrderBookEntry { + if !withLimit { + return keeper.GetTopNLongBooksForPair(lctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom, 1) + } + return keeper.GetTopNLongBooksForPairStarting(lctx, keepertest.TestContract, keepertest.TestPriceDenom, keepertest.TestAssetDenom, 1, startExclusive) + } + setter := func(lctx sdk.Context, o types.OrderBookEntry) { + keeper.SetLongOrderBookEntry(lctx, keepertest.TestContract, o) + } + deleter := func(lctx sdk.Context, o types.OrderBookEntry) { + keeper.RemoveLongBookByPrice(lctx, keepertest.TestContract, o.GetPrice(), keepertest.TestPriceDenom, keepertest.TestAssetDenom) + } + return types.NewCachedSortedOrderBookEntries(loader, setter, deleter) +} + +func populateEntries(ctx sdk.Context, keeper *keeper.Keeper) { + keeper.SetLongBook(ctx, keepertest.TestContract, types.LongBook{ + Price: TestEntryOne.Price, + Entry: &TestEntryOne, + }) + keeper.SetLongBook(ctx, keepertest.TestContract, types.LongBook{ + Price: TestEntryTwo.Price, + Entry: &TestEntryTwo, + }) +} + +func TestIterateAndMutate(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + populateEntries(ctx, dexkeeper) + cache := getCachedSortedOrderBookEntries(dexkeeper) + // first Next should return entry two since its a higher priced long + entry := cache.Next(ctx) + require.NotNil(t, entry) + require.Equal(t, TestEntryTwo.Price, entry.GetPrice()) + require.Equal(t, TestEntryTwo, *entry.GetOrderEntry()) + res, settled := cache.SettleQuantity(ctx, sdk.OneDec()) + require.Equal(t, []types.ToSettle{{ + Amount: sdk.OneDec(), + Account: "ghi", + OrderID: 3, + }}, res) + require.Equal(t, sdk.OneDec(), settled) + + // second Next should still return entry two with decreased quantity + entry = cache.Next(ctx) + require.NotNil(t, entry) + require.Equal(t, TestEntryTwo.Price, entry.GetPrice()) + require.Equal(t, sdk.OneDec(), entry.GetOrderEntry().Quantity) + require.Equal(t, 1, len(entry.GetOrderEntry().Allocations)) + require.Equal(t, types.Allocation{ + Quantity: sdk.OneDec(), + Account: "ghi", + OrderId: 3, + }, *entry.GetOrderEntry().Allocations[0]) + res, settled = cache.SettleQuantity(ctx, sdk.OneDec()) + require.Equal(t, []types.ToSettle{{ + Amount: sdk.OneDec(), + Account: "ghi", + OrderID: 3, + }}, res) + require.Equal(t, sdk.OneDec(), settled) + + // third Next should return entry one since entry two has fully settled (whether flushed or not) + entry = cache.Next(ctx) + require.NotNil(t, entry) + require.Equal(t, TestEntryOne.Price, entry.GetPrice()) + require.Equal(t, TestEntryOne, *entry.GetOrderEntry()) + res, settled = cache.SettleQuantity(ctx, sdk.NewDec(4)) + require.Equal(t, []types.ToSettle{{ + Amount: sdk.NewDec(2), + Account: "abc", + OrderID: 1, + }, { + Amount: sdk.NewDec(1), + Account: "def", + OrderID: 2, + }}, res) + require.Equal(t, sdk.NewDec(3), settled) + + // fourth Next should return nil + entry = cache.Next(ctx) + require.Nil(t, entry) +} + +func TestRefreshAndFlush(t *testing.T) { + dexkeeper, ctx := keepertest.DexKeeper(t) + populateEntries(ctx, dexkeeper) + cache := getCachedSortedOrderBookEntries(dexkeeper) + _ = cache.Next(ctx) + _, _ = cache.SettleQuantity(ctx, sdk.OneDec()) + // refresh without flushing settle changes should undo the settle + cache.Refresh(ctx) + entry := cache.Next(ctx) + require.NotNil(t, entry) + require.Equal(t, TestEntryTwo.Price, entry.GetPrice()) + require.Equal(t, TestEntryTwo, *entry.GetOrderEntry()) + + _, _ = cache.SettleQuantity(ctx, sdk.OneDec()) + cache.Flush(ctx) + // refresh after flushing should reflect the settle change + cache.Refresh(ctx) + entry = cache.Next(ctx) + require.NotNil(t, entry) + require.Equal(t, TestEntryTwo.Price, entry.GetPrice()) + require.Equal(t, sdk.OneDec(), entry.GetOrderEntry().Quantity) + require.Equal(t, 1, len(entry.GetOrderEntry().Allocations)) + require.Equal(t, types.Allocation{ + Quantity: sdk.OneDec(), + Account: "ghi", + OrderId: 3, + }, *entry.GetOrderEntry().Allocations[0]) + + _, _ = cache.SettleQuantity(ctx, sdk.OneDec()) + cache.Flush(ctx) + // refresh after flushing a deleted entry should result in the next Next being the next entry + cache.Refresh(ctx) + entry = cache.Next(ctx) + require.NotNil(t, entry) + require.Equal(t, TestEntryOne.Price, entry.GetPrice()) + require.Equal(t, TestEntryOne, *entry.GetOrderEntry()) +} diff --git a/x/dex/types/pair.pb.go b/x/dex/types/pair.pb.go new file mode 100644 index 000000000..55841676d --- /dev/null +++ b/x/dex/types/pair.pb.go @@ -0,0 +1,718 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/pair.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 Pair struct { + PriceDenom string `protobuf:"bytes,1,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,2,opt,name=assetDenom,proto3" json:"asset_denom"` + PriceTicksize *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=priceTicksize,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price_tick_size"` + QuantityTicksize *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=quantityTicksize,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"quantity_tick_size"` +} + +func (m *Pair) Reset() { *m = Pair{} } +func (m *Pair) String() string { return proto.CompactTextString(m) } +func (*Pair) ProtoMessage() {} +func (*Pair) Descriptor() ([]byte, []int) { + return fileDescriptor_d4350ebee878f69a, []int{0} +} +func (m *Pair) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Pair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Pair.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 *Pair) XXX_Merge(src proto.Message) { + xxx_messageInfo_Pair.Merge(m, src) +} +func (m *Pair) XXX_Size() int { + return m.Size() +} +func (m *Pair) XXX_DiscardUnknown() { + xxx_messageInfo_Pair.DiscardUnknown(m) +} + +var xxx_messageInfo_Pair proto.InternalMessageInfo + +func (m *Pair) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *Pair) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +type BatchContractPair struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_addr"` + Pairs []*Pair `protobuf:"bytes,2,rep,name=pairs,proto3" json:"pairs"` +} + +func (m *BatchContractPair) Reset() { *m = BatchContractPair{} } +func (m *BatchContractPair) String() string { return proto.CompactTextString(m) } +func (*BatchContractPair) ProtoMessage() {} +func (*BatchContractPair) Descriptor() ([]byte, []int) { + return fileDescriptor_d4350ebee878f69a, []int{1} +} +func (m *BatchContractPair) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BatchContractPair) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BatchContractPair.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 *BatchContractPair) XXX_Merge(src proto.Message) { + xxx_messageInfo_BatchContractPair.Merge(m, src) +} +func (m *BatchContractPair) XXX_Size() int { + return m.Size() +} +func (m *BatchContractPair) XXX_DiscardUnknown() { + xxx_messageInfo_BatchContractPair.DiscardUnknown(m) +} + +var xxx_messageInfo_BatchContractPair proto.InternalMessageInfo + +func (m *BatchContractPair) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *BatchContractPair) GetPairs() []*Pair { + if m != nil { + return m.Pairs + } + return nil +} + +func init() { + proto.RegisterType((*Pair)(nil), "seiprotocol.seichain.dex.Pair") + proto.RegisterType((*BatchContractPair)(nil), "seiprotocol.seichain.dex.BatchContractPair") +} + +func init() { proto.RegisterFile("dex/pair.proto", fileDescriptor_d4350ebee878f69a) } + +var fileDescriptor_d4350ebee878f69a = []byte{ + // 368 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x52, 0x3f, 0x4f, 0xf2, 0x40, + 0x18, 0xa7, 0xc0, 0xfb, 0x26, 0x1c, 0x22, 0xd2, 0x38, 0x34, 0x0e, 0x2d, 0x61, 0x30, 0x2c, 0xf4, + 0x12, 0x8d, 0xb3, 0xa1, 0x92, 0xb8, 0x9a, 0xc6, 0xc9, 0x85, 0x1c, 0x77, 0x97, 0x72, 0x41, 0x7a, + 0xf5, 0xee, 0x48, 0xc0, 0xaf, 0xe0, 0xe2, 0x77, 0x72, 0x61, 0x64, 0x34, 0x0e, 0x8d, 0x81, 0xad, + 0x9f, 0xc2, 0xdc, 0x95, 0x0a, 0xc4, 0x38, 0x38, 0xdd, 0x3d, 0xbf, 0xe7, 0xf7, 0xa7, 0x7d, 0x9e, + 0x03, 0xc7, 0x84, 0xce, 0x61, 0x82, 0x98, 0xf0, 0x13, 0xc1, 0x15, 0xb7, 0x1d, 0x49, 0x99, 0xb9, + 0x61, 0xfe, 0xe8, 0x4b, 0xca, 0xf0, 0x18, 0xb1, 0xd8, 0x27, 0x74, 0x7e, 0x76, 0x1a, 0xf1, 0x88, + 0x9b, 0x16, 0xd4, 0xb7, 0x9c, 0xdf, 0x79, 0x2b, 0x83, 0xea, 0x1d, 0x62, 0xc2, 0x86, 0x00, 0x24, + 0x82, 0x61, 0x3a, 0xa0, 0x31, 0x9f, 0x3a, 0x56, 0xdb, 0xea, 0xd6, 0x82, 0x66, 0x96, 0x7a, 0x75, + 0x83, 0x0e, 0x89, 0x86, 0xc3, 0x3d, 0x8a, 0x16, 0x20, 0x29, 0xa9, 0xca, 0x05, 0xe5, 0x9d, 0xc0, + 0xa0, 0x85, 0x60, 0x47, 0xb1, 0x23, 0xd0, 0x30, 0xf2, 0x7b, 0x86, 0x27, 0x92, 0x3d, 0x53, 0xa7, + 0x62, 0x34, 0xfd, 0x65, 0xea, 0x59, 0x1f, 0xa9, 0x77, 0x1e, 0x31, 0x35, 0x9e, 0x8d, 0x7c, 0xcc, + 0xa7, 0x10, 0x73, 0x39, 0xe5, 0x72, 0x7b, 0xf4, 0x24, 0x99, 0x40, 0xb5, 0x48, 0xa8, 0xf4, 0x07, + 0x14, 0x67, 0xa9, 0xd7, 0xcc, 0x3f, 0x49, 0x31, 0x3c, 0x19, 0x6a, 0xa3, 0xf0, 0xd0, 0xd7, 0x4e, + 0xc0, 0xc9, 0xd3, 0x0c, 0xc5, 0x8a, 0xa9, 0xc5, 0x77, 0x56, 0xd5, 0x64, 0x0d, 0xfe, 0x9c, 0x65, + 0x17, 0x4e, 0x7b, 0x71, 0x3f, 0xdc, 0x3b, 0x2f, 0x16, 0x68, 0x05, 0x48, 0xe1, 0xf1, 0x0d, 0x8f, + 0x95, 0x40, 0x58, 0x99, 0x91, 0x5e, 0x81, 0x23, 0xbc, 0xad, 0xfb, 0x84, 0x88, 0xed, 0x50, 0x5b, + 0x59, 0xea, 0x35, 0x0a, 0x7c, 0x88, 0x08, 0x11, 0xe1, 0x01, 0xcd, 0xbe, 0x06, 0xff, 0xf4, 0x42, + 0xa5, 0x53, 0x6e, 0x57, 0xba, 0xf5, 0x0b, 0xd7, 0xff, 0x6d, 0xa5, 0xbe, 0x4e, 0x09, 0x6a, 0x59, + 0xea, 0xe5, 0x82, 0x30, 0x3f, 0x82, 0xdb, 0xe5, 0xda, 0xb5, 0x56, 0x6b, 0xd7, 0xfa, 0x5c, 0xbb, + 0xd6, 0xeb, 0xc6, 0x2d, 0xad, 0x36, 0x6e, 0xe9, 0x7d, 0xe3, 0x96, 0x1e, 0x7a, 0x7b, 0xff, 0x2d, + 0x29, 0xeb, 0x15, 0xb6, 0xa6, 0x30, 0xbe, 0x70, 0x0e, 0xf5, 0x8b, 0x32, 0x23, 0x18, 0xfd, 0x37, + 0xfd, 0xcb, 0xaf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd0, 0x03, 0x32, 0x50, 0x65, 0x02, 0x00, 0x00, +} + +func (m *Pair) 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 *Pair) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Pair) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.QuantityTicksize != nil { + { + size := m.QuantityTicksize.Size() + i -= size + if _, err := m.QuantityTicksize.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPair(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.PriceTicksize != nil { + { + size := m.PriceTicksize.Size() + i -= size + if _, err := m.PriceTicksize.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPair(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintPair(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintPair(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *BatchContractPair) 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 *BatchContractPair) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BatchContractPair) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Pairs) > 0 { + for iNdEx := len(m.Pairs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Pairs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPair(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintPair(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintPair(dAtA []byte, offset int, v uint64) int { + offset -= sovPair(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Pair) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovPair(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovPair(uint64(l)) + } + if m.PriceTicksize != nil { + l = m.PriceTicksize.Size() + n += 1 + l + sovPair(uint64(l)) + } + if m.QuantityTicksize != nil { + l = m.QuantityTicksize.Size() + n += 1 + l + sovPair(uint64(l)) + } + return n +} + +func (m *BatchContractPair) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovPair(uint64(l)) + } + if len(m.Pairs) > 0 { + for _, e := range m.Pairs { + l = e.Size() + n += 1 + l + sovPair(uint64(l)) + } + } + return n +} + +func sovPair(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozPair(x uint64) (n int) { + return sovPair(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Pair) 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 ErrIntOverflowPair + } + 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: Pair: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Pair: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowPair + } + 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 ErrInvalidLengthPair + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPair + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + 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 ErrIntOverflowPair + } + 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 ErrInvalidLengthPair + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPair + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PriceTicksize", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPair + } + 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 ErrInvalidLengthPair + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPair + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.PriceTicksize = &v + if err := m.PriceTicksize.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field QuantityTicksize", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPair + } + 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 ErrInvalidLengthPair + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPair + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.QuantityTicksize = &v + if err := m.QuantityTicksize.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPair(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPair + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BatchContractPair) 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 ErrIntOverflowPair + } + 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: BatchContractPair: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BatchContractPair: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPair + } + 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 ErrInvalidLengthPair + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPair + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pairs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPair + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPair + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPair + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Pairs = append(m.Pairs, &Pair{}) + if err := m.Pairs[len(m.Pairs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPair(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPair + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPair(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, ErrIntOverflowPair + } + 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, ErrIntOverflowPair + } + 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, ErrIntOverflowPair + } + 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, ErrInvalidLengthPair + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupPair + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthPair + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthPair = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPair = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupPair = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/params.go b/x/dex/types/params.go new file mode 100644 index 000000000..aa0f4cde7 --- /dev/null +++ b/x/dex/types/params.go @@ -0,0 +1,143 @@ +package types + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" + "gopkg.in/yaml.v2" +) + +var ( + KeyPriceSnapshotRetention = []byte("PriceSnapshotRetention") // number of epochs to retain price snapshots for + KeySudoCallGasPrice = []byte("KeySudoCallGasPrice") // gas price for sudo calls from endblock + KeyBeginBlockGasLimit = []byte("KeyBeginBlockGasLimit") + KeyEndBlockGasLimit = []byte("KeyEndBlockGasLimit") + KeyDefaultGasPerOrder = []byte("KeyDefaultGasPerOrder") + KeyDefaultGasPerCancel = []byte("KeyDefaultGasPerCancel") + KeyMinRentDeposit = []byte("KeyMinRentDeposit") + KeyGasAllowancePerSettlement = []byte("KeyGasAllowancePerSettlement") + KeyMinProcessableRent = []byte("KeyMinProcessableRent") + KeyOrderBookEntriesPerLoad = []byte("KeyOrderBookEntriesPerLoad") + KeyContractUnsuspendCost = []byte("KeyContractUnsuspendCost") + KeyMaxOrderPerPrice = []byte("KeyMaxOrderPerPrice") + KeyMaxPairsPerContract = []byte("KeyMaxPairsPerContract") + KeyDefaultGasPerOrderDataByte = []byte("KeyDefaultGasPerOrderDataByte") +) + +const ( + DefaultPriceSnapshotRetention = 24 * 3600 // default to one day + DefaultBeginBlockGasLimit = 200000000 // 200M + DefaultEndBlockGasLimit = 1000000000 // 1B + DefaultDefaultGasPerOrder = 55000 + DefaultDefaultGasPerCancel = 53000 + DefaultMinRentDeposit = 10000000 // 10 sei + DefaultGasAllowancePerSettlement = 10000 + DefaultMinProcessableRent = 100000 + DefaultOrderBookEntriesPerLoad = 10 + DefaultContractUnsuspendCost = 1000000 + DefaultMaxOrderPerPrice = 10000 + DefaultMaxPairsPerContract = 100 + DefaultDefaultGasPerOrderDataByte = 30 +) + +var DefaultSudoCallGasPrice = sdk.NewDecWithPrec(1, 1) // 0.1 + +var _ paramtypes.ParamSet = (*Params)(nil) + +// ParamKeyTable the param key table for launch module +func ParamKeyTable() paramtypes.KeyTable { + return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) +} + +// DefaultParams returns a default set of parameters +func DefaultParams() Params { + return Params{ + PriceSnapshotRetention: DefaultPriceSnapshotRetention, + SudoCallGasPrice: DefaultSudoCallGasPrice, + BeginBlockGasLimit: DefaultBeginBlockGasLimit, + EndBlockGasLimit: DefaultEndBlockGasLimit, + DefaultGasPerOrder: DefaultDefaultGasPerOrder, + DefaultGasPerCancel: DefaultDefaultGasPerCancel, + MinRentDeposit: DefaultMinRentDeposit, + GasAllowancePerSettlement: DefaultGasAllowancePerSettlement, + MinProcessableRent: DefaultMinProcessableRent, + OrderBookEntriesPerLoad: DefaultOrderBookEntriesPerLoad, + ContractUnsuspendCost: DefaultContractUnsuspendCost, + MaxOrderPerPrice: DefaultMaxOrderPerPrice, + MaxPairsPerContract: DefaultMaxPairsPerContract, + DefaultGasPerOrderDataByte: DefaultDefaultGasPerOrderDataByte, + } +} + +// ParamSetPairs get the params.ParamSet +func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { + return paramtypes.ParamSetPairs{ + paramtypes.NewParamSetPair(KeyPriceSnapshotRetention, &p.PriceSnapshotRetention, validatePriceSnapshotRetention), + paramtypes.NewParamSetPair(KeySudoCallGasPrice, &p.SudoCallGasPrice, validateSudoCallGasPrice), + paramtypes.NewParamSetPair(KeyBeginBlockGasLimit, &p.BeginBlockGasLimit, validateUint64Param), + paramtypes.NewParamSetPair(KeyEndBlockGasLimit, &p.EndBlockGasLimit, validateUint64Param), + paramtypes.NewParamSetPair(KeyDefaultGasPerOrder, &p.DefaultGasPerOrder, validateUint64Param), + paramtypes.NewParamSetPair(KeyDefaultGasPerCancel, &p.DefaultGasPerCancel, validateUint64Param), + paramtypes.NewParamSetPair(KeyMinRentDeposit, &p.MinRentDeposit, validateUint64Param), + paramtypes.NewParamSetPair(KeyGasAllowancePerSettlement, &p.GasAllowancePerSettlement, validateUint64Param), + paramtypes.NewParamSetPair(KeyMinProcessableRent, &p.MinProcessableRent, validateUint64Param), + paramtypes.NewParamSetPair(KeyOrderBookEntriesPerLoad, &p.OrderBookEntriesPerLoad, validateUint64Param), + paramtypes.NewParamSetPair(KeyContractUnsuspendCost, &p.ContractUnsuspendCost, validateUint64Param), + paramtypes.NewParamSetPair(KeyMaxOrderPerPrice, &p.MaxOrderPerPrice, validateUint64Param), + paramtypes.NewParamSetPair(KeyMaxPairsPerContract, &p.MaxPairsPerContract, validateUint64Param), + paramtypes.NewParamSetPair(KeyDefaultGasPerOrderDataByte, &p.DefaultGasPerOrderDataByte, validateUint64Param), + } +} + +// Validate validates the set of params +func (p Params) Validate() error { + if err := validatePriceSnapshotRetention(p.PriceSnapshotRetention); err != nil { + return err + } + if err := validateSudoCallGasPrice(p.SudoCallGasPrice); err != nil { + return err + } + // it's not possible for other params to fail validation if they've already + // made it into Params' fields. + return nil +} + +// String implements the Stringer interface. +func (p Params) String() string { + out, _ := yaml.Marshal(p) + return string(out) +} + +func validatePriceSnapshotRetention(i interface{}) error { + v, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + if v == 0 { + return fmt.Errorf("price snapshot retention must be a positive integer: %d", v) + } + + return nil +} + +func validateSudoCallGasPrice(i interface{}) error { + price, ok := i.(sdk.Dec) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + if !price.IsPositive() { + return fmt.Errorf("nonpositive sudo call price") + } + return nil +} + +func validateUint64Param(i interface{}) error { + _, ok := i.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", i) + } + + return nil +} diff --git a/x/dex/types/params.pb.go b/x/dex/types/params.pb.go new file mode 100644 index 000000000..7322767bc --- /dev/null +++ b/x/dex/types/params.pb.go @@ -0,0 +1,870 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/params.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 + +// Params defines the parameters for the module. +type Params struct { + PriceSnapshotRetention uint64 `protobuf:"varint,1,opt,name=price_snapshot_retention,json=priceSnapshotRetention,proto3" json:"price_snapshot_retention" yaml:"price_snapshot_retention"` + SudoCallGasPrice github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=sudo_call_gas_price,json=sudoCallGasPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"sudo_call_gas_price"` + BeginBlockGasLimit uint64 `protobuf:"varint,3,opt,name=begin_block_gas_limit,json=beginBlockGasLimit,proto3" json:"begin_block_gas_limit" yaml:"begin_block_gas_limit"` + EndBlockGasLimit uint64 `protobuf:"varint,4,opt,name=end_block_gas_limit,json=endBlockGasLimit,proto3" json:"end_block_gas_limit" yaml:"end_block_gas_limit"` + DefaultGasPerOrder uint64 `protobuf:"varint,5,opt,name=default_gas_per_order,json=defaultGasPerOrder,proto3" json:"default_gas_per_order" yaml:"default_gas_per_order"` + DefaultGasPerCancel uint64 `protobuf:"varint,6,opt,name=default_gas_per_cancel,json=defaultGasPerCancel,proto3" json:"default_gas_per_cancel" yaml:"default_gas_per_cancel"` + MinRentDeposit uint64 `protobuf:"varint,7,opt,name=min_rent_deposit,json=minRentDeposit,proto3" json:"min_rent_deposit" yaml:"min_rent_deposit"` + GasAllowancePerSettlement uint64 `protobuf:"varint,8,opt,name=gas_allowance_per_settlement,json=gasAllowancePerSettlement,proto3" json:"gas_allowance_per_settlement" yaml:"gas_allowance_per_settlement"` + MinProcessableRent uint64 `protobuf:"varint,9,opt,name=min_processable_rent,json=minProcessableRent,proto3" json:"min_processable_rent" yaml:"min_processable_rent"` + OrderBookEntriesPerLoad uint64 `protobuf:"varint,10,opt,name=order_book_entries_per_load,json=orderBookEntriesPerLoad,proto3" json:"order_book_entries_per_load" yaml:"order_book_entries_per_load"` + ContractUnsuspendCost uint64 `protobuf:"varint,11,opt,name=contract_unsuspend_cost,json=contractUnsuspendCost,proto3" json:"contract_unsuspend_cost" yaml:"contract_unsuspend_cost"` + MaxOrderPerPrice uint64 `protobuf:"varint,12,opt,name=max_order_per_price,json=maxOrderPerPrice,proto3" json:"max_order_per_price" yaml:"max_order_per_price"` + MaxPairsPerContract uint64 `protobuf:"varint,13,opt,name=max_pairs_per_contract,json=maxPairsPerContract,proto3" json:"max_pairs_per_contract" yaml:"max_pairs_per_contract"` + DefaultGasPerOrderDataByte uint64 `protobuf:"varint,14,opt,name=default_gas_per_order_data_byte,json=defaultGasPerOrderDataByte,proto3" json:"default_gas_per_order_data_byte" yaml:"default_gas_per_order_data_byte"` +} + +func (m *Params) Reset() { *m = Params{} } +func (*Params) ProtoMessage() {} +func (*Params) Descriptor() ([]byte, []int) { + return fileDescriptor_e49286500ccff43e, []int{0} +} +func (m *Params) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Params) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Params.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 *Params) XXX_Merge(src proto.Message) { + xxx_messageInfo_Params.Merge(m, src) +} +func (m *Params) XXX_Size() int { + return m.Size() +} +func (m *Params) XXX_DiscardUnknown() { + xxx_messageInfo_Params.DiscardUnknown(m) +} + +var xxx_messageInfo_Params proto.InternalMessageInfo + +func (m *Params) GetPriceSnapshotRetention() uint64 { + if m != nil { + return m.PriceSnapshotRetention + } + return 0 +} + +func (m *Params) GetBeginBlockGasLimit() uint64 { + if m != nil { + return m.BeginBlockGasLimit + } + return 0 +} + +func (m *Params) GetEndBlockGasLimit() uint64 { + if m != nil { + return m.EndBlockGasLimit + } + return 0 +} + +func (m *Params) GetDefaultGasPerOrder() uint64 { + if m != nil { + return m.DefaultGasPerOrder + } + return 0 +} + +func (m *Params) GetDefaultGasPerCancel() uint64 { + if m != nil { + return m.DefaultGasPerCancel + } + return 0 +} + +func (m *Params) GetMinRentDeposit() uint64 { + if m != nil { + return m.MinRentDeposit + } + return 0 +} + +func (m *Params) GetGasAllowancePerSettlement() uint64 { + if m != nil { + return m.GasAllowancePerSettlement + } + return 0 +} + +func (m *Params) GetMinProcessableRent() uint64 { + if m != nil { + return m.MinProcessableRent + } + return 0 +} + +func (m *Params) GetOrderBookEntriesPerLoad() uint64 { + if m != nil { + return m.OrderBookEntriesPerLoad + } + return 0 +} + +func (m *Params) GetContractUnsuspendCost() uint64 { + if m != nil { + return m.ContractUnsuspendCost + } + return 0 +} + +func (m *Params) GetMaxOrderPerPrice() uint64 { + if m != nil { + return m.MaxOrderPerPrice + } + return 0 +} + +func (m *Params) GetMaxPairsPerContract() uint64 { + if m != nil { + return m.MaxPairsPerContract + } + return 0 +} + +func (m *Params) GetDefaultGasPerOrderDataByte() uint64 { + if m != nil { + return m.DefaultGasPerOrderDataByte + } + return 0 +} + +func init() { + proto.RegisterType((*Params)(nil), "seiprotocol.seichain.dex.Params") +} + +func init() { proto.RegisterFile("dex/params.proto", fileDescriptor_e49286500ccff43e) } + +var fileDescriptor_e49286500ccff43e = []byte{ + // 787 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x95, 0xc1, 0x6f, 0x1b, 0x45, + 0x14, 0xc6, 0xbd, 0x50, 0x42, 0x3b, 0x94, 0xca, 0xda, 0x34, 0xc9, 0x92, 0x16, 0x4f, 0x35, 0x48, + 0x55, 0x2f, 0xb1, 0x0f, 0x08, 0x21, 0x8a, 0x10, 0xc2, 0x49, 0x94, 0x4b, 0x11, 0xd6, 0x54, 0x1c, + 0xe0, 0xb2, 0x1a, 0xef, 0x3e, 0x9c, 0x51, 0x66, 0x67, 0x56, 0x33, 0x63, 0x61, 0x9f, 0xb9, 0x70, + 0x44, 0x9c, 0x38, 0xf6, 0xcf, 0xe9, 0xb1, 0x47, 0xc4, 0x61, 0x84, 0x92, 0x0b, 0xda, 0xe3, 0xfe, + 0x05, 0x68, 0x66, 0x6d, 0x96, 0x24, 0x6b, 0xf7, 0x94, 0xcd, 0xf7, 0xfb, 0xb4, 0xdf, 0x7b, 0xde, + 0x79, 0x6f, 0x50, 0x3f, 0x87, 0xc5, 0xa8, 0x64, 0x9a, 0x15, 0x66, 0x58, 0x6a, 0x65, 0x55, 0x9c, + 0x18, 0xe0, 0xe1, 0x29, 0x53, 0x62, 0x68, 0x80, 0x67, 0xe7, 0x8c, 0xcb, 0x61, 0x0e, 0x8b, 0xc3, + 0x87, 0x33, 0x35, 0x53, 0x01, 0x8d, 0xfc, 0x53, 0xe3, 0x27, 0xf5, 0x7d, 0xb4, 0x33, 0x09, 0x2f, + 0x88, 0x97, 0x28, 0x29, 0x35, 0xcf, 0x20, 0x35, 0x92, 0x95, 0xe6, 0x5c, 0xd9, 0x54, 0x83, 0x05, + 0x69, 0xb9, 0x92, 0x49, 0xf4, 0x24, 0x7a, 0x76, 0x67, 0xfc, 0x75, 0xe5, 0xf0, 0x46, 0x4f, 0xed, + 0x30, 0x5e, 0xb2, 0x42, 0x3c, 0x27, 0x9b, 0x1c, 0x84, 0xee, 0x07, 0xf4, 0x72, 0x45, 0xe8, 0x1a, + 0xc4, 0x16, 0xed, 0x9a, 0x79, 0xae, 0xd2, 0x8c, 0x09, 0x91, 0xce, 0x98, 0x49, 0x83, 0x2f, 0x79, + 0xe7, 0x49, 0xf4, 0xec, 0xde, 0xf8, 0xf4, 0xb5, 0xc3, 0xbd, 0xbf, 0x1c, 0x7e, 0x3a, 0xe3, 0xf6, + 0x7c, 0x3e, 0x1d, 0x66, 0xaa, 0x18, 0x65, 0xca, 0x14, 0xca, 0xac, 0xfe, 0x1c, 0x99, 0xfc, 0x62, + 0x64, 0x97, 0x25, 0x98, 0xe1, 0x09, 0x64, 0x95, 0xc3, 0x5d, 0x2f, 0xa3, 0x7d, 0x2f, 0x1e, 0x33, + 0x21, 0xce, 0x98, 0x99, 0x78, 0x25, 0x16, 0x68, 0x6f, 0x0a, 0x33, 0x2e, 0xd3, 0xa9, 0x50, 0xd9, + 0x45, 0xb0, 0x0a, 0x5e, 0x70, 0x9b, 0xbc, 0x1b, 0xba, 0xfd, 0xa2, 0x72, 0xb8, 0xdb, 0x50, 0x3b, + 0xfc, 0xb8, 0x69, 0xb5, 0x13, 0x13, 0x1a, 0x07, 0x7d, 0xec, 0xe5, 0x33, 0x66, 0x5e, 0x78, 0x31, + 0xce, 0xd1, 0x2e, 0xc8, 0xfc, 0x56, 0xd6, 0x9d, 0x90, 0xf5, 0x99, 0xaf, 0xba, 0x03, 0xd7, 0x0e, + 0x1f, 0x36, 0x49, 0x1d, 0x90, 0xd0, 0x3e, 0xc8, 0xfc, 0x7a, 0x8a, 0x40, 0x7b, 0x39, 0xfc, 0xc4, + 0xe6, 0xc2, 0x36, 0xad, 0x83, 0x4e, 0x95, 0xce, 0x41, 0x27, 0xef, 0xb5, 0x3d, 0x75, 0x1a, 0xda, + 0x9e, 0x3a, 0x31, 0xa1, 0xf1, 0x4a, 0xf7, 0x3f, 0x1f, 0xe8, 0xef, 0xbc, 0x18, 0x97, 0x68, 0xff, + 0xa6, 0x3b, 0x63, 0x32, 0x03, 0x91, 0xec, 0x84, 0xb8, 0x2f, 0x2b, 0x87, 0x37, 0x38, 0x6a, 0x87, + 0x3f, 0xee, 0xce, 0x6b, 0x38, 0xa1, 0xbb, 0xd7, 0x02, 0x8f, 0x83, 0x1a, 0xff, 0x80, 0xfa, 0x05, + 0x97, 0xa9, 0x06, 0x69, 0xd3, 0x1c, 0x4a, 0x65, 0xb8, 0x4d, 0xde, 0x0f, 0x59, 0xa3, 0xca, 0xe1, + 0x5b, 0xac, 0x76, 0xf8, 0xa0, 0x49, 0xb9, 0x49, 0x08, 0x7d, 0x50, 0x70, 0x49, 0x41, 0xda, 0x93, + 0x46, 0x88, 0x7f, 0x8d, 0xd0, 0x63, 0x5f, 0x03, 0x13, 0x42, 0xfd, 0xec, 0xd3, 0x42, 0x35, 0x06, + 0xac, 0x15, 0x50, 0x80, 0xb4, 0xc9, 0xdd, 0x90, 0x73, 0x56, 0x39, 0xbc, 0xd5, 0x57, 0x3b, 0xfc, + 0x49, 0x93, 0xb9, 0xcd, 0x45, 0xe8, 0x47, 0x33, 0x66, 0xbe, 0x59, 0xd3, 0x09, 0xe8, 0x97, 0xff, + 0xb1, 0x98, 0xa3, 0x87, 0xbe, 0xde, 0x52, 0xab, 0x0c, 0x8c, 0x61, 0x53, 0x01, 0xa1, 0xf6, 0xe4, + 0x5e, 0xa8, 0xe0, 0xf3, 0xca, 0xe1, 0x4e, 0x5e, 0x3b, 0xfc, 0xa8, 0xed, 0xf6, 0x26, 0x25, 0x34, + 0x2e, 0xb8, 0x9c, 0xb4, 0xaa, 0x6f, 0x3e, 0xfe, 0x25, 0x42, 0x8f, 0xc2, 0x17, 0x4e, 0xa7, 0x4a, + 0x5d, 0xa4, 0x20, 0xad, 0xe6, 0xd0, 0x7c, 0x08, 0xa1, 0x58, 0x9e, 0xa0, 0x10, 0x79, 0x5a, 0x39, + 0xbc, 0xcd, 0x56, 0x3b, 0x4c, 0x9a, 0xe4, 0x2d, 0x26, 0x42, 0x0f, 0x02, 0x1d, 0x2b, 0x75, 0x71, + 0xda, 0xb0, 0x09, 0xe8, 0x17, 0x8a, 0xe5, 0xf1, 0x1c, 0x1d, 0x64, 0x4a, 0x5a, 0xcd, 0x32, 0x9b, + 0xce, 0xa5, 0x99, 0x9b, 0xd2, 0x9f, 0xf7, 0x4c, 0x19, 0x9b, 0x7c, 0x10, 0x0a, 0xf8, 0xaa, 0x72, + 0x78, 0x93, 0xa5, 0x76, 0x78, 0xd0, 0x84, 0x6f, 0x30, 0x10, 0xba, 0xb7, 0x26, 0xdf, 0xaf, 0xc1, + 0xb1, 0x32, 0x61, 0x26, 0x0b, 0xb6, 0x68, 0x4e, 0x78, 0x28, 0xb3, 0xd9, 0x3b, 0xf7, 0xdb, 0x99, + 0xec, 0xc0, 0xed, 0x4c, 0x76, 0x40, 0x42, 0xfb, 0x05, 0x5b, 0x84, 0xe9, 0x98, 0x80, 0x6e, 0xf6, + 0x4c, 0x89, 0xf6, 0xbd, 0xb3, 0x64, 0x5c, 0xaf, 0x4e, 0xf8, 0xaa, 0x98, 0xe4, 0xc3, 0x76, 0x4a, + 0xba, 0x1d, 0xed, 0x94, 0x74, 0x73, 0x42, 0x7d, 0x85, 0x13, 0xaf, 0xfb, 0x19, 0x59, 0xa9, 0xf1, + 0xef, 0x11, 0xc2, 0x9d, 0x63, 0x9c, 0xe6, 0xcc, 0xb2, 0x74, 0xba, 0xb4, 0x90, 0x3c, 0x08, 0xd9, + 0xdf, 0x56, 0x0e, 0xbf, 0xcd, 0x5a, 0x3b, 0xfc, 0x74, 0xcb, 0x6a, 0x68, 0x8d, 0x84, 0x1e, 0xde, + 0x5e, 0x12, 0x27, 0xcc, 0xb2, 0xf1, 0xd2, 0xc2, 0xf3, 0xbb, 0x7f, 0xbc, 0xc2, 0xbd, 0x7f, 0x5e, + 0xe1, 0x68, 0x7c, 0xf6, 0xfa, 0x72, 0x10, 0xbd, 0xb9, 0x1c, 0x44, 0x7f, 0x5f, 0x0e, 0xa2, 0xdf, + 0xae, 0x06, 0xbd, 0x37, 0x57, 0x83, 0xde, 0x9f, 0x57, 0x83, 0xde, 0x8f, 0x47, 0xff, 0xdb, 0xf1, + 0x06, 0xf8, 0xd1, 0xfa, 0x2a, 0x0b, 0xff, 0x84, 0xbb, 0x6c, 0xb4, 0x18, 0xf9, 0x4b, 0x2f, 0xac, + 0xfb, 0xe9, 0x4e, 0xe0, 0x9f, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xff, 0x27, 0x82, 0x3c, 0x08, + 0x07, 0x00, 0x00, +} + +func (this *Params) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*Params) + if !ok { + that2, ok := that.(Params) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.PriceSnapshotRetention != that1.PriceSnapshotRetention { + return false + } + if !this.SudoCallGasPrice.Equal(that1.SudoCallGasPrice) { + return false + } + if this.BeginBlockGasLimit != that1.BeginBlockGasLimit { + return false + } + if this.EndBlockGasLimit != that1.EndBlockGasLimit { + return false + } + if this.DefaultGasPerOrder != that1.DefaultGasPerOrder { + return false + } + if this.DefaultGasPerCancel != that1.DefaultGasPerCancel { + return false + } + if this.MinRentDeposit != that1.MinRentDeposit { + return false + } + if this.GasAllowancePerSettlement != that1.GasAllowancePerSettlement { + return false + } + if this.MinProcessableRent != that1.MinProcessableRent { + return false + } + if this.OrderBookEntriesPerLoad != that1.OrderBookEntriesPerLoad { + return false + } + if this.ContractUnsuspendCost != that1.ContractUnsuspendCost { + return false + } + if this.MaxOrderPerPrice != that1.MaxOrderPerPrice { + return false + } + if this.MaxPairsPerContract != that1.MaxPairsPerContract { + return false + } + if this.DefaultGasPerOrderDataByte != that1.DefaultGasPerOrderDataByte { + return false + } + return true +} +func (m *Params) 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 *Params) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.DefaultGasPerOrderDataByte != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.DefaultGasPerOrderDataByte)) + i-- + dAtA[i] = 0x70 + } + if m.MaxPairsPerContract != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.MaxPairsPerContract)) + i-- + dAtA[i] = 0x68 + } + if m.MaxOrderPerPrice != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.MaxOrderPerPrice)) + i-- + dAtA[i] = 0x60 + } + if m.ContractUnsuspendCost != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.ContractUnsuspendCost)) + i-- + dAtA[i] = 0x58 + } + if m.OrderBookEntriesPerLoad != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.OrderBookEntriesPerLoad)) + i-- + dAtA[i] = 0x50 + } + if m.MinProcessableRent != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.MinProcessableRent)) + i-- + dAtA[i] = 0x48 + } + if m.GasAllowancePerSettlement != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.GasAllowancePerSettlement)) + i-- + dAtA[i] = 0x40 + } + if m.MinRentDeposit != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.MinRentDeposit)) + i-- + dAtA[i] = 0x38 + } + if m.DefaultGasPerCancel != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.DefaultGasPerCancel)) + i-- + dAtA[i] = 0x30 + } + if m.DefaultGasPerOrder != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.DefaultGasPerOrder)) + i-- + dAtA[i] = 0x28 + } + if m.EndBlockGasLimit != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.EndBlockGasLimit)) + i-- + dAtA[i] = 0x20 + } + if m.BeginBlockGasLimit != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.BeginBlockGasLimit)) + i-- + dAtA[i] = 0x18 + } + { + size := m.SudoCallGasPrice.Size() + i -= size + if _, err := m.SudoCallGasPrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintParams(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.PriceSnapshotRetention != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.PriceSnapshotRetention)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintParams(dAtA []byte, offset int, v uint64) int { + offset -= sovParams(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Params) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.PriceSnapshotRetention != 0 { + n += 1 + sovParams(uint64(m.PriceSnapshotRetention)) + } + l = m.SudoCallGasPrice.Size() + n += 1 + l + sovParams(uint64(l)) + if m.BeginBlockGasLimit != 0 { + n += 1 + sovParams(uint64(m.BeginBlockGasLimit)) + } + if m.EndBlockGasLimit != 0 { + n += 1 + sovParams(uint64(m.EndBlockGasLimit)) + } + if m.DefaultGasPerOrder != 0 { + n += 1 + sovParams(uint64(m.DefaultGasPerOrder)) + } + if m.DefaultGasPerCancel != 0 { + n += 1 + sovParams(uint64(m.DefaultGasPerCancel)) + } + if m.MinRentDeposit != 0 { + n += 1 + sovParams(uint64(m.MinRentDeposit)) + } + if m.GasAllowancePerSettlement != 0 { + n += 1 + sovParams(uint64(m.GasAllowancePerSettlement)) + } + if m.MinProcessableRent != 0 { + n += 1 + sovParams(uint64(m.MinProcessableRent)) + } + if m.OrderBookEntriesPerLoad != 0 { + n += 1 + sovParams(uint64(m.OrderBookEntriesPerLoad)) + } + if m.ContractUnsuspendCost != 0 { + n += 1 + sovParams(uint64(m.ContractUnsuspendCost)) + } + if m.MaxOrderPerPrice != 0 { + n += 1 + sovParams(uint64(m.MaxOrderPerPrice)) + } + if m.MaxPairsPerContract != 0 { + n += 1 + sovParams(uint64(m.MaxPairsPerContract)) + } + if m.DefaultGasPerOrderDataByte != 0 { + n += 1 + sovParams(uint64(m.DefaultGasPerOrderDataByte)) + } + return n +} + +func sovParams(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozParams(x uint64) (n int) { + return sovParams(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Params) 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 ErrIntOverflowParams + } + 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: Params: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Params: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PriceSnapshotRetention", wireType) + } + m.PriceSnapshotRetention = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PriceSnapshotRetention |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SudoCallGasPrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + 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 ErrInvalidLengthParams + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthParams + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.SudoCallGasPrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BeginBlockGasLimit", wireType) + } + m.BeginBlockGasLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BeginBlockGasLimit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EndBlockGasLimit", wireType) + } + m.EndBlockGasLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EndBlockGasLimit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultGasPerOrder", wireType) + } + m.DefaultGasPerOrder = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DefaultGasPerOrder |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultGasPerCancel", wireType) + } + m.DefaultGasPerCancel = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DefaultGasPerCancel |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinRentDeposit", wireType) + } + m.MinRentDeposit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinRentDeposit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field GasAllowancePerSettlement", wireType) + } + m.GasAllowancePerSettlement = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.GasAllowancePerSettlement |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MinProcessableRent", wireType) + } + m.MinProcessableRent = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MinProcessableRent |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OrderBookEntriesPerLoad", wireType) + } + m.OrderBookEntriesPerLoad = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OrderBookEntriesPerLoad |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractUnsuspendCost", wireType) + } + m.ContractUnsuspendCost = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ContractUnsuspendCost |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxOrderPerPrice", wireType) + } + m.MaxOrderPerPrice = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxOrderPerPrice |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MaxPairsPerContract", wireType) + } + m.MaxPairsPerContract = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MaxPairsPerContract |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DefaultGasPerOrderDataByte", wireType) + } + m.DefaultGasPerOrderDataByte = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DefaultGasPerOrderDataByte |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipParams(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthParams + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipParams(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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrIntOverflowParams + } + 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, ErrInvalidLengthParams + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupParams + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthParams + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthParams = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowParams = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupParams = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/params_test.go b/x/dex/types/params_test.go new file mode 100644 index 000000000..efd19a5cf --- /dev/null +++ b/x/dex/types/params_test.go @@ -0,0 +1,17 @@ +package types_test + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/sei-protocol/sei-chain/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestParamsValidate(t *testing.T) { + p := types.Params{PriceSnapshotRetention: 0} + require.Error(t, p.Validate()) + + p = types.Params{SudoCallGasPrice: sdk.ZeroDec()} + require.Error(t, p.Validate()) +} diff --git a/x/dex/types/price.pb.go b/x/dex/types/price.pb.go new file mode 100644 index 000000000..b85e68649 --- /dev/null +++ b/x/dex/types/price.pb.go @@ -0,0 +1,881 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/price.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 Price struct { + SnapshotTimestampInSeconds uint64 `protobuf:"varint,1,opt,name=snapshotTimestampInSeconds,proto3" json:"snapshot_timestamp_in_seconds"` + Price github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=price,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price" yaml:"price"` + Pair *Pair `protobuf:"bytes,3,opt,name=pair,proto3" json:"pair"` +} + +func (m *Price) Reset() { *m = Price{} } +func (m *Price) String() string { return proto.CompactTextString(m) } +func (*Price) ProtoMessage() {} +func (*Price) Descriptor() ([]byte, []int) { + return fileDescriptor_bd5d1c9d490efb8c, []int{0} +} +func (m *Price) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Price) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Price.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 *Price) XXX_Merge(src proto.Message) { + xxx_messageInfo_Price.Merge(m, src) +} +func (m *Price) XXX_Size() int { + return m.Size() +} +func (m *Price) XXX_DiscardUnknown() { + xxx_messageInfo_Price.DiscardUnknown(m) +} + +var xxx_messageInfo_Price proto.InternalMessageInfo + +func (m *Price) GetSnapshotTimestampInSeconds() uint64 { + if m != nil { + return m.SnapshotTimestampInSeconds + } + return 0 +} + +func (m *Price) GetPair() *Pair { + if m != nil { + return m.Pair + } + return nil +} + +type PriceCandlestick struct { + BeginTimestamp uint64 `protobuf:"varint,1,opt,name=beginTimestamp,proto3" json:"begin_timestamp"` + EndTimestamp uint64 `protobuf:"varint,2,opt,name=endTimestamp,proto3" json:"end_timestamp"` + Open *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=open,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"open"` + High *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=high,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"high"` + Low *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=low,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"low"` + Close *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,6,opt,name=close,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"close"` + Volume *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,7,opt,name=volume,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"volume"` +} + +func (m *PriceCandlestick) Reset() { *m = PriceCandlestick{} } +func (m *PriceCandlestick) String() string { return proto.CompactTextString(m) } +func (*PriceCandlestick) ProtoMessage() {} +func (*PriceCandlestick) Descriptor() ([]byte, []int) { + return fileDescriptor_bd5d1c9d490efb8c, []int{1} +} +func (m *PriceCandlestick) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PriceCandlestick) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PriceCandlestick.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 *PriceCandlestick) XXX_Merge(src proto.Message) { + xxx_messageInfo_PriceCandlestick.Merge(m, src) +} +func (m *PriceCandlestick) XXX_Size() int { + return m.Size() +} +func (m *PriceCandlestick) XXX_DiscardUnknown() { + xxx_messageInfo_PriceCandlestick.DiscardUnknown(m) +} + +var xxx_messageInfo_PriceCandlestick proto.InternalMessageInfo + +func (m *PriceCandlestick) GetBeginTimestamp() uint64 { + if m != nil { + return m.BeginTimestamp + } + return 0 +} + +func (m *PriceCandlestick) GetEndTimestamp() uint64 { + if m != nil { + return m.EndTimestamp + } + return 0 +} + +func init() { + proto.RegisterType((*Price)(nil), "seiprotocol.seichain.dex.Price") + proto.RegisterType((*PriceCandlestick)(nil), "seiprotocol.seichain.dex.PriceCandlestick") +} + +func init() { proto.RegisterFile("dex/price.proto", fileDescriptor_bd5d1c9d490efb8c) } + +var fileDescriptor_bd5d1c9d490efb8c = []byte{ + // 466 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x93, 0xcf, 0x6e, 0xd3, 0x40, + 0x10, 0xc6, 0xe3, 0xfc, 0x83, 0x2e, 0xa5, 0x85, 0x85, 0x83, 0x15, 0x09, 0x3b, 0xe4, 0x80, 0x72, + 0x89, 0x2d, 0x5a, 0xb8, 0x00, 0x27, 0x17, 0x51, 0x55, 0xe2, 0x50, 0x2d, 0x9c, 0x90, 0x50, 0xe4, + 0xac, 0x47, 0xf6, 0xaa, 0xf6, 0xae, 0x95, 0x75, 0x21, 0x7d, 0x02, 0xae, 0x3c, 0x56, 0x8f, 0x3d, + 0x22, 0x0e, 0x16, 0x4a, 0x6e, 0x3e, 0x22, 0x1e, 0x00, 0xed, 0x38, 0xa1, 0x01, 0x09, 0x24, 0x73, + 0x99, 0xd9, 0xf1, 0x7c, 0xdf, 0x4f, 0x9e, 0xf1, 0x9a, 0xec, 0x47, 0xb0, 0xf0, 0xf3, 0xb9, 0xe0, + 0xe0, 0xe5, 0x73, 0x55, 0x28, 0x6a, 0x6b, 0x10, 0x78, 0xe2, 0x2a, 0xf5, 0x34, 0x08, 0x9e, 0x84, + 0x42, 0x7a, 0x11, 0x2c, 0x06, 0xf7, 0x63, 0x15, 0x2b, 0x6c, 0xf9, 0xe6, 0x54, 0xeb, 0x07, 0x7b, + 0x08, 0x08, 0xc5, 0xbc, 0xae, 0x47, 0x9f, 0xda, 0xa4, 0x77, 0x6a, 0x78, 0x34, 0x24, 0x03, 0x2d, + 0xc3, 0x5c, 0x27, 0xaa, 0x78, 0x2b, 0x32, 0xd0, 0x45, 0x98, 0xe5, 0x27, 0xf2, 0x0d, 0x70, 0x25, + 0x23, 0x6d, 0x5b, 0x43, 0x6b, 0xdc, 0x0d, 0x1e, 0x56, 0xa5, 0xfb, 0x60, 0xa3, 0x9a, 0x16, 0x1b, + 0xd9, 0x54, 0xc8, 0xa9, 0xae, 0x85, 0xec, 0x1f, 0x10, 0xfa, 0x9e, 0xf4, 0xf0, 0xdd, 0xed, 0xf6, + 0xd0, 0x1a, 0xef, 0x04, 0xc7, 0x97, 0xa5, 0xdb, 0xfa, 0x5a, 0xba, 0x8f, 0x62, 0x51, 0x24, 0xe7, + 0x33, 0x8f, 0xab, 0xcc, 0xe7, 0x4a, 0x67, 0x4a, 0xaf, 0xd3, 0x44, 0x47, 0x67, 0x7e, 0x71, 0x91, + 0x83, 0xf6, 0x5e, 0x02, 0xaf, 0x4a, 0xb7, 0xb6, 0x7f, 0x2f, 0xdd, 0xdd, 0x8b, 0x30, 0x4b, 0x9f, + 0x8d, 0xb0, 0x1c, 0xb1, 0xfa, 0x31, 0x7d, 0x41, 0xba, 0x66, 0x32, 0xbb, 0x33, 0xb4, 0xc6, 0xb7, + 0x0e, 0x1c, 0xef, 0x6f, 0xab, 0xf1, 0x4e, 0x43, 0x31, 0x0f, 0x6e, 0x56, 0xa5, 0x8b, 0x7a, 0x86, + 0x71, 0xf4, 0xa3, 0x43, 0xee, 0xe0, 0x26, 0x8e, 0x42, 0x19, 0xa5, 0xa0, 0x0b, 0xc1, 0xcf, 0xe8, + 0x73, 0xb2, 0x37, 0x83, 0x58, 0xc8, 0x5f, 0xc3, 0xac, 0x17, 0x71, 0xaf, 0x2a, 0xdd, 0x7d, 0xec, + 0x5c, 0x6f, 0x81, 0xfd, 0x21, 0xa5, 0x4f, 0xc9, 0x2e, 0xc8, 0xe8, 0xda, 0xda, 0x46, 0xeb, 0xdd, + 0xaa, 0x74, 0x6f, 0x83, 0x8c, 0xb6, 0x8c, 0xbf, 0xc9, 0xe8, 0x2b, 0xd2, 0x55, 0x39, 0x48, 0x1c, + 0x63, 0x27, 0x38, 0x68, 0xb4, 0x20, 0x74, 0x32, 0x8c, 0x86, 0x93, 0x88, 0x38, 0xb1, 0xbb, 0xff, + 0xc3, 0x31, 0x4e, 0x86, 0x91, 0x1e, 0x91, 0x4e, 0xaa, 0x3e, 0xda, 0x3d, 0xc4, 0x3c, 0x6e, 0x84, + 0x31, 0x46, 0x66, 0x02, 0x3d, 0x21, 0x3d, 0x9e, 0x2a, 0x0d, 0x76, 0x1f, 0x31, 0x87, 0xcd, 0x3e, + 0x3b, 0x5a, 0x59, 0x9d, 0xe8, 0x6b, 0xd2, 0xff, 0xa0, 0xd2, 0xf3, 0x0c, 0xec, 0x1b, 0xc8, 0x7a, + 0xd2, 0x88, 0xb5, 0xf6, 0xb2, 0x75, 0x0e, 0x8e, 0x2f, 0x97, 0x8e, 0x75, 0xb5, 0x74, 0xac, 0x6f, + 0x4b, 0xc7, 0xfa, 0xbc, 0x72, 0x5a, 0x57, 0x2b, 0xa7, 0xf5, 0x65, 0xe5, 0xb4, 0xde, 0x4d, 0xb6, + 0x98, 0x1a, 0xc4, 0x64, 0x73, 0x97, 0xb0, 0xc0, 0xcb, 0xe4, 0x2f, 0x7c, 0xf3, 0x3b, 0x21, 0x7e, + 0xd6, 0xc7, 0xfe, 0xe1, 0xcf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xa8, 0xe7, 0x11, 0xeb, 0xa3, 0x03, + 0x00, 0x00, +} + +func (m *Price) 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 *Price) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Price) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pair != nil { + { + size, err := m.Pair.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPrice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + { + size := m.Price.Size() + i -= size + if _, err := m.Price.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPrice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.SnapshotTimestampInSeconds != 0 { + i = encodeVarintPrice(dAtA, i, uint64(m.SnapshotTimestampInSeconds)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *PriceCandlestick) 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 *PriceCandlestick) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PriceCandlestick) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Volume != nil { + { + size := m.Volume.Size() + i -= size + if _, err := m.Volume.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPrice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + if m.Close != nil { + { + size := m.Close.Size() + i -= size + if _, err := m.Close.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPrice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if m.Low != nil { + { + size := m.Low.Size() + i -= size + if _, err := m.Low.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPrice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.High != nil { + { + size := m.High.Size() + i -= size + if _, err := m.High.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPrice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.Open != nil { + { + size := m.Open.Size() + i -= size + if _, err := m.Open.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintPrice(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.EndTimestamp != 0 { + i = encodeVarintPrice(dAtA, i, uint64(m.EndTimestamp)) + i-- + dAtA[i] = 0x10 + } + if m.BeginTimestamp != 0 { + i = encodeVarintPrice(dAtA, i, uint64(m.BeginTimestamp)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintPrice(dAtA []byte, offset int, v uint64) int { + offset -= sovPrice(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Price) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.SnapshotTimestampInSeconds != 0 { + n += 1 + sovPrice(uint64(m.SnapshotTimestampInSeconds)) + } + l = m.Price.Size() + n += 1 + l + sovPrice(uint64(l)) + if m.Pair != nil { + l = m.Pair.Size() + n += 1 + l + sovPrice(uint64(l)) + } + return n +} + +func (m *PriceCandlestick) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.BeginTimestamp != 0 { + n += 1 + sovPrice(uint64(m.BeginTimestamp)) + } + if m.EndTimestamp != 0 { + n += 1 + sovPrice(uint64(m.EndTimestamp)) + } + if m.Open != nil { + l = m.Open.Size() + n += 1 + l + sovPrice(uint64(l)) + } + if m.High != nil { + l = m.High.Size() + n += 1 + l + sovPrice(uint64(l)) + } + if m.Low != nil { + l = m.Low.Size() + n += 1 + l + sovPrice(uint64(l)) + } + if m.Close != nil { + l = m.Close.Size() + n += 1 + l + sovPrice(uint64(l)) + } + if m.Volume != nil { + l = m.Volume.Size() + n += 1 + l + sovPrice(uint64(l)) + } + return n +} + +func sovPrice(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozPrice(x uint64) (n int) { + return sovPrice(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Price) 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 ErrIntOverflowPrice + } + 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: Price: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Price: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SnapshotTimestampInSeconds", wireType) + } + m.SnapshotTimestampInSeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SnapshotTimestampInSeconds |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + 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 ErrInvalidLengthPrice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPrice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pair", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPrice + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPrice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pair == nil { + m.Pair = &Pair{} + } + if err := m.Pair.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPrice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPrice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PriceCandlestick) 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 ErrIntOverflowPrice + } + 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: PriceCandlestick: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PriceCandlestick: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field BeginTimestamp", wireType) + } + m.BeginTimestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.BeginTimestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EndTimestamp", wireType) + } + m.EndTimestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.EndTimestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Open", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + 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 ErrInvalidLengthPrice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPrice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.Open = &v + if err := m.Open.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field High", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + 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 ErrInvalidLengthPrice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPrice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.High = &v + if err := m.High.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Low", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + 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 ErrInvalidLengthPrice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPrice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.Low = &v + if err := m.Low.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Close", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + 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 ErrInvalidLengthPrice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPrice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.Close = &v + if err := m.Close.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Volume", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPrice + } + 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 ErrInvalidLengthPrice + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPrice + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.Volume = &v + if err := m.Volume.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPrice(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthPrice + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipPrice(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, ErrIntOverflowPrice + } + 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, ErrIntOverflowPrice + } + 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, ErrIntOverflowPrice + } + 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, ErrInvalidLengthPrice + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupPrice + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthPrice + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthPrice = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowPrice = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupPrice = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/query.pb.go b/x/dex/types/query.pb.go new file mode 100644 index 000000000..931520f80 --- /dev/null +++ b/x/dex/types/query.pb.go @@ -0,0 +1,10031 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/query.proto + +package types + +import ( + context "context" + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + query "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + 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 + +// QueryParamsRequest is request type for the Query/Params RPC method. +type QueryParamsRequest struct { +} + +func (m *QueryParamsRequest) Reset() { *m = QueryParamsRequest{} } +func (m *QueryParamsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryParamsRequest) ProtoMessage() {} +func (*QueryParamsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{0} +} +func (m *QueryParamsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsRequest.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 *QueryParamsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsRequest.Merge(m, src) +} +func (m *QueryParamsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsRequest proto.InternalMessageInfo + +// QueryParamsResponse is response type for the Query/Params RPC method. +type QueryParamsResponse struct { + // params holds all the parameters of this module. + Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"` +} + +func (m *QueryParamsResponse) Reset() { *m = QueryParamsResponse{} } +func (m *QueryParamsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryParamsResponse) ProtoMessage() {} +func (*QueryParamsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{1} +} +func (m *QueryParamsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryParamsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryParamsResponse.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 *QueryParamsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryParamsResponse.Merge(m, src) +} +func (m *QueryParamsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryParamsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryParamsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryParamsResponse proto.InternalMessageInfo + +func (m *QueryParamsResponse) GetParams() Params { + if m != nil { + return m.Params + } + return Params{} +} + +type QueryGetLongBookRequest struct { + Price string `protobuf:"bytes,1,opt,name=price,proto3" json:"price,omitempty"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"` + PriceDenom string `protobuf:"bytes,3,opt,name=priceDenom,proto3" json:"priceDenom,omitempty"` + AssetDenom string `protobuf:"bytes,4,opt,name=assetDenom,proto3" json:"assetDenom,omitempty"` +} + +func (m *QueryGetLongBookRequest) Reset() { *m = QueryGetLongBookRequest{} } +func (m *QueryGetLongBookRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetLongBookRequest) ProtoMessage() {} +func (*QueryGetLongBookRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{2} +} +func (m *QueryGetLongBookRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetLongBookRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetLongBookRequest.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 *QueryGetLongBookRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetLongBookRequest.Merge(m, src) +} +func (m *QueryGetLongBookRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetLongBookRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetLongBookRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetLongBookRequest proto.InternalMessageInfo + +func (m *QueryGetLongBookRequest) GetPrice() string { + if m != nil { + return m.Price + } + return "" +} + +func (m *QueryGetLongBookRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryGetLongBookRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryGetLongBookRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +type QueryGetLongBookResponse struct { + LongBook LongBook `protobuf:"bytes,1,opt,name=LongBook,proto3" json:"LongBook"` +} + +func (m *QueryGetLongBookResponse) Reset() { *m = QueryGetLongBookResponse{} } +func (m *QueryGetLongBookResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetLongBookResponse) ProtoMessage() {} +func (*QueryGetLongBookResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{3} +} +func (m *QueryGetLongBookResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetLongBookResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetLongBookResponse.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 *QueryGetLongBookResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetLongBookResponse.Merge(m, src) +} +func (m *QueryGetLongBookResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetLongBookResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetLongBookResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetLongBookResponse proto.InternalMessageInfo + +func (m *QueryGetLongBookResponse) GetLongBook() LongBook { + if m != nil { + return m.LongBook + } + return LongBook{} +} + +type QueryAllLongBookRequest struct { + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"` + PriceDenom string `protobuf:"bytes,3,opt,name=priceDenom,proto3" json:"priceDenom,omitempty"` + AssetDenom string `protobuf:"bytes,4,opt,name=assetDenom,proto3" json:"assetDenom,omitempty"` +} + +func (m *QueryAllLongBookRequest) Reset() { *m = QueryAllLongBookRequest{} } +func (m *QueryAllLongBookRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAllLongBookRequest) ProtoMessage() {} +func (*QueryAllLongBookRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{4} +} +func (m *QueryAllLongBookRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllLongBookRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllLongBookRequest.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 *QueryAllLongBookRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllLongBookRequest.Merge(m, src) +} +func (m *QueryAllLongBookRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAllLongBookRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllLongBookRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllLongBookRequest proto.InternalMessageInfo + +func (m *QueryAllLongBookRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +func (m *QueryAllLongBookRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryAllLongBookRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryAllLongBookRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +type QueryAllLongBookResponse struct { + LongBook []LongBook `protobuf:"bytes,1,rep,name=LongBook,proto3" json:"LongBook"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryAllLongBookResponse) Reset() { *m = QueryAllLongBookResponse{} } +func (m *QueryAllLongBookResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAllLongBookResponse) ProtoMessage() {} +func (*QueryAllLongBookResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{5} +} +func (m *QueryAllLongBookResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllLongBookResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllLongBookResponse.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 *QueryAllLongBookResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllLongBookResponse.Merge(m, src) +} +func (m *QueryAllLongBookResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAllLongBookResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllLongBookResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllLongBookResponse proto.InternalMessageInfo + +func (m *QueryAllLongBookResponse) GetLongBook() []LongBook { + if m != nil { + return m.LongBook + } + return nil +} + +func (m *QueryAllLongBookResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +type QueryGetShortBookRequest struct { + Price string `protobuf:"bytes,1,opt,name=price,proto3" json:"price,omitempty"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"` + PriceDenom string `protobuf:"bytes,3,opt,name=priceDenom,proto3" json:"priceDenom,omitempty"` + AssetDenom string `protobuf:"bytes,4,opt,name=assetDenom,proto3" json:"assetDenom,omitempty"` +} + +func (m *QueryGetShortBookRequest) Reset() { *m = QueryGetShortBookRequest{} } +func (m *QueryGetShortBookRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetShortBookRequest) ProtoMessage() {} +func (*QueryGetShortBookRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{6} +} +func (m *QueryGetShortBookRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetShortBookRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetShortBookRequest.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 *QueryGetShortBookRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetShortBookRequest.Merge(m, src) +} +func (m *QueryGetShortBookRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetShortBookRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetShortBookRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetShortBookRequest proto.InternalMessageInfo + +func (m *QueryGetShortBookRequest) GetPrice() string { + if m != nil { + return m.Price + } + return "" +} + +func (m *QueryGetShortBookRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryGetShortBookRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryGetShortBookRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +type QueryGetShortBookResponse struct { + ShortBook ShortBook `protobuf:"bytes,1,opt,name=ShortBook,proto3" json:"ShortBook"` +} + +func (m *QueryGetShortBookResponse) Reset() { *m = QueryGetShortBookResponse{} } +func (m *QueryGetShortBookResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetShortBookResponse) ProtoMessage() {} +func (*QueryGetShortBookResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{7} +} +func (m *QueryGetShortBookResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetShortBookResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetShortBookResponse.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 *QueryGetShortBookResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetShortBookResponse.Merge(m, src) +} +func (m *QueryGetShortBookResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetShortBookResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetShortBookResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetShortBookResponse proto.InternalMessageInfo + +func (m *QueryGetShortBookResponse) GetShortBook() ShortBook { + if m != nil { + return m.ShortBook + } + return ShortBook{} +} + +type QueryAllShortBookRequest struct { + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"` + PriceDenom string `protobuf:"bytes,3,opt,name=priceDenom,proto3" json:"priceDenom,omitempty"` + AssetDenom string `protobuf:"bytes,4,opt,name=assetDenom,proto3" json:"assetDenom,omitempty"` +} + +func (m *QueryAllShortBookRequest) Reset() { *m = QueryAllShortBookRequest{} } +func (m *QueryAllShortBookRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAllShortBookRequest) ProtoMessage() {} +func (*QueryAllShortBookRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{8} +} +func (m *QueryAllShortBookRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllShortBookRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllShortBookRequest.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 *QueryAllShortBookRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllShortBookRequest.Merge(m, src) +} +func (m *QueryAllShortBookRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAllShortBookRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllShortBookRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllShortBookRequest proto.InternalMessageInfo + +func (m *QueryAllShortBookRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +func (m *QueryAllShortBookRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryAllShortBookRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryAllShortBookRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +type QueryAllShortBookResponse struct { + ShortBook []ShortBook `protobuf:"bytes,1,rep,name=ShortBook,proto3" json:"ShortBook"` + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryAllShortBookResponse) Reset() { *m = QueryAllShortBookResponse{} } +func (m *QueryAllShortBookResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAllShortBookResponse) ProtoMessage() {} +func (*QueryAllShortBookResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{9} +} +func (m *QueryAllShortBookResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAllShortBookResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAllShortBookResponse.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 *QueryAllShortBookResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAllShortBookResponse.Merge(m, src) +} +func (m *QueryAllShortBookResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAllShortBookResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAllShortBookResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAllShortBookResponse proto.InternalMessageInfo + +func (m *QueryAllShortBookResponse) GetShortBook() []ShortBook { + if m != nil { + return m.ShortBook + } + return nil +} + +func (m *QueryAllShortBookResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +type QueryGetPricesRequest struct { + PriceDenom string `protobuf:"bytes,1,opt,name=priceDenom,proto3" json:"priceDenom,omitempty"` + AssetDenom string `protobuf:"bytes,2,opt,name=assetDenom,proto3" json:"assetDenom,omitempty"` + ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"` +} + +func (m *QueryGetPricesRequest) Reset() { *m = QueryGetPricesRequest{} } +func (m *QueryGetPricesRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetPricesRequest) ProtoMessage() {} +func (*QueryGetPricesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{10} +} +func (m *QueryGetPricesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetPricesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetPricesRequest.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 *QueryGetPricesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetPricesRequest.Merge(m, src) +} +func (m *QueryGetPricesRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetPricesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetPricesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetPricesRequest proto.InternalMessageInfo + +func (m *QueryGetPricesRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryGetPricesRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *QueryGetPricesRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +type QueryGetPricesResponse struct { + Prices []*Price `protobuf:"bytes,1,rep,name=prices,proto3" json:"prices,omitempty"` +} + +func (m *QueryGetPricesResponse) Reset() { *m = QueryGetPricesResponse{} } +func (m *QueryGetPricesResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetPricesResponse) ProtoMessage() {} +func (*QueryGetPricesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{11} +} +func (m *QueryGetPricesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetPricesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetPricesResponse.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 *QueryGetPricesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetPricesResponse.Merge(m, src) +} +func (m *QueryGetPricesResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetPricesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetPricesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetPricesResponse proto.InternalMessageInfo + +func (m *QueryGetPricesResponse) GetPrices() []*Price { + if m != nil { + return m.Prices + } + return nil +} + +type QueryGetPriceRequest struct { + PriceDenom string `protobuf:"bytes,1,opt,name=priceDenom,proto3" json:"priceDenom,omitempty"` + AssetDenom string `protobuf:"bytes,2,opt,name=assetDenom,proto3" json:"assetDenom,omitempty"` + ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr,proto3" json:"contractAddr,omitempty"` + Timestamp uint64 `protobuf:"varint,4,opt,name=timestamp,proto3" json:"timestamp,omitempty"` +} + +func (m *QueryGetPriceRequest) Reset() { *m = QueryGetPriceRequest{} } +func (m *QueryGetPriceRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetPriceRequest) ProtoMessage() {} +func (*QueryGetPriceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{12} +} +func (m *QueryGetPriceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetPriceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetPriceRequest.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 *QueryGetPriceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetPriceRequest.Merge(m, src) +} +func (m *QueryGetPriceRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetPriceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetPriceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetPriceRequest proto.InternalMessageInfo + +func (m *QueryGetPriceRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryGetPriceRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *QueryGetPriceRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryGetPriceRequest) GetTimestamp() uint64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +type QueryGetPriceResponse struct { + Price *Price `protobuf:"bytes,1,opt,name=price,proto3" json:"price,omitempty"` + Found bool `protobuf:"varint,2,opt,name=found,proto3" json:"found,omitempty"` +} + +func (m *QueryGetPriceResponse) Reset() { *m = QueryGetPriceResponse{} } +func (m *QueryGetPriceResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetPriceResponse) ProtoMessage() {} +func (*QueryGetPriceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{13} +} +func (m *QueryGetPriceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetPriceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetPriceResponse.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 *QueryGetPriceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetPriceResponse.Merge(m, src) +} +func (m *QueryGetPriceResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetPriceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetPriceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetPriceResponse proto.InternalMessageInfo + +func (m *QueryGetPriceResponse) GetPrice() *Price { + if m != nil { + return m.Price + } + return nil +} + +func (m *QueryGetPriceResponse) GetFound() bool { + if m != nil { + return m.Found + } + return false +} + +type QueryGetLatestPriceRequest struct { + PriceDenom string `protobuf:"bytes,1,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,2,opt,name=assetDenom,proto3" json:"asset_denom"` + ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr,proto3" json:"contract_address"` +} + +func (m *QueryGetLatestPriceRequest) Reset() { *m = QueryGetLatestPriceRequest{} } +func (m *QueryGetLatestPriceRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetLatestPriceRequest) ProtoMessage() {} +func (*QueryGetLatestPriceRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{14} +} +func (m *QueryGetLatestPriceRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetLatestPriceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetLatestPriceRequest.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 *QueryGetLatestPriceRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetLatestPriceRequest.Merge(m, src) +} +func (m *QueryGetLatestPriceRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetLatestPriceRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetLatestPriceRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetLatestPriceRequest proto.InternalMessageInfo + +func (m *QueryGetLatestPriceRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryGetLatestPriceRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *QueryGetLatestPriceRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +type QueryGetLatestPriceResponse struct { + Price *Price `protobuf:"bytes,1,opt,name=price,proto3" json:"price,omitempty"` +} + +func (m *QueryGetLatestPriceResponse) Reset() { *m = QueryGetLatestPriceResponse{} } +func (m *QueryGetLatestPriceResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetLatestPriceResponse) ProtoMessage() {} +func (*QueryGetLatestPriceResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{15} +} +func (m *QueryGetLatestPriceResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetLatestPriceResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetLatestPriceResponse.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 *QueryGetLatestPriceResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetLatestPriceResponse.Merge(m, src) +} +func (m *QueryGetLatestPriceResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetLatestPriceResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetLatestPriceResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetLatestPriceResponse proto.InternalMessageInfo + +func (m *QueryGetLatestPriceResponse) GetPrice() *Price { + if m != nil { + return m.Price + } + return nil +} + +type QueryGetTwapsRequest struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` + LookbackSeconds uint64 `protobuf:"varint,2,opt,name=lookbackSeconds,proto3" json:"lookback_seconds"` +} + +func (m *QueryGetTwapsRequest) Reset() { *m = QueryGetTwapsRequest{} } +func (m *QueryGetTwapsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetTwapsRequest) ProtoMessage() {} +func (*QueryGetTwapsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{16} +} +func (m *QueryGetTwapsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetTwapsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetTwapsRequest.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 *QueryGetTwapsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetTwapsRequest.Merge(m, src) +} +func (m *QueryGetTwapsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetTwapsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetTwapsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetTwapsRequest proto.InternalMessageInfo + +func (m *QueryGetTwapsRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryGetTwapsRequest) GetLookbackSeconds() uint64 { + if m != nil { + return m.LookbackSeconds + } + return 0 +} + +type QueryGetTwapsResponse struct { + Twaps []*Twap `protobuf:"bytes,1,rep,name=twaps,proto3" json:"twaps"` +} + +func (m *QueryGetTwapsResponse) Reset() { *m = QueryGetTwapsResponse{} } +func (m *QueryGetTwapsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetTwapsResponse) ProtoMessage() {} +func (*QueryGetTwapsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{17} +} +func (m *QueryGetTwapsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetTwapsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetTwapsResponse.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 *QueryGetTwapsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetTwapsResponse.Merge(m, src) +} +func (m *QueryGetTwapsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetTwapsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetTwapsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetTwapsResponse proto.InternalMessageInfo + +func (m *QueryGetTwapsResponse) GetTwaps() []*Twap { + if m != nil { + return m.Twaps + } + return nil +} + +type QueryAssetListRequest struct { +} + +func (m *QueryAssetListRequest) Reset() { *m = QueryAssetListRequest{} } +func (m *QueryAssetListRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAssetListRequest) ProtoMessage() {} +func (*QueryAssetListRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{18} +} +func (m *QueryAssetListRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAssetListRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAssetListRequest.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 *QueryAssetListRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAssetListRequest.Merge(m, src) +} +func (m *QueryAssetListRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAssetListRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAssetListRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAssetListRequest proto.InternalMessageInfo + +type QueryAssetListResponse struct { + AssetList []AssetMetadata `protobuf:"bytes,1,rep,name=assetList,proto3" json:"assetList"` +} + +func (m *QueryAssetListResponse) Reset() { *m = QueryAssetListResponse{} } +func (m *QueryAssetListResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAssetListResponse) ProtoMessage() {} +func (*QueryAssetListResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{19} +} +func (m *QueryAssetListResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAssetListResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAssetListResponse.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 *QueryAssetListResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAssetListResponse.Merge(m, src) +} +func (m *QueryAssetListResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAssetListResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAssetListResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAssetListResponse proto.InternalMessageInfo + +func (m *QueryAssetListResponse) GetAssetList() []AssetMetadata { + if m != nil { + return m.AssetList + } + return nil +} + +type QueryAssetMetadataRequest struct { + Denom string `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` +} + +func (m *QueryAssetMetadataRequest) Reset() { *m = QueryAssetMetadataRequest{} } +func (m *QueryAssetMetadataRequest) String() string { return proto.CompactTextString(m) } +func (*QueryAssetMetadataRequest) ProtoMessage() {} +func (*QueryAssetMetadataRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{20} +} +func (m *QueryAssetMetadataRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAssetMetadataRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAssetMetadataRequest.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 *QueryAssetMetadataRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAssetMetadataRequest.Merge(m, src) +} +func (m *QueryAssetMetadataRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryAssetMetadataRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAssetMetadataRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAssetMetadataRequest proto.InternalMessageInfo + +func (m *QueryAssetMetadataRequest) GetDenom() string { + if m != nil { + return m.Denom + } + return "" +} + +type QueryAssetMetadataResponse struct { + Metadata *AssetMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` +} + +func (m *QueryAssetMetadataResponse) Reset() { *m = QueryAssetMetadataResponse{} } +func (m *QueryAssetMetadataResponse) String() string { return proto.CompactTextString(m) } +func (*QueryAssetMetadataResponse) ProtoMessage() {} +func (*QueryAssetMetadataResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{21} +} +func (m *QueryAssetMetadataResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryAssetMetadataResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryAssetMetadataResponse.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 *QueryAssetMetadataResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryAssetMetadataResponse.Merge(m, src) +} +func (m *QueryAssetMetadataResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryAssetMetadataResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryAssetMetadataResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryAssetMetadataResponse proto.InternalMessageInfo + +func (m *QueryAssetMetadataResponse) GetMetadata() *AssetMetadata { + if m != nil { + return m.Metadata + } + return nil +} + +type QueryRegisteredPairsRequest struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` +} + +func (m *QueryRegisteredPairsRequest) Reset() { *m = QueryRegisteredPairsRequest{} } +func (m *QueryRegisteredPairsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryRegisteredPairsRequest) ProtoMessage() {} +func (*QueryRegisteredPairsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{22} +} +func (m *QueryRegisteredPairsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryRegisteredPairsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryRegisteredPairsRequest.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 *QueryRegisteredPairsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRegisteredPairsRequest.Merge(m, src) +} +func (m *QueryRegisteredPairsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryRegisteredPairsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRegisteredPairsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRegisteredPairsRequest proto.InternalMessageInfo + +func (m *QueryRegisteredPairsRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +type QueryRegisteredPairsResponse struct { + Pairs []Pair `protobuf:"bytes,1,rep,name=pairs,proto3" json:"pairs"` +} + +func (m *QueryRegisteredPairsResponse) Reset() { *m = QueryRegisteredPairsResponse{} } +func (m *QueryRegisteredPairsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryRegisteredPairsResponse) ProtoMessage() {} +func (*QueryRegisteredPairsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{23} +} +func (m *QueryRegisteredPairsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryRegisteredPairsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryRegisteredPairsResponse.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 *QueryRegisteredPairsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRegisteredPairsResponse.Merge(m, src) +} +func (m *QueryRegisteredPairsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryRegisteredPairsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRegisteredPairsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRegisteredPairsResponse proto.InternalMessageInfo + +func (m *QueryRegisteredPairsResponse) GetPairs() []Pair { + if m != nil { + return m.Pairs + } + return nil +} + +type QueryRegisteredContractRequest struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` +} + +func (m *QueryRegisteredContractRequest) Reset() { *m = QueryRegisteredContractRequest{} } +func (m *QueryRegisteredContractRequest) String() string { return proto.CompactTextString(m) } +func (*QueryRegisteredContractRequest) ProtoMessage() {} +func (*QueryRegisteredContractRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{24} +} +func (m *QueryRegisteredContractRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryRegisteredContractRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryRegisteredContractRequest.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 *QueryRegisteredContractRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRegisteredContractRequest.Merge(m, src) +} +func (m *QueryRegisteredContractRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryRegisteredContractRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRegisteredContractRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRegisteredContractRequest proto.InternalMessageInfo + +func (m *QueryRegisteredContractRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +type QueryRegisteredContractResponse struct { + ContractInfo *ContractInfoV2 `protobuf:"bytes,1,opt,name=contract_info,json=contractInfo,proto3" json:"contract_info,omitempty"` +} + +func (m *QueryRegisteredContractResponse) Reset() { *m = QueryRegisteredContractResponse{} } +func (m *QueryRegisteredContractResponse) String() string { return proto.CompactTextString(m) } +func (*QueryRegisteredContractResponse) ProtoMessage() {} +func (*QueryRegisteredContractResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{25} +} +func (m *QueryRegisteredContractResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryRegisteredContractResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryRegisteredContractResponse.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 *QueryRegisteredContractResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryRegisteredContractResponse.Merge(m, src) +} +func (m *QueryRegisteredContractResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryRegisteredContractResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryRegisteredContractResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryRegisteredContractResponse proto.InternalMessageInfo + +func (m *QueryRegisteredContractResponse) GetContractInfo() *ContractInfoV2 { + if m != nil { + return m.ContractInfo + } + return nil +} + +type QueryGetOrdersRequest struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` + Account string `protobuf:"bytes,2,opt,name=account,proto3" json:"account"` +} + +func (m *QueryGetOrdersRequest) Reset() { *m = QueryGetOrdersRequest{} } +func (m *QueryGetOrdersRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetOrdersRequest) ProtoMessage() {} +func (*QueryGetOrdersRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{26} +} +func (m *QueryGetOrdersRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetOrdersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetOrdersRequest.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 *QueryGetOrdersRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetOrdersRequest.Merge(m, src) +} +func (m *QueryGetOrdersRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetOrdersRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetOrdersRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetOrdersRequest proto.InternalMessageInfo + +func (m *QueryGetOrdersRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryGetOrdersRequest) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +type QueryGetOrdersResponse struct { + Orders []*Order `protobuf:"bytes,1,rep,name=orders,proto3" json:"orders"` +} + +func (m *QueryGetOrdersResponse) Reset() { *m = QueryGetOrdersResponse{} } +func (m *QueryGetOrdersResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetOrdersResponse) ProtoMessage() {} +func (*QueryGetOrdersResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{27} +} +func (m *QueryGetOrdersResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetOrdersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetOrdersResponse.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 *QueryGetOrdersResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetOrdersResponse.Merge(m, src) +} +func (m *QueryGetOrdersResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetOrdersResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetOrdersResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetOrdersResponse proto.InternalMessageInfo + +func (m *QueryGetOrdersResponse) GetOrders() []*Order { + if m != nil { + return m.Orders + } + return nil +} + +type QueryGetOrderByIDRequest struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` + PriceDenom string `protobuf:"bytes,2,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,3,opt,name=assetDenom,proto3" json:"asset_denom"` + Id uint64 `protobuf:"varint,4,opt,name=id,proto3" json:"id"` +} + +func (m *QueryGetOrderByIDRequest) Reset() { *m = QueryGetOrderByIDRequest{} } +func (m *QueryGetOrderByIDRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetOrderByIDRequest) ProtoMessage() {} +func (*QueryGetOrderByIDRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{28} +} +func (m *QueryGetOrderByIDRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetOrderByIDRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetOrderByIDRequest.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 *QueryGetOrderByIDRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetOrderByIDRequest.Merge(m, src) +} +func (m *QueryGetOrderByIDRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetOrderByIDRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetOrderByIDRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetOrderByIDRequest proto.InternalMessageInfo + +func (m *QueryGetOrderByIDRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryGetOrderByIDRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryGetOrderByIDRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *QueryGetOrderByIDRequest) GetId() uint64 { + if m != nil { + return m.Id + } + return 0 +} + +type QueryGetOrderByIDResponse struct { + Order *Order `protobuf:"bytes,1,opt,name=order,proto3" json:"order"` +} + +func (m *QueryGetOrderByIDResponse) Reset() { *m = QueryGetOrderByIDResponse{} } +func (m *QueryGetOrderByIDResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetOrderByIDResponse) ProtoMessage() {} +func (*QueryGetOrderByIDResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{29} +} +func (m *QueryGetOrderByIDResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetOrderByIDResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetOrderByIDResponse.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 *QueryGetOrderByIDResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetOrderByIDResponse.Merge(m, src) +} +func (m *QueryGetOrderByIDResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetOrderByIDResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetOrderByIDResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetOrderByIDResponse proto.InternalMessageInfo + +func (m *QueryGetOrderByIDResponse) GetOrder() *Order { + if m != nil { + return m.Order + } + return nil +} + +type QueryGetHistoricalPricesRequest struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` + PriceDenom string `protobuf:"bytes,2,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,3,opt,name=assetDenom,proto3" json:"asset_denom"` + PeriodLengthInSeconds uint64 `protobuf:"varint,4,opt,name=periodLengthInSeconds,proto3" json:"period_length_in_seconds"` + NumOfPeriods uint64 `protobuf:"varint,5,opt,name=numOfPeriods,proto3" json:"number_of_periods"` +} + +func (m *QueryGetHistoricalPricesRequest) Reset() { *m = QueryGetHistoricalPricesRequest{} } +func (m *QueryGetHistoricalPricesRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetHistoricalPricesRequest) ProtoMessage() {} +func (*QueryGetHistoricalPricesRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{30} +} +func (m *QueryGetHistoricalPricesRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetHistoricalPricesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetHistoricalPricesRequest.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 *QueryGetHistoricalPricesRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetHistoricalPricesRequest.Merge(m, src) +} +func (m *QueryGetHistoricalPricesRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetHistoricalPricesRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetHistoricalPricesRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetHistoricalPricesRequest proto.InternalMessageInfo + +func (m *QueryGetHistoricalPricesRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryGetHistoricalPricesRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryGetHistoricalPricesRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *QueryGetHistoricalPricesRequest) GetPeriodLengthInSeconds() uint64 { + if m != nil { + return m.PeriodLengthInSeconds + } + return 0 +} + +func (m *QueryGetHistoricalPricesRequest) GetNumOfPeriods() uint64 { + if m != nil { + return m.NumOfPeriods + } + return 0 +} + +type QueryGetHistoricalPricesResponse struct { + Prices []*PriceCandlestick `protobuf:"bytes,1,rep,name=prices,proto3" json:"prices"` +} + +func (m *QueryGetHistoricalPricesResponse) Reset() { *m = QueryGetHistoricalPricesResponse{} } +func (m *QueryGetHistoricalPricesResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetHistoricalPricesResponse) ProtoMessage() {} +func (*QueryGetHistoricalPricesResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{31} +} +func (m *QueryGetHistoricalPricesResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetHistoricalPricesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetHistoricalPricesResponse.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 *QueryGetHistoricalPricesResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetHistoricalPricesResponse.Merge(m, src) +} +func (m *QueryGetHistoricalPricesResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetHistoricalPricesResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetHistoricalPricesResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetHistoricalPricesResponse proto.InternalMessageInfo + +func (m *QueryGetHistoricalPricesResponse) GetPrices() []*PriceCandlestick { + if m != nil { + return m.Prices + } + return nil +} + +type QueryGetMarketSummaryRequest struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` + PriceDenom string `protobuf:"bytes,2,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,3,opt,name=assetDenom,proto3" json:"asset_denom"` + LookbackInSeconds uint64 `protobuf:"varint,4,opt,name=lookbackInSeconds,proto3" json:"lookback_in_seconds"` +} + +func (m *QueryGetMarketSummaryRequest) Reset() { *m = QueryGetMarketSummaryRequest{} } +func (m *QueryGetMarketSummaryRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetMarketSummaryRequest) ProtoMessage() {} +func (*QueryGetMarketSummaryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{32} +} +func (m *QueryGetMarketSummaryRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetMarketSummaryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetMarketSummaryRequest.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 *QueryGetMarketSummaryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetMarketSummaryRequest.Merge(m, src) +} +func (m *QueryGetMarketSummaryRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetMarketSummaryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetMarketSummaryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetMarketSummaryRequest proto.InternalMessageInfo + +func (m *QueryGetMarketSummaryRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryGetMarketSummaryRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryGetMarketSummaryRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *QueryGetMarketSummaryRequest) GetLookbackInSeconds() uint64 { + if m != nil { + return m.LookbackInSeconds + } + return 0 +} + +type QueryGetMarketSummaryResponse struct { + TotalVolume *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=totalVolume,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"total_volume"` + TotalVolumeNotional *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=totalVolumeNotional,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"total_volume_notional"` + HighPrice *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=highPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"high_price"` + LowPrice *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=lowPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"low_price"` + LastPrice *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=lastPrice,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"last_price"` +} + +func (m *QueryGetMarketSummaryResponse) Reset() { *m = QueryGetMarketSummaryResponse{} } +func (m *QueryGetMarketSummaryResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetMarketSummaryResponse) ProtoMessage() {} +func (*QueryGetMarketSummaryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{33} +} +func (m *QueryGetMarketSummaryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetMarketSummaryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetMarketSummaryResponse.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 *QueryGetMarketSummaryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetMarketSummaryResponse.Merge(m, src) +} +func (m *QueryGetMarketSummaryResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetMarketSummaryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetMarketSummaryResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetMarketSummaryResponse proto.InternalMessageInfo + +type QueryOrderSimulationRequest struct { + Order *Order `protobuf:"bytes,1,opt,name=order,proto3" json:"order"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contract_address"` +} + +func (m *QueryOrderSimulationRequest) Reset() { *m = QueryOrderSimulationRequest{} } +func (m *QueryOrderSimulationRequest) String() string { return proto.CompactTextString(m) } +func (*QueryOrderSimulationRequest) ProtoMessage() {} +func (*QueryOrderSimulationRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{34} +} +func (m *QueryOrderSimulationRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryOrderSimulationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryOrderSimulationRequest.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 *QueryOrderSimulationRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryOrderSimulationRequest.Merge(m, src) +} +func (m *QueryOrderSimulationRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryOrderSimulationRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryOrderSimulationRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryOrderSimulationRequest proto.InternalMessageInfo + +func (m *QueryOrderSimulationRequest) GetOrder() *Order { + if m != nil { + return m.Order + } + return nil +} + +func (m *QueryOrderSimulationRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +type QueryOrderSimulationResponse struct { + ExecutedQuantity *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=ExecutedQuantity,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"executed_quantity"` +} + +func (m *QueryOrderSimulationResponse) Reset() { *m = QueryOrderSimulationResponse{} } +func (m *QueryOrderSimulationResponse) String() string { return proto.CompactTextString(m) } +func (*QueryOrderSimulationResponse) ProtoMessage() {} +func (*QueryOrderSimulationResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{35} +} +func (m *QueryOrderSimulationResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryOrderSimulationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryOrderSimulationResponse.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 *QueryOrderSimulationResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryOrderSimulationResponse.Merge(m, src) +} +func (m *QueryOrderSimulationResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryOrderSimulationResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryOrderSimulationResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryOrderSimulationResponse proto.InternalMessageInfo + +type QueryGetMatchResultRequest struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` +} + +func (m *QueryGetMatchResultRequest) Reset() { *m = QueryGetMatchResultRequest{} } +func (m *QueryGetMatchResultRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetMatchResultRequest) ProtoMessage() {} +func (*QueryGetMatchResultRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{36} +} +func (m *QueryGetMatchResultRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetMatchResultRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetMatchResultRequest.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 *QueryGetMatchResultRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetMatchResultRequest.Merge(m, src) +} +func (m *QueryGetMatchResultRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetMatchResultRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetMatchResultRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetMatchResultRequest proto.InternalMessageInfo + +func (m *QueryGetMatchResultRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +type QueryGetMatchResultResponse struct { + Result *MatchResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result"` +} + +func (m *QueryGetMatchResultResponse) Reset() { *m = QueryGetMatchResultResponse{} } +func (m *QueryGetMatchResultResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetMatchResultResponse) ProtoMessage() {} +func (*QueryGetMatchResultResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{37} +} +func (m *QueryGetMatchResultResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetMatchResultResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetMatchResultResponse.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 *QueryGetMatchResultResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetMatchResultResponse.Merge(m, src) +} +func (m *QueryGetMatchResultResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetMatchResultResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetMatchResultResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetMatchResultResponse proto.InternalMessageInfo + +func (m *QueryGetMatchResultResponse) GetResult() *MatchResult { + if m != nil { + return m.Result + } + return nil +} + +type QueryGetOrderCountRequest struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` + PriceDenom string `protobuf:"bytes,2,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,3,opt,name=assetDenom,proto3" json:"asset_denom"` + Price *github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=price,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price"` + PositionDirection PositionDirection `protobuf:"varint,5,opt,name=positionDirection,proto3,enum=seiprotocol.seichain.dex.PositionDirection" json:"position_direction"` +} + +func (m *QueryGetOrderCountRequest) Reset() { *m = QueryGetOrderCountRequest{} } +func (m *QueryGetOrderCountRequest) String() string { return proto.CompactTextString(m) } +func (*QueryGetOrderCountRequest) ProtoMessage() {} +func (*QueryGetOrderCountRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{38} +} +func (m *QueryGetOrderCountRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetOrderCountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetOrderCountRequest.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 *QueryGetOrderCountRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetOrderCountRequest.Merge(m, src) +} +func (m *QueryGetOrderCountRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryGetOrderCountRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetOrderCountRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetOrderCountRequest proto.InternalMessageInfo + +func (m *QueryGetOrderCountRequest) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *QueryGetOrderCountRequest) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *QueryGetOrderCountRequest) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *QueryGetOrderCountRequest) GetPositionDirection() PositionDirection { + if m != nil { + return m.PositionDirection + } + return PositionDirection_LONG +} + +type QueryGetOrderCountResponse struct { + Count uint64 `protobuf:"varint,1,opt,name=count,proto3" json:"count"` +} + +func (m *QueryGetOrderCountResponse) Reset() { *m = QueryGetOrderCountResponse{} } +func (m *QueryGetOrderCountResponse) String() string { return proto.CompactTextString(m) } +func (*QueryGetOrderCountResponse) ProtoMessage() {} +func (*QueryGetOrderCountResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_d8e98105e6e08a59, []int{39} +} +func (m *QueryGetOrderCountResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryGetOrderCountResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryGetOrderCountResponse.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 *QueryGetOrderCountResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryGetOrderCountResponse.Merge(m, src) +} +func (m *QueryGetOrderCountResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryGetOrderCountResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryGetOrderCountResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryGetOrderCountResponse proto.InternalMessageInfo + +func (m *QueryGetOrderCountResponse) GetCount() uint64 { + if m != nil { + return m.Count + } + return 0 +} + +func init() { + proto.RegisterType((*QueryParamsRequest)(nil), "seiprotocol.seichain.dex.QueryParamsRequest") + proto.RegisterType((*QueryParamsResponse)(nil), "seiprotocol.seichain.dex.QueryParamsResponse") + proto.RegisterType((*QueryGetLongBookRequest)(nil), "seiprotocol.seichain.dex.QueryGetLongBookRequest") + proto.RegisterType((*QueryGetLongBookResponse)(nil), "seiprotocol.seichain.dex.QueryGetLongBookResponse") + proto.RegisterType((*QueryAllLongBookRequest)(nil), "seiprotocol.seichain.dex.QueryAllLongBookRequest") + proto.RegisterType((*QueryAllLongBookResponse)(nil), "seiprotocol.seichain.dex.QueryAllLongBookResponse") + proto.RegisterType((*QueryGetShortBookRequest)(nil), "seiprotocol.seichain.dex.QueryGetShortBookRequest") + proto.RegisterType((*QueryGetShortBookResponse)(nil), "seiprotocol.seichain.dex.QueryGetShortBookResponse") + proto.RegisterType((*QueryAllShortBookRequest)(nil), "seiprotocol.seichain.dex.QueryAllShortBookRequest") + proto.RegisterType((*QueryAllShortBookResponse)(nil), "seiprotocol.seichain.dex.QueryAllShortBookResponse") + proto.RegisterType((*QueryGetPricesRequest)(nil), "seiprotocol.seichain.dex.QueryGetPricesRequest") + proto.RegisterType((*QueryGetPricesResponse)(nil), "seiprotocol.seichain.dex.QueryGetPricesResponse") + proto.RegisterType((*QueryGetPriceRequest)(nil), "seiprotocol.seichain.dex.QueryGetPriceRequest") + proto.RegisterType((*QueryGetPriceResponse)(nil), "seiprotocol.seichain.dex.QueryGetPriceResponse") + proto.RegisterType((*QueryGetLatestPriceRequest)(nil), "seiprotocol.seichain.dex.QueryGetLatestPriceRequest") + proto.RegisterType((*QueryGetLatestPriceResponse)(nil), "seiprotocol.seichain.dex.QueryGetLatestPriceResponse") + proto.RegisterType((*QueryGetTwapsRequest)(nil), "seiprotocol.seichain.dex.QueryGetTwapsRequest") + proto.RegisterType((*QueryGetTwapsResponse)(nil), "seiprotocol.seichain.dex.QueryGetTwapsResponse") + proto.RegisterType((*QueryAssetListRequest)(nil), "seiprotocol.seichain.dex.QueryAssetListRequest") + proto.RegisterType((*QueryAssetListResponse)(nil), "seiprotocol.seichain.dex.QueryAssetListResponse") + proto.RegisterType((*QueryAssetMetadataRequest)(nil), "seiprotocol.seichain.dex.QueryAssetMetadataRequest") + proto.RegisterType((*QueryAssetMetadataResponse)(nil), "seiprotocol.seichain.dex.QueryAssetMetadataResponse") + proto.RegisterType((*QueryRegisteredPairsRequest)(nil), "seiprotocol.seichain.dex.QueryRegisteredPairsRequest") + proto.RegisterType((*QueryRegisteredPairsResponse)(nil), "seiprotocol.seichain.dex.QueryRegisteredPairsResponse") + proto.RegisterType((*QueryRegisteredContractRequest)(nil), "seiprotocol.seichain.dex.QueryRegisteredContractRequest") + proto.RegisterType((*QueryRegisteredContractResponse)(nil), "seiprotocol.seichain.dex.QueryRegisteredContractResponse") + proto.RegisterType((*QueryGetOrdersRequest)(nil), "seiprotocol.seichain.dex.QueryGetOrdersRequest") + proto.RegisterType((*QueryGetOrdersResponse)(nil), "seiprotocol.seichain.dex.QueryGetOrdersResponse") + proto.RegisterType((*QueryGetOrderByIDRequest)(nil), "seiprotocol.seichain.dex.QueryGetOrderByIDRequest") + proto.RegisterType((*QueryGetOrderByIDResponse)(nil), "seiprotocol.seichain.dex.QueryGetOrderByIDResponse") + proto.RegisterType((*QueryGetHistoricalPricesRequest)(nil), "seiprotocol.seichain.dex.QueryGetHistoricalPricesRequest") + proto.RegisterType((*QueryGetHistoricalPricesResponse)(nil), "seiprotocol.seichain.dex.QueryGetHistoricalPricesResponse") + proto.RegisterType((*QueryGetMarketSummaryRequest)(nil), "seiprotocol.seichain.dex.QueryGetMarketSummaryRequest") + proto.RegisterType((*QueryGetMarketSummaryResponse)(nil), "seiprotocol.seichain.dex.QueryGetMarketSummaryResponse") + proto.RegisterType((*QueryOrderSimulationRequest)(nil), "seiprotocol.seichain.dex.QueryOrderSimulationRequest") + proto.RegisterType((*QueryOrderSimulationResponse)(nil), "seiprotocol.seichain.dex.QueryOrderSimulationResponse") + proto.RegisterType((*QueryGetMatchResultRequest)(nil), "seiprotocol.seichain.dex.QueryGetMatchResultRequest") + proto.RegisterType((*QueryGetMatchResultResponse)(nil), "seiprotocol.seichain.dex.QueryGetMatchResultResponse") + proto.RegisterType((*QueryGetOrderCountRequest)(nil), "seiprotocol.seichain.dex.QueryGetOrderCountRequest") + proto.RegisterType((*QueryGetOrderCountResponse)(nil), "seiprotocol.seichain.dex.QueryGetOrderCountResponse") +} + +func init() { proto.RegisterFile("dex/query.proto", fileDescriptor_d8e98105e6e08a59) } + +var fileDescriptor_d8e98105e6e08a59 = []byte{ + // 2281 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x59, 0xcb, 0x6f, 0x1c, 0x49, + 0x1d, 0x76, 0x8f, 0x63, 0x63, 0x97, 0xf3, 0x2c, 0xdb, 0x89, 0x19, 0xc2, 0x4c, 0xa8, 0x55, 0x36, + 0xcb, 0x2e, 0x9e, 0x26, 0x4e, 0xb2, 0x79, 0x48, 0x9b, 0x6c, 0xc6, 0xce, 0x1a, 0x8b, 0x38, 0x71, + 0xda, 0x89, 0x37, 0x84, 0x0d, 0xbd, 0xe5, 0xe9, 0xf2, 0x4c, 0xe3, 0x9e, 0xae, 0x49, 0x77, 0xcf, + 0xc6, 0x96, 0x19, 0xf1, 0x12, 0x17, 0xb8, 0x44, 0x5a, 0x0e, 0xec, 0x81, 0x3f, 0x00, 0x09, 0x0e, + 0x5c, 0xd0, 0x8a, 0x3b, 0xab, 0x95, 0x40, 0x4b, 0xa4, 0x05, 0x09, 0x81, 0x34, 0x42, 0x09, 0xa7, + 0xb9, 0x23, 0xc4, 0x6d, 0xd5, 0x55, 0xd5, 0xef, 0x19, 0x77, 0x77, 0x1c, 0xad, 0xb2, 0xa7, 0xf6, + 0x54, 0xd7, 0xf7, 0xab, 0xdf, 0xf7, 0xd5, 0xaf, 0x1e, 0xfd, 0x19, 0x1c, 0xd2, 0xc8, 0x96, 0xfc, + 0xa0, 0x4d, 0xac, 0xed, 0x4a, 0xcb, 0xa2, 0x0e, 0x85, 0x33, 0x36, 0xd1, 0xd9, 0x5f, 0x35, 0x6a, + 0x54, 0x6c, 0xa2, 0xd7, 0x1a, 0x58, 0x37, 0x2b, 0x1a, 0xd9, 0x2a, 0x4e, 0xd5, 0x69, 0x9d, 0xb2, + 0x57, 0xb2, 0xfb, 0x17, 0xef, 0x5f, 0x3c, 0x5e, 0xa7, 0xb4, 0x6e, 0x10, 0x19, 0xb7, 0x74, 0x19, + 0x9b, 0x26, 0x75, 0xb0, 0xa3, 0x53, 0xd3, 0x16, 0x6f, 0x5f, 0xad, 0x51, 0xbb, 0x49, 0x6d, 0x79, + 0x1d, 0xdb, 0x84, 0x0f, 0x23, 0xbf, 0x77, 0x7a, 0x9d, 0x38, 0xf8, 0xb4, 0xdc, 0xc2, 0x75, 0xdd, + 0x64, 0x9d, 0x45, 0xdf, 0xc3, 0x6e, 0x2a, 0x2d, 0x6c, 0xe1, 0xa6, 0x87, 0x9e, 0x74, 0x5b, 0x0c, + 0x6a, 0xd6, 0xd5, 0x75, 0x4a, 0x37, 0x45, 0xe3, 0x94, 0xdb, 0x68, 0x37, 0xa8, 0xe5, 0x84, 0x5b, + 0x19, 0x8f, 0x96, 0xa5, 0xd7, 0x88, 0x68, 0x80, 0x6e, 0x43, 0x8d, 0x9a, 0x8e, 0x85, 0x6b, 0x8e, + 0x68, 0x3b, 0xe8, 0xb6, 0x39, 0x0f, 0x71, 0x2b, 0x1c, 0x0a, 0xdb, 0x36, 0x71, 0x54, 0x43, 0xb7, + 0x23, 0xbd, 0x5a, 0x58, 0xb7, 0xc2, 0xa1, 0xa9, 0xa5, 0x11, 0xaf, 0xe1, 0xa8, 0xdb, 0xd0, 0xc4, + 0x4e, 0xad, 0xa1, 0x5a, 0xc4, 0x6e, 0x1b, 0x4e, 0xb8, 0x23, 0x31, 0xdb, 0x5e, 0xfe, 0x68, 0x0a, + 0xc0, 0x5b, 0x2e, 0xe7, 0x15, 0x46, 0x4a, 0x21, 0x0f, 0xda, 0xc4, 0x76, 0xd0, 0x1d, 0x30, 0x19, + 0x69, 0xb5, 0x5b, 0xd4, 0xb4, 0x09, 0xbc, 0x0c, 0x46, 0x39, 0xf9, 0x19, 0xe9, 0x84, 0xf4, 0xca, + 0xc4, 0xdc, 0x89, 0xca, 0xa0, 0x99, 0xa8, 0x70, 0x64, 0x75, 0xdf, 0xc7, 0xdd, 0xf2, 0x90, 0x22, + 0x50, 0xe8, 0x7d, 0x09, 0x1c, 0x63, 0x71, 0x17, 0x89, 0x73, 0x9d, 0x9a, 0xf5, 0x2a, 0xa5, 0x9b, + 0x62, 0x48, 0x38, 0x05, 0x46, 0x98, 0x36, 0x2c, 0xf4, 0xb8, 0xc2, 0x7f, 0x40, 0x04, 0xf6, 0x7b, + 0x02, 0x5d, 0xd5, 0x34, 0x6b, 0xa6, 0xc0, 0x5e, 0x46, 0xda, 0x60, 0x09, 0x00, 0xd6, 0x79, 0x81, + 0x98, 0xb4, 0x39, 0x33, 0xcc, 0x7a, 0x84, 0x5a, 0xdc, 0xf7, 0x4c, 0x40, 0xfe, 0x7e, 0x1f, 0x7f, + 0x1f, 0xb4, 0xa0, 0x77, 0xc1, 0x4c, 0x32, 0x29, 0xc1, 0x78, 0x01, 0x8c, 0x79, 0x6d, 0x82, 0x33, + 0x1a, 0xcc, 0xd9, 0xeb, 0x29, 0x58, 0xfb, 0x48, 0xf4, 0x27, 0x8f, 0xf7, 0x55, 0xc3, 0x88, 0xf3, + 0x7e, 0x0b, 0x80, 0xa0, 0xcc, 0xc4, 0x18, 0x2f, 0x57, 0x78, 0x4d, 0x56, 0xdc, 0x9a, 0xac, 0xf0, + 0xd2, 0x17, 0x35, 0x59, 0x59, 0xc1, 0x75, 0x22, 0xb0, 0x4a, 0x08, 0xf9, 0xb9, 0x28, 0xf5, 0x1b, + 0x49, 0x48, 0x15, 0xe1, 0xd1, 0x57, 0xaa, 0xe1, 0x67, 0x93, 0x0a, 0x2e, 0x46, 0xe4, 0x28, 0x30, + 0x39, 0x4e, 0xa5, 0xca, 0xc1, 0x53, 0x08, 0xeb, 0x81, 0x7e, 0x29, 0x05, 0xd3, 0xba, 0xea, 0x2e, + 0xc5, 0x17, 0xa3, 0xd8, 0x34, 0xf0, 0xe5, 0x3e, 0x59, 0x09, 0x09, 0x17, 0xc1, 0xb8, 0xdf, 0x28, + 0x4a, 0xe1, 0xa5, 0xc1, 0x1a, 0xfa, 0x5d, 0x85, 0x88, 0x01, 0x16, 0x7d, 0x14, 0x9a, 0xa8, 0x04, + 0xf9, 0x2f, 0x52, 0xc5, 0xfd, 0x4e, 0x12, 0x7a, 0x45, 0x89, 0xf4, 0xd7, 0x6b, 0xf8, 0x59, 0xf5, + 0x7a, 0x7e, 0x55, 0xb7, 0x03, 0xa6, 0xbd, 0xe9, 0x5d, 0x71, 0x59, 0x7a, 0x3b, 0x6a, 0x4c, 0x08, + 0x29, 0x45, 0x88, 0x42, 0x5c, 0x88, 0x84, 0xd8, 0xc3, 0x49, 0xb1, 0xd1, 0x2d, 0x70, 0x34, 0x3e, + 0xb8, 0x10, 0xea, 0x3c, 0x18, 0x65, 0x63, 0xd9, 0x42, 0xa5, 0xf2, 0x2e, 0x1b, 0xb7, 0xdb, 0x4f, + 0x11, 0xdd, 0xd1, 0xaf, 0x24, 0x30, 0x15, 0x89, 0xf9, 0x39, 0xf2, 0x81, 0xc7, 0xc1, 0xb8, 0xa3, + 0x37, 0x89, 0xed, 0xe0, 0x66, 0x8b, 0xd5, 0xc6, 0x3e, 0x25, 0x68, 0x40, 0x5a, 0x4c, 0x6a, 0x9f, + 0xec, 0xb9, 0xf0, 0xe2, 0xce, 0xc0, 0x55, 0xac, 0xfe, 0x29, 0x30, 0xb2, 0x41, 0xdb, 0xa6, 0xc6, + 0x92, 0x1d, 0x53, 0xf8, 0x0f, 0xf4, 0xa1, 0x04, 0x8a, 0xfe, 0xe9, 0x80, 0x1d, 0x62, 0x47, 0x65, + 0x90, 0x93, 0x32, 0x54, 0x0f, 0xf5, 0xba, 0xe5, 0x09, 0xd6, 0xaa, 0x6a, 0x6e, 0x73, 0x44, 0x17, + 0x39, 0xa9, 0x0b, 0x07, 0xf0, 0x33, 0x5e, 0x00, 0x42, 0x42, 0x5d, 0xe8, 0x27, 0x54, 0x75, 0xaa, + 0xd7, 0x2d, 0x1f, 0xf6, 0xda, 0x55, 0xac, 0x69, 0x16, 0xb1, 0xed, 0x58, 0x39, 0xdc, 0x06, 0x5f, + 0xe9, 0x9b, 0xf9, 0x9e, 0x64, 0x42, 0x8f, 0x42, 0x15, 0x71, 0xfb, 0x21, 0x6e, 0xf9, 0x15, 0x1e, + 0x4f, 0x54, 0xca, 0x9a, 0x28, 0xbc, 0x0c, 0x0e, 0x19, 0x94, 0x6e, 0xae, 0xe3, 0xda, 0xe6, 0x2a, + 0xa9, 0x51, 0x53, 0xb3, 0x99, 0x30, 0xfb, 0x38, 0xd8, 0x7b, 0xa5, 0xda, 0xfc, 0x9d, 0x12, 0xef, + 0x8c, 0xee, 0x06, 0x95, 0x20, 0x32, 0x12, 0x14, 0xaf, 0x80, 0x11, 0xf7, 0x2a, 0xe5, 0x55, 0x7d, + 0x69, 0x30, 0x45, 0x17, 0x57, 0x1d, 0xef, 0x75, 0xcb, 0x1c, 0xa0, 0xf0, 0x07, 0x3a, 0x26, 0x22, + 0x5f, 0x75, 0xe7, 0xe3, 0xba, 0x6e, 0x3b, 0xde, 0x05, 0x89, 0x88, 0xa5, 0x16, 0x7a, 0x21, 0xc6, + 0xfc, 0x36, 0x18, 0xc7, 0x5e, 0xa3, 0x18, 0xf7, 0xd4, 0xe0, 0x71, 0x19, 0x7e, 0x99, 0x38, 0x58, + 0xc3, 0x0e, 0xf6, 0xf6, 0x25, 0x1f, 0x8f, 0x4e, 0x7b, 0xbb, 0x5f, 0xb8, 0x5b, 0xe8, 0x10, 0xd3, + 0x42, 0xab, 0x8f, 0xff, 0x40, 0x58, 0xd4, 0x6b, 0x0c, 0x22, 0xb2, 0x9b, 0x07, 0x63, 0x4d, 0xd1, + 0x26, 0xe6, 0x3d, 0x6b, 0x72, 0x8a, 0x0f, 0x44, 0x6f, 0x8b, 0xc2, 0x52, 0x48, 0x5d, 0xb7, 0x1d, + 0x62, 0x11, 0x6d, 0x05, 0xeb, 0xd6, 0xde, 0x0b, 0x01, 0xdd, 0x03, 0xc7, 0xfb, 0x07, 0x16, 0xd9, + 0x5f, 0x02, 0x23, 0xee, 0xa5, 0x37, 0xc3, 0x7c, 0xba, 0x38, 0x21, 0x27, 0x87, 0xa0, 0x7b, 0xa0, + 0x14, 0x8b, 0x3d, 0x2f, 0x86, 0xde, 0x7b, 0xde, 0x2d, 0x50, 0x1e, 0x18, 0x5b, 0xa4, 0xbe, 0x0c, + 0x0e, 0xf8, 0x41, 0x74, 0x73, 0x83, 0x0a, 0xf5, 0x5f, 0x19, 0x4c, 0xc1, 0x0b, 0xb1, 0x64, 0x6e, + 0xd0, 0xb5, 0xb9, 0x60, 0x44, 0xf7, 0x37, 0xda, 0x0a, 0x4a, 0xfe, 0xa6, 0x7b, 0xed, 0x7f, 0x0e, + 0xab, 0xf0, 0x24, 0xf8, 0x12, 0xae, 0xd5, 0x68, 0xdb, 0x74, 0xc4, 0xb6, 0x34, 0xd1, 0xeb, 0x96, + 0xbd, 0x26, 0xc5, 0xfb, 0x03, 0xdd, 0x0f, 0x0e, 0x19, 0x6f, 0x64, 0xbf, 0xb6, 0x46, 0xd9, 0x27, + 0x48, 0x86, 0x43, 0x86, 0x21, 0xab, 0xa0, 0xd7, 0x2d, 0x0b, 0x88, 0x22, 0x9e, 0xe8, 0x93, 0xd0, + 0xb5, 0x8d, 0xf7, 0xda, 0x5e, 0x5a, 0xd8, 0x3b, 0xb9, 0xe8, 0x3e, 0x5d, 0xc8, 0xbb, 0x4f, 0x0f, + 0xa7, 0xef, 0xd3, 0x47, 0x41, 0x41, 0xd7, 0xf8, 0x29, 0x55, 0x1d, 0xed, 0x75, 0xcb, 0x05, 0x5d, + 0x53, 0x0a, 0xba, 0x86, 0xee, 0x07, 0x17, 0xbe, 0x10, 0x1f, 0x21, 0xd9, 0x9b, 0x60, 0x84, 0xf1, + 0x4e, 0xdf, 0x83, 0x39, 0x96, 0xed, 0x50, 0x0c, 0xa1, 0xf0, 0x07, 0xfa, 0x4b, 0x41, 0xd4, 0xde, + 0x22, 0x71, 0xbe, 0xa5, 0xdb, 0x0e, 0xb5, 0xf4, 0x1a, 0x36, 0xa2, 0x77, 0x8f, 0x17, 0x59, 0x36, + 0x05, 0x4c, 0xb7, 0x88, 0xa5, 0x53, 0xed, 0x3a, 0x31, 0xeb, 0x4e, 0x63, 0xc9, 0xf4, 0x4e, 0x00, + 0xae, 0xe4, 0xf1, 0x5e, 0xb7, 0x3c, 0xc3, 0x3b, 0xa8, 0x06, 0xeb, 0xa1, 0xea, 0xa6, 0x7f, 0x12, + 0xf4, 0x87, 0xc2, 0x8b, 0x60, 0xbf, 0xd9, 0x6e, 0xde, 0xdc, 0x58, 0x61, 0x6f, 0xed, 0x99, 0x11, + 0x16, 0x6a, 0xba, 0xd7, 0x2d, 0x1f, 0x31, 0xdb, 0xcd, 0x75, 0x62, 0xa9, 0x74, 0x43, 0xe5, 0x50, + 0x5b, 0x89, 0x74, 0x45, 0x16, 0x38, 0x31, 0x58, 0x4d, 0x31, 0x69, 0x37, 0x62, 0x97, 0xa9, 0x57, + 0x53, 0x4e, 0xce, 0x79, 0x6c, 0x6a, 0x06, 0xb1, 0x1d, 0xbd, 0xb6, 0xc9, 0x4b, 0x9e, 0xa3, 0xfd, + 0x3b, 0xd6, 0x8f, 0x0b, 0x62, 0xdb, 0x5b, 0x24, 0xce, 0x32, 0xb6, 0x36, 0x89, 0xb3, 0xda, 0x6e, + 0x36, 0xb1, 0xbb, 0x9d, 0xbc, 0xf8, 0xf3, 0x77, 0x0d, 0x1c, 0xf1, 0x8e, 0xe3, 0xf8, 0xdc, 0x1d, + 0xeb, 0x75, 0xcb, 0x93, 0xfe, 0xe9, 0x1d, 0x9a, 0xb6, 0x24, 0x02, 0xfd, 0x7f, 0x18, 0x7c, 0x75, + 0x80, 0x06, 0x42, 0xf5, 0x77, 0xc0, 0x84, 0x43, 0x1d, 0x6c, 0xac, 0x51, 0xa3, 0xdd, 0x14, 0x1f, + 0x6e, 0xd5, 0x4b, 0xff, 0xec, 0x96, 0x5f, 0xae, 0xeb, 0x4e, 0xa3, 0xbd, 0x5e, 0xa9, 0xd1, 0xa6, + 0x2c, 0xac, 0x1c, 0xfe, 0x98, 0xb5, 0xb5, 0x4d, 0xd9, 0xd9, 0x6e, 0x11, 0xbb, 0xb2, 0x40, 0x6a, + 0xbd, 0x6e, 0x79, 0x3f, 0x0b, 0xa0, 0xbe, 0xc7, 0x22, 0x28, 0xe1, 0x70, 0xb0, 0x0d, 0x26, 0x43, + 0x3f, 0x6f, 0x50, 0xf7, 0x32, 0x8f, 0x0d, 0xa1, 0xd8, 0x7c, 0xae, 0x51, 0xa6, 0xc3, 0xa3, 0xa8, + 0xa6, 0x08, 0xa5, 0xf4, 0x8b, 0x0f, 0xd7, 0xc0, 0x78, 0x43, 0xaf, 0x37, 0x58, 0x99, 0x08, 0xb5, + 0x2f, 0xe4, 0x1a, 0x0c, 0xb8, 0x70, 0x95, 0x4d, 0xa0, 0x12, 0x84, 0x82, 0xab, 0x60, 0xcc, 0xa0, + 0x0f, 0x79, 0x58, 0xf6, 0x51, 0x55, 0x3d, 0x9f, 0x2b, 0xec, 0xb8, 0x41, 0x1f, 0x8a, 0xa8, 0x7e, + 0x20, 0x37, 0x59, 0x03, 0x8b, 0x5b, 0x24, 0x5b, 0x53, 0xb9, 0x93, 0x75, 0xe1, 0x5e, 0xb2, 0x7e, + 0x28, 0xf4, 0x81, 0x24, 0xee, 0x13, 0x6c, 0x8f, 0x5b, 0xd5, 0x9b, 0x6d, 0x83, 0x7d, 0x4c, 0x79, + 0xe5, 0xbf, 0xe7, 0x4d, 0x32, 0xb1, 0x80, 0x0a, 0x99, 0x4f, 0xf6, 0x5f, 0x48, 0x62, 0x6d, 0x26, + 0x72, 0x13, 0x65, 0xb9, 0x09, 0x0e, 0x5f, 0xdb, 0x22, 0xb5, 0xb6, 0x43, 0xb4, 0x5b, 0x6d, 0x6c, + 0x3a, 0xba, 0xb3, 0x2d, 0x6a, 0xf3, 0x4a, 0x2e, 0x6d, 0x8e, 0x10, 0x11, 0x45, 0x7d, 0x20, 0xc2, + 0x28, 0x89, 0xc0, 0x68, 0x2d, 0xf8, 0x16, 0x59, 0xc6, 0x4e, 0xad, 0xa1, 0x30, 0x6b, 0x6f, 0xef, + 0xf7, 0x97, 0x46, 0xf0, 0xa5, 0x10, 0x89, 0x2b, 0x38, 0x2e, 0x81, 0x51, 0x6e, 0x22, 0x8a, 0x19, + 0x38, 0x39, 0x78, 0x06, 0x42, 0x70, 0xbe, 0xd7, 0x71, 0xa0, 0x22, 0x9e, 0xe8, 0xbf, 0x85, 0xd8, + 0x71, 0x38, 0xcf, 0x6e, 0x17, 0x5f, 0x80, 0x8d, 0x6e, 0xc9, 0xfb, 0x5c, 0xe2, 0xeb, 0xe9, 0x4c, + 0xae, 0xd9, 0xe5, 0x50, 0xef, 0x4b, 0xf3, 0x01, 0x38, 0xd2, 0xa2, 0xb6, 0xee, 0xd6, 0xd1, 0x82, + 0x6e, 0x91, 0x1a, 0x33, 0x1d, 0xdc, 0x05, 0x75, 0x70, 0xee, 0xb5, 0x5d, 0xce, 0x92, 0x38, 0xa4, + 0x7a, 0xb4, 0xd7, 0x2d, 0x43, 0x2f, 0x92, 0xaa, 0x79, 0xed, 0x4a, 0x32, 0x3a, 0x7a, 0x23, 0xa8, + 0x9c, 0xb0, 0xec, 0x62, 0x82, 0xcb, 0x60, 0x84, 0x5f, 0xfc, 0x24, 0xb6, 0x71, 0xb3, 0x05, 0xc4, + 0xaf, 0x7d, 0xfc, 0x31, 0xf7, 0xdb, 0x12, 0x18, 0x61, 0x78, 0xf8, 0x48, 0x02, 0xa3, 0xdc, 0xdb, + 0x85, 0xdf, 0x18, 0x9c, 0x6b, 0xd2, 0x52, 0x2e, 0xce, 0x66, 0xec, 0xcd, 0x53, 0x42, 0x5f, 0xff, + 0xc9, 0xa7, 0xff, 0x79, 0xbf, 0xf0, 0x12, 0xfc, 0x9a, 0x6c, 0x13, 0x7d, 0xd6, 0xc3, 0xc9, 0x1e, + 0x4e, 0x0e, 0x8c, 0x78, 0xf8, 0x58, 0x0a, 0x9c, 0x47, 0x78, 0x3a, 0x65, 0x98, 0xa4, 0xf3, 0x5c, + 0x9c, 0xcb, 0x03, 0x11, 0xe9, 0xdd, 0x67, 0xe9, 0xbd, 0x0d, 0xef, 0xec, 0x92, 0x9e, 0xff, 0x5f, + 0x01, 0x79, 0x27, 0x5c, 0xab, 0x1d, 0x79, 0x27, 0xa8, 0xc3, 0x8e, 0xbc, 0x13, 0xd4, 0x98, 0xf7, + 0xa6, 0x03, 0xff, 0x2c, 0x81, 0x09, 0x6f, 0xcc, 0xab, 0x86, 0x91, 0xca, 0x2a, 0xe9, 0x2b, 0xa7, + 0xb2, 0xea, 0x63, 0xe1, 0xa2, 0x3b, 0x8c, 0xd5, 0x4d, 0xb8, 0xfc, 0x5c, 0x59, 0xc1, 0xbf, 0x49, + 0x21, 0x9f, 0x0e, 0x66, 0x90, 0x3b, 0x6e, 0x59, 0x16, 0xcf, 0xe4, 0xc2, 0x08, 0x36, 0xdf, 0x63, + 0x6c, 0xee, 0xc2, 0xb5, 0x5d, 0xd8, 0x04, 0xff, 0xa4, 0xc9, 0x3f, 0x49, 0x7f, 0x95, 0xc0, 0x7e, + 0x7f, 0x54, 0x77, 0x96, 0x32, 0x48, 0x9e, 0x9b, 0x59, 0x3f, 0xdf, 0x13, 0xad, 0x31, 0x66, 0x2b, + 0xf0, 0xc6, 0xf3, 0x65, 0x06, 0x3f, 0x91, 0xc0, 0x98, 0x67, 0xa7, 0xc1, 0x4a, 0xba, 0xe6, 0x61, + 0x2b, 0xac, 0x28, 0x67, 0xee, 0x2f, 0x58, 0x60, 0xc6, 0xe2, 0xbb, 0xf0, 0x3b, 0xbb, 0xb0, 0xa8, + 0x13, 0x71, 0x61, 0xc8, 0x31, 0x3d, 0xbe, 0x45, 0xd8, 0x81, 0xff, 0x92, 0xc0, 0xc1, 0xa8, 0xfd, + 0x05, 0xcf, 0x66, 0x58, 0xed, 0x09, 0x9f, 0xaf, 0x78, 0x2e, 0x27, 0x4a, 0x50, 0x7c, 0x87, 0x51, + 0x5c, 0x83, 0xb7, 0x53, 0x28, 0x1a, 0x0c, 0x9b, 0x93, 0x29, 0xfc, 0x48, 0x02, 0xe3, 0xbe, 0xd7, + 0x0b, 0xb3, 0xea, 0xef, 0xef, 0xc8, 0xdf, 0xcc, 0x0e, 0xc8, 0x51, 0x77, 0xfe, 0x8c, 0xd9, 0xd9, + 0x89, 0xfc, 0x91, 0xd7, 0x1d, 0x33, 0xef, 0xb2, 0xd4, 0x5d, 0xd8, 0x77, 0xcc, 0x52, 0x77, 0x11, + 0x57, 0x10, 0x2d, 0x33, 0x16, 0x8b, 0xf0, 0x5a, 0x0a, 0x0b, 0x66, 0x01, 0x26, 0x48, 0xc4, 0xcc, + 0xc7, 0x0e, 0xfc, 0xbd, 0x04, 0x0e, 0x44, 0x9c, 0x32, 0x98, 0xba, 0xa6, 0xfb, 0xb8, 0x79, 0xc5, + 0xb3, 0xf9, 0x40, 0x82, 0xcb, 0x39, 0xc6, 0x45, 0x86, 0xb3, 0xbb, 0x70, 0x09, 0xfe, 0x7b, 0x2c, + 0xef, 0x68, 0x5c, 0xf0, 0x5f, 0x4b, 0x60, 0xdc, 0xb7, 0x2e, 0x53, 0x2b, 0x27, 0xee, 0x7e, 0xa6, + 0x56, 0x4e, 0xc2, 0x15, 0x45, 0xb3, 0x2c, 0xcf, 0x53, 0xf0, 0x64, 0xa6, 0x3c, 0xe1, 0x87, 0x12, + 0x80, 0x8b, 0xc4, 0x89, 0xf9, 0x80, 0x30, 0x6d, 0x15, 0xf6, 0x37, 0x24, 0x8b, 0xaf, 0xe7, 0x85, + 0x89, 0xa4, 0xcf, 0xb0, 0xa4, 0x67, 0xe1, 0x6b, 0xbb, 0x24, 0x6d, 0xf9, 0x58, 0x95, 0xf9, 0x8c, + 0xf0, 0x53, 0x09, 0x4c, 0x47, 0x52, 0xf7, 0x7c, 0x3c, 0x78, 0x21, 0x73, 0x1a, 0x31, 0x67, 0xb2, + 0x78, 0xf1, 0x19, 0x90, 0x82, 0xc3, 0x35, 0xc6, 0xe1, 0x0a, 0x7c, 0x23, 0x1b, 0x07, 0xaf, 0xd8, + 0x63, 0x65, 0x0f, 0xff, 0xc0, 0xb7, 0x1a, 0xee, 0xf8, 0x65, 0xd9, 0x6a, 0x22, 0xae, 0x64, 0x96, + 0xad, 0x26, 0x6a, 0x26, 0xa2, 0xb7, 0x58, 0xde, 0x6f, 0xc2, 0xcb, 0x29, 0x8b, 0x94, 0xdb, 0x86, + 0x89, 0x55, 0x2a, 0xdc, 0xca, 0x0e, 0xfc, 0x3b, 0xdf, 0x5a, 0x58, 0xf4, 0x2c, 0x57, 0x8f, 0xb8, + 0xe7, 0x98, 0xe5, 0xea, 0x91, 0xf0, 0xf5, 0xd0, 0xbb, 0x2c, 0xfb, 0x7b, 0xf0, 0x6e, 0x96, 0xec, + 0xd5, 0xf5, 0x6d, 0x55, 0xd7, 0x72, 0x1c, 0x70, 0xba, 0xd6, 0x81, 0x1f, 0x14, 0xc0, 0x64, 0x1f, + 0x93, 0x0a, 0x5e, 0x4c, 0x4f, 0x77, 0x80, 0x4d, 0x58, 0xbc, 0xf4, 0x2c, 0x50, 0x41, 0xf8, 0xe7, + 0x12, 0x63, 0xfc, 0x53, 0x09, 0xfe, 0x48, 0x4a, 0xe1, 0xdc, 0xf0, 0x63, 0xe4, 0x3d, 0x27, 0xe4, + 0x9d, 0xbe, 0x7e, 0x5f, 0x47, 0xde, 0x09, 0x7b, 0x78, 0x1d, 0xf8, 0x3f, 0x09, 0x1c, 0x8e, 0xfb, + 0x48, 0xf0, 0xf5, 0x74, 0x76, 0xfd, 0xcc, 0xb7, 0xe2, 0xf9, 0xdc, 0x38, 0x21, 0x89, 0xc5, 0x14, + 0x31, 0xe0, 0xf7, 0x53, 0xf4, 0x68, 0x32, 0xb4, 0x6a, 0x73, 0x78, 0x0e, 0x31, 0x12, 0x2e, 0x5a, + 0x07, 0xfe, 0x8c, 0xef, 0x9b, 0x31, 0xb3, 0x22, 0x75, 0xdf, 0xec, 0x6f, 0xbc, 0xa4, 0xee, 0x9b, + 0x03, 0x3c, 0x11, 0x34, 0x04, 0x7f, 0xc8, 0xae, 0x5d, 0x21, 0x33, 0x20, 0xcb, 0xb5, 0x2b, 0x69, + 0x69, 0x64, 0xb9, 0x76, 0xf5, 0x31, 0x2c, 0xd0, 0x10, 0xfc, 0x01, 0x38, 0x10, 0xf9, 0xd4, 0x85, + 0x59, 0x97, 0x71, 0xd8, 0x8f, 0x28, 0x9e, 0xcd, 0x07, 0xf2, 0x46, 0xaf, 0x2e, 0x7e, 0xfc, 0xa4, + 0x24, 0x3d, 0x7e, 0x52, 0x92, 0xfe, 0xfd, 0xa4, 0x24, 0x3d, 0x7a, 0x5a, 0x1a, 0x7a, 0xfc, 0xb4, + 0x34, 0xf4, 0x8f, 0xa7, 0xa5, 0xa1, 0x7b, 0xb3, 0x21, 0xcb, 0x20, 0x5e, 0x16, 0xb3, 0xbc, 0x2e, + 0xb6, 0x58, 0x65, 0x30, 0xf7, 0x60, 0x7d, 0x94, 0xbd, 0x3f, 0xf3, 0x59, 0x00, 0x00, 0x00, 0xff, + 0xff, 0xf0, 0x0a, 0x3f, 0x2b, 0x03, 0x27, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryClient is the client API for Query service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryClient interface { + // Parameters queries the parameters of the module. + Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) + // Queries a LongBook by id. + LongBook(ctx context.Context, in *QueryGetLongBookRequest, opts ...grpc.CallOption) (*QueryGetLongBookResponse, error) + // Queries a list of LongBook items. + LongBookAll(ctx context.Context, in *QueryAllLongBookRequest, opts ...grpc.CallOption) (*QueryAllLongBookResponse, error) + // Queries a ShortBook by id. + ShortBook(ctx context.Context, in *QueryGetShortBookRequest, opts ...grpc.CallOption) (*QueryGetShortBookResponse, error) + // Queries a list of ShortBook items. + ShortBookAll(ctx context.Context, in *QueryAllShortBookRequest, opts ...grpc.CallOption) (*QueryAllShortBookResponse, error) + GetPrice(ctx context.Context, in *QueryGetPriceRequest, opts ...grpc.CallOption) (*QueryGetPriceResponse, error) + GetLatestPrice(ctx context.Context, in *QueryGetLatestPriceRequest, opts ...grpc.CallOption) (*QueryGetLatestPriceResponse, error) + GetPrices(ctx context.Context, in *QueryGetPricesRequest, opts ...grpc.CallOption) (*QueryGetPricesResponse, error) + GetTwaps(ctx context.Context, in *QueryGetTwapsRequest, opts ...grpc.CallOption) (*QueryGetTwapsResponse, error) + // Returns the metadata for a specified denom / display type + AssetMetadata(ctx context.Context, in *QueryAssetMetadataRequest, opts ...grpc.CallOption) (*QueryAssetMetadataResponse, error) + // Returns metadata for all the assets + AssetList(ctx context.Context, in *QueryAssetListRequest, opts ...grpc.CallOption) (*QueryAssetListResponse, error) + // Returns all registered pairs for specified contract address + GetRegisteredPairs(ctx context.Context, in *QueryRegisteredPairsRequest, opts ...grpc.CallOption) (*QueryRegisteredPairsResponse, error) + // Returns registered contract information + GetRegisteredContract(ctx context.Context, in *QueryRegisteredContractRequest, opts ...grpc.CallOption) (*QueryRegisteredContractResponse, error) + GetOrders(ctx context.Context, in *QueryGetOrdersRequest, opts ...grpc.CallOption) (*QueryGetOrdersResponse, error) + GetOrder(ctx context.Context, in *QueryGetOrderByIDRequest, opts ...grpc.CallOption) (*QueryGetOrderByIDResponse, error) + GetHistoricalPrices(ctx context.Context, in *QueryGetHistoricalPricesRequest, opts ...grpc.CallOption) (*QueryGetHistoricalPricesResponse, error) + GetMarketSummary(ctx context.Context, in *QueryGetMarketSummaryRequest, opts ...grpc.CallOption) (*QueryGetMarketSummaryResponse, error) + GetOrderSimulation(ctx context.Context, in *QueryOrderSimulationRequest, opts ...grpc.CallOption) (*QueryOrderSimulationResponse, error) + GetMatchResult(ctx context.Context, in *QueryGetMatchResultRequest, opts ...grpc.CallOption) (*QueryGetMatchResultResponse, error) + GetOrderCount(ctx context.Context, in *QueryGetOrderCountRequest, opts ...grpc.CallOption) (*QueryGetOrderCountResponse, error) +} + +type queryClient struct { + cc grpc1.ClientConn +} + +func NewQueryClient(cc grpc1.ClientConn) QueryClient { + return &queryClient{cc} +} + +func (c *queryClient) Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) { + out := new(QueryParamsResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/Params", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) LongBook(ctx context.Context, in *QueryGetLongBookRequest, opts ...grpc.CallOption) (*QueryGetLongBookResponse, error) { + out := new(QueryGetLongBookResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/LongBook", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) LongBookAll(ctx context.Context, in *QueryAllLongBookRequest, opts ...grpc.CallOption) (*QueryAllLongBookResponse, error) { + out := new(QueryAllLongBookResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/LongBookAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ShortBook(ctx context.Context, in *QueryGetShortBookRequest, opts ...grpc.CallOption) (*QueryGetShortBookResponse, error) { + out := new(QueryGetShortBookResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/ShortBook", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) ShortBookAll(ctx context.Context, in *QueryAllShortBookRequest, opts ...grpc.CallOption) (*QueryAllShortBookResponse, error) { + out := new(QueryAllShortBookResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/ShortBookAll", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetPrice(ctx context.Context, in *QueryGetPriceRequest, opts ...grpc.CallOption) (*QueryGetPriceResponse, error) { + out := new(QueryGetPriceResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetPrice", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetLatestPrice(ctx context.Context, in *QueryGetLatestPriceRequest, opts ...grpc.CallOption) (*QueryGetLatestPriceResponse, error) { + out := new(QueryGetLatestPriceResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetLatestPrice", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetPrices(ctx context.Context, in *QueryGetPricesRequest, opts ...grpc.CallOption) (*QueryGetPricesResponse, error) { + out := new(QueryGetPricesResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetPrices", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetTwaps(ctx context.Context, in *QueryGetTwapsRequest, opts ...grpc.CallOption) (*QueryGetTwapsResponse, error) { + out := new(QueryGetTwapsResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetTwaps", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AssetMetadata(ctx context.Context, in *QueryAssetMetadataRequest, opts ...grpc.CallOption) (*QueryAssetMetadataResponse, error) { + out := new(QueryAssetMetadataResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/AssetMetadata", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) AssetList(ctx context.Context, in *QueryAssetListRequest, opts ...grpc.CallOption) (*QueryAssetListResponse, error) { + out := new(QueryAssetListResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/AssetList", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetRegisteredPairs(ctx context.Context, in *QueryRegisteredPairsRequest, opts ...grpc.CallOption) (*QueryRegisteredPairsResponse, error) { + out := new(QueryRegisteredPairsResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetRegisteredPairs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetRegisteredContract(ctx context.Context, in *QueryRegisteredContractRequest, opts ...grpc.CallOption) (*QueryRegisteredContractResponse, error) { + out := new(QueryRegisteredContractResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetRegisteredContract", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetOrders(ctx context.Context, in *QueryGetOrdersRequest, opts ...grpc.CallOption) (*QueryGetOrdersResponse, error) { + out := new(QueryGetOrdersResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetOrders", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetOrder(ctx context.Context, in *QueryGetOrderByIDRequest, opts ...grpc.CallOption) (*QueryGetOrderByIDResponse, error) { + out := new(QueryGetOrderByIDResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetOrder", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetHistoricalPrices(ctx context.Context, in *QueryGetHistoricalPricesRequest, opts ...grpc.CallOption) (*QueryGetHistoricalPricesResponse, error) { + out := new(QueryGetHistoricalPricesResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetHistoricalPrices", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetMarketSummary(ctx context.Context, in *QueryGetMarketSummaryRequest, opts ...grpc.CallOption) (*QueryGetMarketSummaryResponse, error) { + out := new(QueryGetMarketSummaryResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetMarketSummary", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetOrderSimulation(ctx context.Context, in *QueryOrderSimulationRequest, opts ...grpc.CallOption) (*QueryOrderSimulationResponse, error) { + out := new(QueryOrderSimulationResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetOrderSimulation", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetMatchResult(ctx context.Context, in *QueryGetMatchResultRequest, opts ...grpc.CallOption) (*QueryGetMatchResultResponse, error) { + out := new(QueryGetMatchResultResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetMatchResult", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryClient) GetOrderCount(ctx context.Context, in *QueryGetOrderCountRequest, opts ...grpc.CallOption) (*QueryGetOrderCountResponse, error) { + out := new(QueryGetOrderCountResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Query/GetOrderCount", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryServer is the server API for Query service. +type QueryServer interface { + // Parameters queries the parameters of the module. + Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) + // Queries a LongBook by id. + LongBook(context.Context, *QueryGetLongBookRequest) (*QueryGetLongBookResponse, error) + // Queries a list of LongBook items. + LongBookAll(context.Context, *QueryAllLongBookRequest) (*QueryAllLongBookResponse, error) + // Queries a ShortBook by id. + ShortBook(context.Context, *QueryGetShortBookRequest) (*QueryGetShortBookResponse, error) + // Queries a list of ShortBook items. + ShortBookAll(context.Context, *QueryAllShortBookRequest) (*QueryAllShortBookResponse, error) + GetPrice(context.Context, *QueryGetPriceRequest) (*QueryGetPriceResponse, error) + GetLatestPrice(context.Context, *QueryGetLatestPriceRequest) (*QueryGetLatestPriceResponse, error) + GetPrices(context.Context, *QueryGetPricesRequest) (*QueryGetPricesResponse, error) + GetTwaps(context.Context, *QueryGetTwapsRequest) (*QueryGetTwapsResponse, error) + // Returns the metadata for a specified denom / display type + AssetMetadata(context.Context, *QueryAssetMetadataRequest) (*QueryAssetMetadataResponse, error) + // Returns metadata for all the assets + AssetList(context.Context, *QueryAssetListRequest) (*QueryAssetListResponse, error) + // Returns all registered pairs for specified contract address + GetRegisteredPairs(context.Context, *QueryRegisteredPairsRequest) (*QueryRegisteredPairsResponse, error) + // Returns registered contract information + GetRegisteredContract(context.Context, *QueryRegisteredContractRequest) (*QueryRegisteredContractResponse, error) + GetOrders(context.Context, *QueryGetOrdersRequest) (*QueryGetOrdersResponse, error) + GetOrder(context.Context, *QueryGetOrderByIDRequest) (*QueryGetOrderByIDResponse, error) + GetHistoricalPrices(context.Context, *QueryGetHistoricalPricesRequest) (*QueryGetHistoricalPricesResponse, error) + GetMarketSummary(context.Context, *QueryGetMarketSummaryRequest) (*QueryGetMarketSummaryResponse, error) + GetOrderSimulation(context.Context, *QueryOrderSimulationRequest) (*QueryOrderSimulationResponse, error) + GetMatchResult(context.Context, *QueryGetMatchResultRequest) (*QueryGetMatchResultResponse, error) + GetOrderCount(context.Context, *QueryGetOrderCountRequest) (*QueryGetOrderCountResponse, error) +} + +// UnimplementedQueryServer can be embedded to have forward compatible implementations. +type UnimplementedQueryServer struct { +} + +func (*UnimplementedQueryServer) Params(ctx context.Context, req *QueryParamsRequest) (*QueryParamsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Params not implemented") +} +func (*UnimplementedQueryServer) LongBook(ctx context.Context, req *QueryGetLongBookRequest) (*QueryGetLongBookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LongBook not implemented") +} +func (*UnimplementedQueryServer) LongBookAll(ctx context.Context, req *QueryAllLongBookRequest) (*QueryAllLongBookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method LongBookAll not implemented") +} +func (*UnimplementedQueryServer) ShortBook(ctx context.Context, req *QueryGetShortBookRequest) (*QueryGetShortBookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ShortBook not implemented") +} +func (*UnimplementedQueryServer) ShortBookAll(ctx context.Context, req *QueryAllShortBookRequest) (*QueryAllShortBookResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ShortBookAll not implemented") +} +func (*UnimplementedQueryServer) GetPrice(ctx context.Context, req *QueryGetPriceRequest) (*QueryGetPriceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPrice not implemented") +} +func (*UnimplementedQueryServer) GetLatestPrice(ctx context.Context, req *QueryGetLatestPriceRequest) (*QueryGetLatestPriceResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLatestPrice not implemented") +} +func (*UnimplementedQueryServer) GetPrices(ctx context.Context, req *QueryGetPricesRequest) (*QueryGetPricesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetPrices not implemented") +} +func (*UnimplementedQueryServer) GetTwaps(ctx context.Context, req *QueryGetTwapsRequest) (*QueryGetTwapsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTwaps not implemented") +} +func (*UnimplementedQueryServer) AssetMetadata(ctx context.Context, req *QueryAssetMetadataRequest) (*QueryAssetMetadataResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AssetMetadata not implemented") +} +func (*UnimplementedQueryServer) AssetList(ctx context.Context, req *QueryAssetListRequest) (*QueryAssetListResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method AssetList not implemented") +} +func (*UnimplementedQueryServer) GetRegisteredPairs(ctx context.Context, req *QueryRegisteredPairsRequest) (*QueryRegisteredPairsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRegisteredPairs not implemented") +} +func (*UnimplementedQueryServer) GetRegisteredContract(ctx context.Context, req *QueryRegisteredContractRequest) (*QueryRegisteredContractResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetRegisteredContract not implemented") +} +func (*UnimplementedQueryServer) GetOrders(ctx context.Context, req *QueryGetOrdersRequest) (*QueryGetOrdersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetOrders not implemented") +} +func (*UnimplementedQueryServer) GetOrder(ctx context.Context, req *QueryGetOrderByIDRequest) (*QueryGetOrderByIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetOrder not implemented") +} +func (*UnimplementedQueryServer) GetHistoricalPrices(ctx context.Context, req *QueryGetHistoricalPricesRequest) (*QueryGetHistoricalPricesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetHistoricalPrices not implemented") +} +func (*UnimplementedQueryServer) GetMarketSummary(ctx context.Context, req *QueryGetMarketSummaryRequest) (*QueryGetMarketSummaryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMarketSummary not implemented") +} +func (*UnimplementedQueryServer) GetOrderSimulation(ctx context.Context, req *QueryOrderSimulationRequest) (*QueryOrderSimulationResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetOrderSimulation not implemented") +} +func (*UnimplementedQueryServer) GetMatchResult(ctx context.Context, req *QueryGetMatchResultRequest) (*QueryGetMatchResultResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMatchResult not implemented") +} +func (*UnimplementedQueryServer) GetOrderCount(ctx context.Context, req *QueryGetOrderCountRequest) (*QueryGetOrderCountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetOrderCount not implemented") +} + +func RegisterQueryServer(s grpc1.Server, srv QueryServer) { + s.RegisterService(&_Query_serviceDesc, srv) +} + +func _Query_Params_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryParamsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).Params(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/Params", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).Params(ctx, req.(*QueryParamsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_LongBook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetLongBookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).LongBook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/LongBook", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).LongBook(ctx, req.(*QueryGetLongBookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_LongBookAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllLongBookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).LongBookAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/LongBookAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).LongBookAll(ctx, req.(*QueryAllLongBookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ShortBook_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetShortBookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ShortBook(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/ShortBook", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ShortBook(ctx, req.(*QueryGetShortBookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_ShortBookAll_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAllShortBookRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).ShortBookAll(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/ShortBookAll", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).ShortBookAll(ctx, req.(*QueryAllShortBookRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetPrice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetPriceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetPrice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetPrice", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetPrice(ctx, req.(*QueryGetPriceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetLatestPrice_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetLatestPriceRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetLatestPrice(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetLatestPrice", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetLatestPrice(ctx, req.(*QueryGetLatestPriceRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetPrices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetPricesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetPrices(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetPrices", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetPrices(ctx, req.(*QueryGetPricesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetTwaps_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetTwapsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetTwaps(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetTwaps", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetTwaps(ctx, req.(*QueryGetTwapsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AssetMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAssetMetadataRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AssetMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/AssetMetadata", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AssetMetadata(ctx, req.(*QueryAssetMetadataRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_AssetList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryAssetListRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).AssetList(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/AssetList", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).AssetList(ctx, req.(*QueryAssetListRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetRegisteredPairs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryRegisteredPairsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetRegisteredPairs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetRegisteredPairs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetRegisteredPairs(ctx, req.(*QueryRegisteredPairsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetRegisteredContract_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryRegisteredContractRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetRegisteredContract(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetRegisteredContract", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetRegisteredContract(ctx, req.(*QueryRegisteredContractRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetOrders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetOrdersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetOrders(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetOrders", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetOrders(ctx, req.(*QueryGetOrdersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetOrder_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetOrderByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetOrder(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetOrder", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetOrder(ctx, req.(*QueryGetOrderByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetHistoricalPrices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetHistoricalPricesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetHistoricalPrices(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetHistoricalPrices", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetHistoricalPrices(ctx, req.(*QueryGetHistoricalPricesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetMarketSummary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetMarketSummaryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetMarketSummary(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetMarketSummary", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetMarketSummary(ctx, req.(*QueryGetMarketSummaryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetOrderSimulation_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryOrderSimulationRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetOrderSimulation(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetOrderSimulation", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetOrderSimulation(ctx, req.(*QueryOrderSimulationRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetMatchResult_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetMatchResultRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetMatchResult(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetMatchResult", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetMatchResult(ctx, req.(*QueryGetMatchResultRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Query_GetOrderCount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryGetOrderCountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).GetOrderCount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Query/GetOrderCount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).GetOrderCount(ctx, req.(*QueryGetOrderCountRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Query_serviceDesc = grpc.ServiceDesc{ + ServiceName: "seiprotocol.seichain.dex.Query", + HandlerType: (*QueryServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Params", + Handler: _Query_Params_Handler, + }, + { + MethodName: "LongBook", + Handler: _Query_LongBook_Handler, + }, + { + MethodName: "LongBookAll", + Handler: _Query_LongBookAll_Handler, + }, + { + MethodName: "ShortBook", + Handler: _Query_ShortBook_Handler, + }, + { + MethodName: "ShortBookAll", + Handler: _Query_ShortBookAll_Handler, + }, + { + MethodName: "GetPrice", + Handler: _Query_GetPrice_Handler, + }, + { + MethodName: "GetLatestPrice", + Handler: _Query_GetLatestPrice_Handler, + }, + { + MethodName: "GetPrices", + Handler: _Query_GetPrices_Handler, + }, + { + MethodName: "GetTwaps", + Handler: _Query_GetTwaps_Handler, + }, + { + MethodName: "AssetMetadata", + Handler: _Query_AssetMetadata_Handler, + }, + { + MethodName: "AssetList", + Handler: _Query_AssetList_Handler, + }, + { + MethodName: "GetRegisteredPairs", + Handler: _Query_GetRegisteredPairs_Handler, + }, + { + MethodName: "GetRegisteredContract", + Handler: _Query_GetRegisteredContract_Handler, + }, + { + MethodName: "GetOrders", + Handler: _Query_GetOrders_Handler, + }, + { + MethodName: "GetOrder", + Handler: _Query_GetOrder_Handler, + }, + { + MethodName: "GetHistoricalPrices", + Handler: _Query_GetHistoricalPrices_Handler, + }, + { + MethodName: "GetMarketSummary", + Handler: _Query_GetMarketSummary_Handler, + }, + { + MethodName: "GetOrderSimulation", + Handler: _Query_GetOrderSimulation_Handler, + }, + { + MethodName: "GetMatchResult", + Handler: _Query_GetMatchResult_Handler, + }, + { + MethodName: "GetOrderCount", + Handler: _Query_GetOrderCount_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "dex/query.proto", +} + +func (m *QueryParamsRequest) 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 *QueryParamsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryParamsResponse) 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 *QueryParamsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryParamsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.Params.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryGetLongBookRequest) 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 *QueryGetLongBookRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetLongBookRequest) 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 = encodeVarintQuery(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x22 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x1a + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if len(m.Price) > 0 { + i -= len(m.Price) + copy(dAtA[i:], m.Price) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Price))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetLongBookResponse) 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 *QueryGetLongBookResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetLongBookResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.LongBook.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryAllLongBookRequest) 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 *QueryAllLongBookRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllLongBookRequest) 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 = encodeVarintQuery(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x22 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x1a + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAllLongBookResponse) 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 *QueryAllLongBookResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllLongBookResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.LongBook) > 0 { + for iNdEx := len(m.LongBook) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.LongBook[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryGetShortBookRequest) 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 *QueryGetShortBookRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetShortBookRequest) 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 = encodeVarintQuery(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x22 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x1a + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if len(m.Price) > 0 { + i -= len(m.Price) + copy(dAtA[i:], m.Price) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Price))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetShortBookResponse) 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 *QueryGetShortBookResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetShortBookResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + { + size, err := m.ShortBook.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *QueryAllShortBookRequest) 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 *QueryAllShortBookRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllShortBookRequest) 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 = encodeVarintQuery(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x22 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x1a + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAllShortBookResponse) 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 *QueryAllShortBookResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAllShortBookResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.ShortBook) > 0 { + for iNdEx := len(m.ShortBook) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.ShortBook[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryGetPricesRequest) 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 *QueryGetPricesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetPricesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x1a + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetPricesResponse) 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 *QueryGetPricesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetPricesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Prices) > 0 { + for iNdEx := len(m.Prices) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Prices[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryGetPriceRequest) 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 *QueryGetPriceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetPriceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timestamp != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x20 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x1a + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetPriceResponse) 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 *QueryGetPriceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetPriceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Found { + i-- + if m.Found { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if m.Price != nil { + { + size, err := m.Price.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetLatestPriceRequest) 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 *QueryGetLatestPriceRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetLatestPriceRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x1a + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.AssetDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.PriceDenom) > 0 { + i -= len(m.PriceDenom) + copy(dAtA[i:], m.PriceDenom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetLatestPriceResponse) 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 *QueryGetLatestPriceResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetLatestPriceResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Price != nil { + { + size, err := m.Price.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetTwapsRequest) 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 *QueryGetTwapsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetTwapsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.LookbackSeconds != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.LookbackSeconds)) + i-- + dAtA[i] = 0x10 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetTwapsResponse) 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 *QueryGetTwapsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetTwapsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Twaps) > 0 { + for iNdEx := len(m.Twaps) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Twaps[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryAssetListRequest) 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 *QueryAssetListRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAssetListRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryAssetListResponse) 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 *QueryAssetListResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAssetListResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.AssetList) > 0 { + for iNdEx := len(m.AssetList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.AssetList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryAssetMetadataRequest) 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 *QueryAssetMetadataRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAssetMetadataRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Denom) > 0 { + i -= len(m.Denom) + copy(dAtA[i:], m.Denom) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Denom))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryAssetMetadataResponse) 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 *QueryAssetMetadataResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryAssetMetadataResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Metadata != nil { + { + size, err := m.Metadata.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryRegisteredPairsRequest) 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 *QueryRegisteredPairsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRegisteredPairsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryRegisteredPairsResponse) 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 *QueryRegisteredPairsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRegisteredPairsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Pairs) > 0 { + for iNdEx := len(m.Pairs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Pairs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryRegisteredContractRequest) 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 *QueryRegisteredContractRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRegisteredContractRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryRegisteredContractResponse) 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 *QueryRegisteredContractResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryRegisteredContractResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ContractInfo != nil { + { + size, err := m.ContractInfo.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetOrdersRequest) 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 *QueryGetOrdersRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetOrdersRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintQuery(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0x12 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetOrdersResponse) 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 *QueryGetOrdersResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetOrdersResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Orders) > 0 { + for iNdEx := len(m.Orders) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Orders[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryGetOrderByIDRequest) 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 *QueryGetOrderByIDRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetOrderByIDRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Id != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x20 + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintQuery(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 = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetOrderByIDResponse) 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 *QueryGetOrderByIDResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetOrderByIDResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Order != nil { + { + size, err := m.Order.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetHistoricalPricesRequest) 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 *QueryGetHistoricalPricesRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetHistoricalPricesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.NumOfPeriods != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.NumOfPeriods)) + i-- + dAtA[i] = 0x28 + } + if m.PeriodLengthInSeconds != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.PeriodLengthInSeconds)) + i-- + dAtA[i] = 0x20 + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintQuery(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 = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetHistoricalPricesResponse) 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 *QueryGetHistoricalPricesResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetHistoricalPricesResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Prices) > 0 { + for iNdEx := len(m.Prices) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Prices[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *QueryGetMarketSummaryRequest) 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 *QueryGetMarketSummaryRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetMarketSummaryRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.LookbackInSeconds != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.LookbackInSeconds)) + i-- + dAtA[i] = 0x20 + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintQuery(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 = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetMarketSummaryResponse) 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 *QueryGetMarketSummaryResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetMarketSummaryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.LastPrice != nil { + { + size := m.LastPrice.Size() + i -= size + if _, err := m.LastPrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.LowPrice != nil { + { + size := m.LowPrice.Size() + i -= size + if _, err := m.LowPrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.HighPrice != nil { + { + size := m.HighPrice.Size() + i -= size + if _, err := m.HighPrice.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.TotalVolumeNotional != nil { + { + size := m.TotalVolumeNotional.Size() + i -= size + if _, err := m.TotalVolumeNotional.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.TotalVolume != nil { + { + size := m.TotalVolume.Size() + i -= size + if _, err := m.TotalVolume.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryOrderSimulationRequest) 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 *QueryOrderSimulationRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryOrderSimulationRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if m.Order != nil { + { + size, err := m.Order.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryOrderSimulationResponse) 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 *QueryOrderSimulationResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryOrderSimulationResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.ExecutedQuantity != nil { + { + size := m.ExecutedQuantity.Size() + i -= size + if _, err := m.ExecutedQuantity.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetMatchResultRequest) 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 *QueryGetMatchResultRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetMatchResultRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetMatchResultResponse) 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 *QueryGetMatchResultResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetMatchResultResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Result != nil { + { + size, err := m.Result.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetOrderCountRequest) 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 *QueryGetOrderCountRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetOrderCountRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.PositionDirection != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.PositionDirection)) + i-- + dAtA[i] = 0x28 + } + if m.Price != nil { + { + size := m.Price.Size() + i -= size + if _, err := m.Price.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintQuery(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintQuery(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 = encodeVarintQuery(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintQuery(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryGetOrderCountResponse) 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 *QueryGetOrderCountResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryGetOrderCountResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Count != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.Count)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { + offset -= sovQuery(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryParamsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryParamsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Params.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryGetLongBookRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Price) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetLongBookResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.LongBook.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryAllLongBookRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAllLongBookResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.LongBook) > 0 { + for _, e := range m.LongBook { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetShortBookRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Price) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetShortBookResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.ShortBook.Size() + n += 1 + l + sovQuery(uint64(l)) + return n +} + +func (m *QueryAllShortBookRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAllShortBookResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.ShortBook) > 0 { + for _, e := range m.ShortBook { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetPricesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetPricesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Prices) > 0 { + for _, e := range m.Prices { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryGetPriceRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Timestamp != 0 { + n += 1 + sovQuery(uint64(m.Timestamp)) + } + return n +} + +func (m *QueryGetPriceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Price != nil { + l = m.Price.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.Found { + n += 2 + } + return n +} + +func (m *QueryGetLatestPriceRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetLatestPriceResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Price != nil { + l = m.Price.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetTwapsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.LookbackSeconds != 0 { + n += 1 + sovQuery(uint64(m.LookbackSeconds)) + } + return n +} + +func (m *QueryGetTwapsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Twaps) > 0 { + for _, e := range m.Twaps { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryAssetListRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryAssetListResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.AssetList) > 0 { + for _, e := range m.AssetList { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryAssetMetadataRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Denom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryAssetMetadataResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Metadata != nil { + l = m.Metadata.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryRegisteredPairsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryRegisteredPairsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Pairs) > 0 { + for _, e := range m.Pairs { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryRegisteredContractRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryRegisteredContractResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ContractInfo != nil { + l = m.ContractInfo.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetOrdersRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.Account) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetOrdersResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Orders) > 0 { + for _, e := range m.Orders { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryGetOrderByIDRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Id != 0 { + n += 1 + sovQuery(uint64(m.Id)) + } + return n +} + +func (m *QueryGetOrderByIDResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Order != nil { + l = m.Order.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetHistoricalPricesRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.PeriodLengthInSeconds != 0 { + n += 1 + sovQuery(uint64(m.PeriodLengthInSeconds)) + } + if m.NumOfPeriods != 0 { + n += 1 + sovQuery(uint64(m.NumOfPeriods)) + } + return n +} + +func (m *QueryGetHistoricalPricesResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Prices) > 0 { + for _, e := range m.Prices { + l = e.Size() + n += 1 + l + sovQuery(uint64(l)) + } + } + return n +} + +func (m *QueryGetMarketSummaryRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.LookbackInSeconds != 0 { + n += 1 + sovQuery(uint64(m.LookbackInSeconds)) + } + return n +} + +func (m *QueryGetMarketSummaryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.TotalVolume != nil { + l = m.TotalVolume.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.TotalVolumeNotional != nil { + l = m.TotalVolumeNotional.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.HighPrice != nil { + l = m.HighPrice.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.LowPrice != nil { + l = m.LowPrice.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.LastPrice != nil { + l = m.LastPrice.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryOrderSimulationRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Order != nil { + l = m.Order.Size() + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryOrderSimulationResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.ExecutedQuantity != nil { + l = m.ExecutedQuantity.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetMatchResultRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetMatchResultResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Result != nil { + l = m.Result.Size() + n += 1 + l + sovQuery(uint64(l)) + } + return n +} + +func (m *QueryGetOrderCountRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovQuery(uint64(l)) + } + if m.Price != nil { + l = m.Price.Size() + n += 1 + l + sovQuery(uint64(l)) + } + if m.PositionDirection != 0 { + n += 1 + sovQuery(uint64(m.PositionDirection)) + } + return n +} + +func (m *QueryGetOrderCountResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Count != 0 { + n += 1 + sovQuery(uint64(m.Count)) + } + return n +} + +func sovQuery(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQuery(x uint64) (n int) { + return sovQuery(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryParamsRequest) 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 ErrIntOverflowQuery + } + 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: QueryParamsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryParamsResponse) 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 ErrIntOverflowQuery + } + 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: QueryParamsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryParamsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Params", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Params.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetLongBookRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetLongBookRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetLongBookRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Price = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetLongBookResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetLongBookResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetLongBookResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LongBook", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.LongBook.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAllLongBookRequest) 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 ErrIntOverflowQuery + } + 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: QueryAllLongBookRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllLongBookRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAllLongBookResponse) 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 ErrIntOverflowQuery + } + 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: QueryAllLongBookResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllLongBookResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LongBook", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.LongBook = append(m.LongBook, LongBook{}) + if err := m.LongBook[len(m.LongBook)-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 Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetShortBookRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetShortBookRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetShortBookRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Price = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetShortBookResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetShortBookResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetShortBookResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShortBook", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ShortBook.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAllShortBookRequest) 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 ErrIntOverflowQuery + } + 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: QueryAllShortBookRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllShortBookRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAllShortBookResponse) 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 ErrIntOverflowQuery + } + 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: QueryAllShortBookResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAllShortBookResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ShortBook", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ShortBook = append(m.ShortBook, ShortBook{}) + if err := m.ShortBook[len(m.ShortBook)-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 Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetPricesRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetPricesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetPricesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetPricesResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetPricesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetPricesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Prices", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Prices = append(m.Prices, &Price{}) + if err := m.Prices[len(m.Prices)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetPriceRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetPriceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetPriceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetPriceResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetPriceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetPriceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Price == nil { + m.Price = &Price{} + } + if err := m.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Found", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Found = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetLatestPriceRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetLatestPriceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetLatestPriceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PriceDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetLatestPriceResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetLatestPriceResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetLatestPriceResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Price == nil { + m.Price = &Price{} + } + if err := m.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetTwapsRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetTwapsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetTwapsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LookbackSeconds", wireType) + } + m.LookbackSeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LookbackSeconds |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetTwapsResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetTwapsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetTwapsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Twaps", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Twaps = append(m.Twaps, &Twap{}) + if err := m.Twaps[len(m.Twaps)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAssetListRequest) 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 ErrIntOverflowQuery + } + 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: QueryAssetListRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAssetListRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAssetListResponse) 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 ErrIntOverflowQuery + } + 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: QueryAssetListResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAssetListResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AssetList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetList = append(m.AssetList, AssetMetadata{}) + if err := m.AssetList[len(m.AssetList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAssetMetadataRequest) 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 ErrIntOverflowQuery + } + 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: QueryAssetMetadataRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAssetMetadataRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryAssetMetadataResponse) 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 ErrIntOverflowQuery + } + 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: QueryAssetMetadataResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryAssetMetadataResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Metadata", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Metadata == nil { + m.Metadata = &AssetMetadata{} + } + if err := m.Metadata.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryRegisteredPairsRequest) 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 ErrIntOverflowQuery + } + 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: QueryRegisteredPairsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryRegisteredPairsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryRegisteredPairsResponse) 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 ErrIntOverflowQuery + } + 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: QueryRegisteredPairsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryRegisteredPairsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pairs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Pairs = append(m.Pairs, Pair{}) + if err := m.Pairs[len(m.Pairs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryRegisteredContractRequest) 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 ErrIntOverflowQuery + } + 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: QueryRegisteredContractRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryRegisteredContractRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryRegisteredContractResponse) 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 ErrIntOverflowQuery + } + 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: QueryRegisteredContractResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryRegisteredContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractInfo", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ContractInfo == nil { + m.ContractInfo = &ContractInfoV2{} + } + if err := m.ContractInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetOrdersRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetOrdersRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetOrdersRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetOrdersResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetOrdersResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetOrdersResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Orders", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Orders = append(m.Orders, &Order{}) + if err := m.Orders[len(m.Orders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetOrderByIDRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetOrderByIDRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetOrderByIDRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetOrderByIDResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetOrderByIDResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetOrderByIDResponse: 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 ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Order == nil { + m.Order = &Order{} + } + if err := m.Order.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetHistoricalPricesRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetHistoricalPricesRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetHistoricalPricesRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PeriodLengthInSeconds", wireType) + } + m.PeriodLengthInSeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PeriodLengthInSeconds |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumOfPeriods", wireType) + } + m.NumOfPeriods = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumOfPeriods |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetHistoricalPricesResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetHistoricalPricesResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetHistoricalPricesResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Prices", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Prices = append(m.Prices, &PriceCandlestick{}) + if err := m.Prices[len(m.Prices)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetMarketSummaryRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetMarketSummaryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetMarketSummaryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LookbackInSeconds", wireType) + } + m.LookbackInSeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LookbackInSeconds |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetMarketSummaryResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetMarketSummaryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetMarketSummaryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalVolume", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.TotalVolume = &v + if err := m.TotalVolume.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalVolumeNotional", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.TotalVolumeNotional = &v + if err := m.TotalVolumeNotional.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field HighPrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.HighPrice = &v + if err := m.HighPrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LowPrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.LowPrice = &v + if err := m.LowPrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field LastPrice", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.LastPrice = &v + if err := m.LastPrice.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryOrderSimulationRequest) 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 ErrIntOverflowQuery + } + 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: QueryOrderSimulationRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryOrderSimulationRequest: 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 ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Order == nil { + m.Order = &Order{} + } + if err := m.Order.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryOrderSimulationResponse) 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 ErrIntOverflowQuery + } + 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: QueryOrderSimulationResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryOrderSimulationResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutedQuantity", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.ExecutedQuantity = &v + if err := m.ExecutedQuantity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetMatchResultRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetMatchResultRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetMatchResultRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetMatchResultResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetMatchResultResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetMatchResultResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Result", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQuery + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Result == nil { + m.Result = &MatchResult{} + } + if err := m.Result.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetOrderCountRequest) 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 ErrIntOverflowQuery + } + 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: QueryGetOrderCountRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetOrderCountRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + 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 ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + 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 ErrInvalidLengthQuery + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQuery + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var v github_com_cosmos_cosmos_sdk_types.Dec + m.Price = &v + if err := m.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PositionDirection", wireType) + } + m.PositionDirection = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PositionDirection |= PositionDirection(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryGetOrderCountResponse) 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 ErrIntOverflowQuery + } + 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: QueryGetOrderCountResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryGetOrderCountResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Count", wireType) + } + m.Count = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Count |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQuery(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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrIntOverflowQuery + } + 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, ErrInvalidLengthQuery + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQuery + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQuery + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQuery = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQuery = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQuery = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/query.pb.gw.go b/x/dex/types/query.pb.gw.go new file mode 100644 index 000000000..d7d13cf88 --- /dev/null +++ b/x/dex/types/query.pb.gw.go @@ -0,0 +1,2389 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: dex/query.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := client.Params(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_Params_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryParamsRequest + var metadata runtime.ServerMetadata + + msg, err := server.Params(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_LongBook_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetLongBookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["price"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "price") + } + + protoReq.Price, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "price", err) + } + + msg, err := client.LongBook(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_LongBook_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetLongBookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["price"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "price") + } + + protoReq.Price, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "price", err) + } + + msg, err := server.LongBook(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_LongBookAll_0 = &utilities.DoubleArray{Encoding: map[string]int{"contractAddr": 0, "priceDenom": 1, "assetDenom": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}} +) + +func request_Query_LongBookAll_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllLongBookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_LongBookAll_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.LongBookAll(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_LongBookAll_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllLongBookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_LongBookAll_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.LongBookAll(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_ShortBook_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetShortBookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["price"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "price") + } + + protoReq.Price, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "price", err) + } + + msg, err := client.ShortBook(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ShortBook_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetShortBookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["price"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "price") + } + + protoReq.Price, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "price", err) + } + + msg, err := server.ShortBook(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_ShortBookAll_0 = &utilities.DoubleArray{Encoding: map[string]int{"contractAddr": 0, "priceDenom": 1, "assetDenom": 2}, Base: []int{1, 1, 2, 3, 0, 0, 0}, Check: []int{0, 1, 1, 1, 2, 3, 4}} +) + +func request_Query_ShortBookAll_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllShortBookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ShortBookAll_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ShortBookAll(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_ShortBookAll_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAllShortBookRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_ShortBookAll_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ShortBookAll(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetPrice_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetPriceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["timestamp"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "timestamp") + } + + protoReq.Timestamp, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "timestamp", err) + } + + msg, err := client.GetPrice(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetPrice_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetPriceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["timestamp"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "timestamp") + } + + protoReq.Timestamp, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "timestamp", err) + } + + msg, err := server.GetPrice(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetLatestPrice_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetLatestPriceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + msg, err := client.GetLatestPrice(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetLatestPrice_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetLatestPriceRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + msg, err := server.GetLatestPrice(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetPrices_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetPricesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + msg, err := client.GetPrices(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetPrices_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetPricesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + msg, err := server.GetPrices(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetTwaps_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetTwapsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["lookbackSeconds"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "lookbackSeconds") + } + + protoReq.LookbackSeconds, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "lookbackSeconds", err) + } + + msg, err := client.GetTwaps(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetTwaps_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetTwapsRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["lookbackSeconds"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "lookbackSeconds") + } + + protoReq.LookbackSeconds, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "lookbackSeconds", err) + } + + msg, err := server.GetTwaps(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_AssetMetadata_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAssetMetadataRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["denom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom") + } + + protoReq.Denom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err) + } + + msg, err := client.AssetMetadata(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AssetMetadata_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAssetMetadataRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["denom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "denom") + } + + protoReq.Denom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "denom", err) + } + + msg, err := server.AssetMetadata(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_AssetList_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAssetListRequest + var metadata runtime.ServerMetadata + + msg, err := client.AssetList(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_AssetList_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryAssetListRequest + var metadata runtime.ServerMetadata + + msg, err := server.AssetList(ctx, &protoReq) + return msg, metadata, err + +} + +var ( + filter_Query_GetRegisteredPairs_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_Query_GetRegisteredPairs_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRegisteredPairsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetRegisteredPairs_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.GetRegisteredPairs(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetRegisteredPairs_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRegisteredPairsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_GetRegisteredPairs_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.GetRegisteredPairs(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetRegisteredContract_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRegisteredContractRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + msg, err := client.GetRegisteredContract(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetRegisteredContract_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryRegisteredContractRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + msg, err := server.GetRegisteredContract(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetOrders_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetOrdersRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["account"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "account") + } + + protoReq.Account, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "account", err) + } + + msg, err := client.GetOrders(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetOrders_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetOrdersRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["account"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "account") + } + + protoReq.Account, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "account", err) + } + + msg, err := server.GetOrders(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetOrder_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetOrderByIDRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := client.GetOrder(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetOrder_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetOrderByIDRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id") + } + + protoReq.Id, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) + } + + msg, err := server.GetOrder(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetHistoricalPrices_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetHistoricalPricesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["periodLengthInSeconds"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "periodLengthInSeconds") + } + + protoReq.PeriodLengthInSeconds, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "periodLengthInSeconds", err) + } + + val, ok = pathParams["numOfPeriods"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "numOfPeriods") + } + + protoReq.NumOfPeriods, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "numOfPeriods", err) + } + + msg, err := client.GetHistoricalPrices(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetHistoricalPrices_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetHistoricalPricesRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["periodLengthInSeconds"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "periodLengthInSeconds") + } + + protoReq.PeriodLengthInSeconds, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "periodLengthInSeconds", err) + } + + val, ok = pathParams["numOfPeriods"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "numOfPeriods") + } + + protoReq.NumOfPeriods, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "numOfPeriods", err) + } + + msg, err := server.GetHistoricalPrices(ctx, &protoReq) + return msg, metadata, err + +} + +func request_Query_GetMarketSummary_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetMarketSummaryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["lookbackInSeconds"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "lookbackInSeconds") + } + + protoReq.LookbackInSeconds, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "lookbackInSeconds", err) + } + + msg, err := client.GetMarketSummary(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_GetMarketSummary_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryGetMarketSummaryRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["contractAddr"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "contractAddr") + } + + protoReq.ContractAddr, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "contractAddr", err) + } + + val, ok = pathParams["priceDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "priceDenom") + } + + protoReq.PriceDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "priceDenom", err) + } + + val, ok = pathParams["assetDenom"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "assetDenom") + } + + protoReq.AssetDenom, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "assetDenom", err) + } + + val, ok = pathParams["lookbackInSeconds"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "lookbackInSeconds") + } + + protoReq.LookbackInSeconds, err = runtime.Uint64(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "lookbackInSeconds", err) + } + + msg, err := server.GetMarketSummary(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". +// UnaryRPC :call QueryServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryHandlerFromEndpoint instead. +func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryServer) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_Params_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_LongBook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_LongBook_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_LongBook_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_LongBookAll_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_LongBookAll_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_LongBookAll_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ShortBook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ShortBook_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ShortBook_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ShortBookAll_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_ShortBookAll_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ShortBookAll_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetPrice_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetPrice_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetPrice_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetLatestPrice_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetLatestPrice_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetLatestPrice_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetPrices_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetPrices_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetPrices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetTwaps_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetTwaps_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetTwaps_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AssetMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AssetMetadata_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AssetMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AssetList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_AssetList_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AssetList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetRegisteredPairs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetRegisteredPairs_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetRegisteredPairs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetRegisteredContract_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetRegisteredContract_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetRegisteredContract_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetOrders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetOrders_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetOrders_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetOrder_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetOrder_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetOrder_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetHistoricalPrices_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetHistoricalPrices_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetHistoricalPrices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetMarketSummary_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_GetMarketSummary_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetMarketSummary_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryHandlerFromEndpoint is same as RegisterQueryHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryHandler(ctx, mux, conn) +} + +// RegisterQueryHandler registers the http handlers for service Query to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryHandlerClient(ctx, mux, NewQueryClient(conn)) +} + +// RegisterQueryHandlerClient registers the http handlers for service Query +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryClient" to call the correct interceptors. +func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryClient) error { + + mux.Handle("GET", pattern_Query_Params_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_Params_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_Params_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_LongBook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_LongBook_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_LongBook_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_LongBookAll_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_LongBookAll_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_LongBookAll_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ShortBook_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ShortBook_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ShortBook_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_ShortBookAll_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_ShortBookAll_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_ShortBookAll_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetPrice_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetPrice_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetPrice_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetLatestPrice_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetLatestPrice_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetLatestPrice_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetPrices_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetPrices_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetPrices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetTwaps_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetTwaps_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetTwaps_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AssetMetadata_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AssetMetadata_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AssetMetadata_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_AssetList_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_AssetList_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_AssetList_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetRegisteredPairs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetRegisteredPairs_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetRegisteredPairs_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetRegisteredContract_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetRegisteredContract_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetRegisteredContract_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetOrders_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetOrders_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetOrders_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetOrder_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetOrder_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetOrder_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetHistoricalPrices_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetHistoricalPrices_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetHistoricalPrices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_Query_GetMarketSummary_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_GetMarketSummary_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_GetMarketSummary_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_Query_Params_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"sei-protocol", "seichain", "dex", "params"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_LongBook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6, 1, 0, 4, 1, 5, 7}, []string{"sei-protocol", "seichain", "dex", "long_book", "contractAddr", "priceDenom", "assetDenom", "price"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_LongBookAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6}, []string{"sei-protocol", "seichain", "dex", "long_book", "contractAddr", "priceDenom", "assetDenom"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_ShortBook_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6, 1, 0, 4, 1, 5, 7}, []string{"sei-protocol", "seichain", "dex", "short_book", "contractAddr", "priceDenom", "assetDenom", "price"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_ShortBookAll_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6}, []string{"sei-protocol", "seichain", "dex", "short_book", "contractAddr", "priceDenom", "assetDenom"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetPrice_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6, 1, 0, 4, 1, 5, 7}, []string{"sei-protocol", "seichain", "dex", "get_price", "contractAddr", "priceDenom", "assetDenom", "timestamp"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetLatestPrice_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6}, []string{"sei-protocol", "seichain", "dex", "get_latest_price", "contractAddr", "priceDenom", "assetDenom"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetPrices_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6}, []string{"sei-protocol", "seichain", "dex", "get_prices", "contractAddr", "priceDenom", "assetDenom"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetTwaps_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"sei-protocol", "seichain", "dex", "get_twaps", "contractAddr", "lookbackSeconds"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_AssetMetadata_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"sei-protocol", "seichain", "dex", "asset_list", "denom"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_AssetList_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"sei-protocol", "seichain", "dex", "asset_list"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetRegisteredPairs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"sei-protocol", "seichain", "dex", "registered_pairs"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetRegisteredContract_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"sei-protocol", "seichain", "dex", "registered_contract", "contractAddr"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetOrders_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5}, []string{"sei-protocol", "seichain", "dex", "get_orders", "contractAddr", "account"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetOrder_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6, 1, 0, 4, 1, 5, 7}, []string{"sei-protocol", "seichain", "dex", "get_order_by_id", "contractAddr", "priceDenom", "assetDenom", "id"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetHistoricalPrices_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6, 1, 0, 4, 1, 5, 7, 1, 0, 4, 1, 5, 8}, []string{"sei-protocol", "seichain", "dex", "get_historical_prices", "contractAddr", "priceDenom", "assetDenom", "periodLengthInSeconds", "numOfPeriods"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_Query_GetMarketSummary_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4, 1, 0, 4, 1, 5, 5, 1, 0, 4, 1, 5, 6, 1, 0, 4, 1, 5, 7}, []string{"sei-protocol", "seichain", "dex", "get_market_summary", "contractAddr", "priceDenom", "assetDenom", "lookbackInSeconds"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_Query_Params_0 = runtime.ForwardResponseMessage + + forward_Query_LongBook_0 = runtime.ForwardResponseMessage + + forward_Query_LongBookAll_0 = runtime.ForwardResponseMessage + + forward_Query_ShortBook_0 = runtime.ForwardResponseMessage + + forward_Query_ShortBookAll_0 = runtime.ForwardResponseMessage + + forward_Query_GetPrice_0 = runtime.ForwardResponseMessage + + forward_Query_GetLatestPrice_0 = runtime.ForwardResponseMessage + + forward_Query_GetPrices_0 = runtime.ForwardResponseMessage + + forward_Query_GetTwaps_0 = runtime.ForwardResponseMessage + + forward_Query_AssetMetadata_0 = runtime.ForwardResponseMessage + + forward_Query_AssetList_0 = runtime.ForwardResponseMessage + + forward_Query_GetRegisteredPairs_0 = runtime.ForwardResponseMessage + + forward_Query_GetRegisteredContract_0 = runtime.ForwardResponseMessage + + forward_Query_GetOrders_0 = runtime.ForwardResponseMessage + + forward_Query_GetOrder_0 = runtime.ForwardResponseMessage + + forward_Query_GetHistoricalPrices_0 = runtime.ForwardResponseMessage + + forward_Query_GetMarketSummary_0 = runtime.ForwardResponseMessage +) diff --git a/x/dex/types/settlement.go b/x/dex/types/settlement.go new file mode 100644 index 000000000..ee3d3378e --- /dev/null +++ b/x/dex/types/settlement.go @@ -0,0 +1,36 @@ +package types + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +type SudoSettlementMsg struct { + Settlement Settlements `json:"settlement"` +} + +func NewSettlementEntry( + ctx sdk.Context, + orderID uint64, + account string, + direction PositionDirection, + priceDenom string, + assetDenom string, + quantity sdk.Dec, + executionCostOrProceed sdk.Dec, + expectedCostOrProceed sdk.Dec, + orderType OrderType, +) *SettlementEntry { + return &SettlementEntry{ + OrderId: orderID, + PositionDirection: GetContractPositionDirection(direction), + PriceDenom: priceDenom, + AssetDenom: assetDenom, + Quantity: quantity, + ExecutionCostOrProceed: executionCostOrProceed, + ExpectedCostOrProceed: expectedCostOrProceed, + Account: account, + OrderType: GetContractOrderType(orderType), + Timestamp: uint64(ctx.BlockTime().Unix()), + Height: uint64(ctx.BlockHeight()), + } +} diff --git a/x/dex/types/settlement.pb.go b/x/dex/types/settlement.pb.go new file mode 100644 index 000000000..0df73a0cc --- /dev/null +++ b/x/dex/types/settlement.pb.go @@ -0,0 +1,1044 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/settlement.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 SettlementEntry struct { + Account string `protobuf:"bytes,1,opt,name=account,proto3" json:"account"` + PriceDenom string `protobuf:"bytes,2,opt,name=priceDenom,proto3" json:"price_denom"` + AssetDenom string `protobuf:"bytes,3,opt,name=assetDenom,proto3" json:"asset_denom"` + Quantity github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=quantity,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"quantity" yaml:"quantity"` + ExecutionCostOrProceed github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=executionCostOrProceed,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"execution_cost_or_proceed" yaml:"execution_cost_or_proceed"` + ExpectedCostOrProceed github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,6,opt,name=expectedCostOrProceed,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"expected_cost_or_proceed" yaml:"expected_cost_or_proceed"` + PositionDirection string `protobuf:"bytes,7,opt,name=positionDirection,proto3" json:"position_direction"` + OrderType string `protobuf:"bytes,8,opt,name=orderType,proto3" json:"order_type"` + OrderId uint64 `protobuf:"varint,9,opt,name=orderId,proto3" json:"order_id"` + Timestamp uint64 `protobuf:"varint,10,opt,name=timestamp,proto3" json:"timestamp"` + Height uint64 `protobuf:"varint,11,opt,name=height,proto3" json:"height"` + SettlementId uint64 `protobuf:"varint,12,opt,name=settlementId,proto3" json:"settlement_id"` +} + +func (m *SettlementEntry) Reset() { *m = SettlementEntry{} } +func (m *SettlementEntry) String() string { return proto.CompactTextString(m) } +func (*SettlementEntry) ProtoMessage() {} +func (*SettlementEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_c24d83c09612bb1c, []int{0} +} +func (m *SettlementEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SettlementEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SettlementEntry.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 *SettlementEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_SettlementEntry.Merge(m, src) +} +func (m *SettlementEntry) XXX_Size() int { + return m.Size() +} +func (m *SettlementEntry) XXX_DiscardUnknown() { + xxx_messageInfo_SettlementEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_SettlementEntry proto.InternalMessageInfo + +func (m *SettlementEntry) GetAccount() string { + if m != nil { + return m.Account + } + return "" +} + +func (m *SettlementEntry) GetPriceDenom() string { + if m != nil { + return m.PriceDenom + } + return "" +} + +func (m *SettlementEntry) GetAssetDenom() string { + if m != nil { + return m.AssetDenom + } + return "" +} + +func (m *SettlementEntry) GetPositionDirection() string { + if m != nil { + return m.PositionDirection + } + return "" +} + +func (m *SettlementEntry) GetOrderType() string { + if m != nil { + return m.OrderType + } + return "" +} + +func (m *SettlementEntry) GetOrderId() uint64 { + if m != nil { + return m.OrderId + } + return 0 +} + +func (m *SettlementEntry) GetTimestamp() uint64 { + if m != nil { + return m.Timestamp + } + return 0 +} + +func (m *SettlementEntry) GetHeight() uint64 { + if m != nil { + return m.Height + } + return 0 +} + +func (m *SettlementEntry) GetSettlementId() uint64 { + if m != nil { + return m.SettlementId + } + return 0 +} + +type Settlements struct { + Epoch int64 `protobuf:"varint,1,opt,name=epoch,proto3" json:"epoch"` + Entries []*SettlementEntry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries"` +} + +func (m *Settlements) Reset() { *m = Settlements{} } +func (m *Settlements) String() string { return proto.CompactTextString(m) } +func (*Settlements) ProtoMessage() {} +func (*Settlements) Descriptor() ([]byte, []int) { + return fileDescriptor_c24d83c09612bb1c, []int{1} +} +func (m *Settlements) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Settlements) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Settlements.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 *Settlements) XXX_Merge(src proto.Message) { + xxx_messageInfo_Settlements.Merge(m, src) +} +func (m *Settlements) XXX_Size() int { + return m.Size() +} +func (m *Settlements) XXX_DiscardUnknown() { + xxx_messageInfo_Settlements.DiscardUnknown(m) +} + +var xxx_messageInfo_Settlements proto.InternalMessageInfo + +func (m *Settlements) GetEpoch() int64 { + if m != nil { + return m.Epoch + } + return 0 +} + +func (m *Settlements) GetEntries() []*SettlementEntry { + if m != nil { + return m.Entries + } + return nil +} + +func init() { + proto.RegisterType((*SettlementEntry)(nil), "seiprotocol.seichain.dex.SettlementEntry") + proto.RegisterType((*Settlements)(nil), "seiprotocol.seichain.dex.Settlements") +} + +func init() { proto.RegisterFile("dex/settlement.proto", fileDescriptor_c24d83c09612bb1c) } + +var fileDescriptor_c24d83c09612bb1c = []byte{ + // 584 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x94, 0x3f, 0x6f, 0xdb, 0x3c, + 0x10, 0xc6, 0xad, 0xfc, 0xb1, 0x63, 0x3a, 0x79, 0x83, 0x10, 0x79, 0x03, 0xb6, 0x83, 0x68, 0x08, + 0x68, 0x90, 0xa2, 0x8d, 0x04, 0xb4, 0xe8, 0xd2, 0xd1, 0x75, 0x51, 0x64, 0x28, 0x1a, 0xb0, 0x9d, + 0xba, 0x08, 0x0a, 0x75, 0xb0, 0x89, 0x46, 0xa2, 0x2a, 0xd2, 0x80, 0xbd, 0xf5, 0x23, 0xf4, 0x3b, + 0x74, 0xe8, 0x57, 0xc9, 0x98, 0xb1, 0xe8, 0x40, 0x14, 0xc9, 0xa6, 0x31, 0x5b, 0xb7, 0x42, 0x94, + 0x65, 0x25, 0xad, 0x3d, 0x64, 0xe2, 0xf1, 0xb9, 0xdf, 0xdd, 0x3d, 0x86, 0x79, 0x42, 0xfb, 0x31, + 0x4c, 0x03, 0x05, 0x5a, 0x9f, 0x43, 0x02, 0xa9, 0xf6, 0xb3, 0x5c, 0x6a, 0x89, 0x89, 0x02, 0x61, + 0x23, 0x2e, 0xcf, 0x7d, 0x05, 0x82, 0x8f, 0x23, 0x91, 0xfa, 0x31, 0x4c, 0x1f, 0xee, 0x8f, 0xe4, + 0x48, 0xda, 0x54, 0x50, 0x46, 0x15, 0xef, 0xfd, 0x6e, 0xa3, 0xdd, 0xf7, 0x8b, 0x26, 0xaf, 0x53, + 0x9d, 0xcf, 0xf0, 0x23, 0xd4, 0x89, 0x38, 0x97, 0x93, 0x54, 0x13, 0xa7, 0xef, 0x1c, 0x75, 0x07, + 0xbd, 0xc2, 0xd0, 0x5a, 0x62, 0x75, 0x80, 0x03, 0x84, 0xb2, 0x5c, 0x70, 0x18, 0x42, 0x2a, 0x13, + 0xb2, 0x66, 0xc9, 0xdd, 0xc2, 0xd0, 0x9e, 0x55, 0xc3, 0xb8, 0x94, 0xd9, 0x2d, 0xa4, 0x2c, 0x88, + 0x94, 0x02, 0x5d, 0x15, 0xac, 0x37, 0x05, 0x56, 0xad, 0x0b, 0x1a, 0x04, 0x0b, 0xb4, 0xf5, 0x79, + 0x12, 0xa5, 0x5a, 0xe8, 0x19, 0xd9, 0xb0, 0xf8, 0xdb, 0x0b, 0x43, 0x5b, 0x3f, 0x0d, 0x3d, 0x1c, + 0x09, 0x3d, 0x9e, 0x9c, 0xf9, 0x5c, 0x26, 0x01, 0x97, 0x2a, 0x91, 0x6a, 0x7e, 0x1c, 0xab, 0xf8, + 0x53, 0xa0, 0x67, 0x19, 0x28, 0x7f, 0x08, 0xbc, 0x30, 0x74, 0xd1, 0xe1, 0xc6, 0xd0, 0xdd, 0x59, + 0x94, 0x9c, 0xbf, 0xf4, 0x6a, 0xc5, 0x63, 0x8b, 0x24, 0xfe, 0xee, 0xa0, 0x03, 0x98, 0x02, 0x9f, + 0x68, 0x21, 0xd3, 0x57, 0x52, 0xe9, 0x77, 0xf9, 0x69, 0x2e, 0x39, 0x40, 0x4c, 0x36, 0xed, 0x64, + 0x79, 0xef, 0xc9, 0x0f, 0x16, 0xfd, 0x42, 0x2e, 0x95, 0x0e, 0x65, 0x1e, 0x66, 0x55, 0xcb, 0x1b, + 0x43, 0xfb, 0x95, 0x95, 0x95, 0x88, 0xc7, 0x56, 0xd8, 0xc1, 0xdf, 0x1c, 0xf4, 0x3f, 0x4c, 0x33, + 0xe0, 0x1a, 0xe2, 0xbb, 0x46, 0xdb, 0xd6, 0x68, 0x72, 0x6f, 0xa3, 0xa4, 0x6e, 0xb7, 0xc4, 0x27, + 0xad, 0x7d, 0x2e, 0x27, 0x3c, 0xb6, 0xdc, 0x0b, 0x1e, 0xa2, 0xbd, 0x4c, 0x2a, 0x51, 0xda, 0x1f, + 0x8a, 0x1c, 0x78, 0x19, 0x90, 0x8e, 0x35, 0x78, 0x50, 0x18, 0x8a, 0xeb, 0x64, 0x18, 0xd7, 0x59, + 0xf6, 0x6f, 0x01, 0x7e, 0x8a, 0xba, 0x32, 0x8f, 0x21, 0xff, 0x30, 0xcb, 0x80, 0x6c, 0xd9, 0xea, + 0xff, 0x0a, 0x43, 0x91, 0x15, 0xc3, 0xf2, 0x37, 0xb0, 0x06, 0xc0, 0x87, 0xa8, 0x63, 0x2f, 0x27, + 0x31, 0xe9, 0xf6, 0x9d, 0xa3, 0x8d, 0xc1, 0x76, 0xf9, 0xff, 0x57, 0xac, 0x88, 0x59, 0x9d, 0xc4, + 0x4f, 0x50, 0x57, 0x8b, 0x04, 0x94, 0x8e, 0x92, 0x8c, 0x20, 0x4b, 0xee, 0x14, 0x86, 0x36, 0x22, + 0x6b, 0x42, 0xec, 0xa1, 0xf6, 0x18, 0xc4, 0x68, 0xac, 0x49, 0xcf, 0x92, 0xa8, 0x30, 0x74, 0xae, + 0xb0, 0xf9, 0x89, 0x5f, 0xa0, 0xed, 0x66, 0x11, 0x4f, 0x62, 0xb2, 0x6d, 0xc9, 0xbd, 0xc2, 0xd0, + 0x9d, 0x46, 0x2f, 0x2d, 0xdc, 0xc1, 0xbc, 0x2f, 0x0e, 0xea, 0x35, 0xbb, 0xa7, 0x30, 0x45, 0x9b, + 0x90, 0x49, 0x3e, 0xb6, 0x5b, 0xb7, 0x3e, 0xe8, 0x16, 0x86, 0x56, 0x02, 0xab, 0x0e, 0x7c, 0x8a, + 0x3a, 0x90, 0xea, 0x5c, 0x80, 0x22, 0x6b, 0xfd, 0xf5, 0xa3, 0xde, 0xb3, 0xc7, 0xfe, 0xaa, 0x75, + 0xf7, 0xff, 0x5a, 0xea, 0x6a, 0x87, 0xe7, 0xd5, 0xac, 0x0e, 0x06, 0x6f, 0x2e, 0xae, 0x5c, 0xe7, + 0xf2, 0xca, 0x75, 0x7e, 0x5d, 0xb9, 0xce, 0xd7, 0x6b, 0xb7, 0x75, 0x79, 0xed, 0xb6, 0x7e, 0x5c, + 0xbb, 0xad, 0x8f, 0xc7, 0xb7, 0x9e, 0x8f, 0x02, 0x71, 0x5c, 0x4f, 0xb1, 0x17, 0x3b, 0x26, 0x98, + 0x06, 0xe5, 0x27, 0xc8, 0xbe, 0xa4, 0xb3, 0xb6, 0xcd, 0x3f, 0xff, 0x13, 0x00, 0x00, 0xff, 0xff, + 0x07, 0xa3, 0x0d, 0xb2, 0x96, 0x04, 0x00, 0x00, +} + +func (m *SettlementEntry) 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 *SettlementEntry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SettlementEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.SettlementId != 0 { + i = encodeVarintSettlement(dAtA, i, uint64(m.SettlementId)) + i-- + dAtA[i] = 0x60 + } + if m.Height != 0 { + i = encodeVarintSettlement(dAtA, i, uint64(m.Height)) + i-- + dAtA[i] = 0x58 + } + if m.Timestamp != 0 { + i = encodeVarintSettlement(dAtA, i, uint64(m.Timestamp)) + i-- + dAtA[i] = 0x50 + } + if m.OrderId != 0 { + i = encodeVarintSettlement(dAtA, i, uint64(m.OrderId)) + i-- + dAtA[i] = 0x48 + } + if len(m.OrderType) > 0 { + i -= len(m.OrderType) + copy(dAtA[i:], m.OrderType) + i = encodeVarintSettlement(dAtA, i, uint64(len(m.OrderType))) + i-- + dAtA[i] = 0x42 + } + if len(m.PositionDirection) > 0 { + i -= len(m.PositionDirection) + copy(dAtA[i:], m.PositionDirection) + i = encodeVarintSettlement(dAtA, i, uint64(len(m.PositionDirection))) + i-- + dAtA[i] = 0x3a + } + { + size := m.ExpectedCostOrProceed.Size() + i -= size + if _, err := m.ExpectedCostOrProceed.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintSettlement(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + { + size := m.ExecutionCostOrProceed.Size() + i -= size + if _, err := m.ExecutionCostOrProceed.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintSettlement(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + { + size := m.Quantity.Size() + i -= size + if _, err := m.Quantity.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintSettlement(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + if len(m.AssetDenom) > 0 { + i -= len(m.AssetDenom) + copy(dAtA[i:], m.AssetDenom) + i = encodeVarintSettlement(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 = encodeVarintSettlement(dAtA, i, uint64(len(m.PriceDenom))) + i-- + dAtA[i] = 0x12 + } + if len(m.Account) > 0 { + i -= len(m.Account) + copy(dAtA[i:], m.Account) + i = encodeVarintSettlement(dAtA, i, uint64(len(m.Account))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Settlements) 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 *Settlements) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Settlements) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Entries) > 0 { + for iNdEx := len(m.Entries) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Entries[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintSettlement(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if m.Epoch != 0 { + i = encodeVarintSettlement(dAtA, i, uint64(m.Epoch)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintSettlement(dAtA []byte, offset int, v uint64) int { + offset -= sovSettlement(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *SettlementEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Account) + if l > 0 { + n += 1 + l + sovSettlement(uint64(l)) + } + l = len(m.PriceDenom) + if l > 0 { + n += 1 + l + sovSettlement(uint64(l)) + } + l = len(m.AssetDenom) + if l > 0 { + n += 1 + l + sovSettlement(uint64(l)) + } + l = m.Quantity.Size() + n += 1 + l + sovSettlement(uint64(l)) + l = m.ExecutionCostOrProceed.Size() + n += 1 + l + sovSettlement(uint64(l)) + l = m.ExpectedCostOrProceed.Size() + n += 1 + l + sovSettlement(uint64(l)) + l = len(m.PositionDirection) + if l > 0 { + n += 1 + l + sovSettlement(uint64(l)) + } + l = len(m.OrderType) + if l > 0 { + n += 1 + l + sovSettlement(uint64(l)) + } + if m.OrderId != 0 { + n += 1 + sovSettlement(uint64(m.OrderId)) + } + if m.Timestamp != 0 { + n += 1 + sovSettlement(uint64(m.Timestamp)) + } + if m.Height != 0 { + n += 1 + sovSettlement(uint64(m.Height)) + } + if m.SettlementId != 0 { + n += 1 + sovSettlement(uint64(m.SettlementId)) + } + return n +} + +func (m *Settlements) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Epoch != 0 { + n += 1 + sovSettlement(uint64(m.Epoch)) + } + if len(m.Entries) > 0 { + for _, e := range m.Entries { + l = e.Size() + n += 1 + l + sovSettlement(uint64(l)) + } + } + return n +} + +func sovSettlement(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozSettlement(x uint64) (n int) { + return sovSettlement(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *SettlementEntry) 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 ErrIntOverflowSettlement + } + 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: SettlementEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SettlementEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Account", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + 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 ErrInvalidLengthSettlement + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettlement + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Account = string(dAtA[iNdEx:postIndex]) + 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 ErrIntOverflowSettlement + } + 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 ErrInvalidLengthSettlement + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettlement + } + 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 ErrIntOverflowSettlement + } + 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 ErrInvalidLengthSettlement + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettlement + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.AssetDenom = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Quantity", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + 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 ErrInvalidLengthSettlement + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettlement + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Quantity.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExecutionCostOrProceed", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + 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 ErrInvalidLengthSettlement + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettlement + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ExecutionCostOrProceed.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ExpectedCostOrProceed", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + 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 ErrInvalidLengthSettlement + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettlement + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.ExpectedCostOrProceed.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PositionDirection", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + 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 ErrInvalidLengthSettlement + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettlement + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.PositionDirection = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OrderType", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + 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 ErrInvalidLengthSettlement + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthSettlement + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.OrderType = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OrderId", wireType) + } + m.OrderId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OrderId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Timestamp", wireType) + } + m.Timestamp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Timestamp |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Height", wireType) + } + m.Height = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Height |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field SettlementId", wireType) + } + m.SettlementId = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.SettlementId |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipSettlement(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSettlement + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Settlements) 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 ErrIntOverflowSettlement + } + 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: Settlements: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Settlements: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) + } + m.Epoch = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Epoch |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entries", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettlement + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthSettlement + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthSettlement + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Entries = append(m.Entries, &SettlementEntry{}) + if err := m.Entries[len(m.Entries)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipSettlement(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthSettlement + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipSettlement(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, ErrIntOverflowSettlement + } + 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, ErrIntOverflowSettlement + } + 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, ErrIntOverflowSettlement + } + 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, ErrInvalidLengthSettlement + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupSettlement + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthSettlement + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthSettlement = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowSettlement = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupSettlement = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/settlement_test.go b/x/dex/types/settlement_test.go new file mode 100644 index 000000000..245e33d05 --- /dev/null +++ b/x/dex/types/settlement_test.go @@ -0,0 +1,31 @@ +package types_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/x/dex/types" + "github.com/stretchr/testify/require" +) + +func TestNewSettlementEntry(t *testing.T) { + _, ctx := keepertest.DexKeeper(t) + ctx = ctx.WithBlockHeight(100) + sudoFinalizeBlockMsg := types.NewSettlementEntry( + ctx, + 1, + "TEST_ACCOUNT", + types.PositionDirection_LONG, + "USDC", + "ATOM", + sdk.MustNewDecFromStr("1"), + sdk.MustNewDecFromStr("2"), + sdk.MustNewDecFromStr("3"), + types.OrderType_MARKET, + ) + + require.Equal(t, "Long", sudoFinalizeBlockMsg.PositionDirection) + require.Equal(t, "Market", sudoFinalizeBlockMsg.OrderType) + require.Equal(t, uint64(100), sudoFinalizeBlockMsg.Height) +} diff --git a/x/dex/types/short_book.pb.go b/x/dex/types/short_book.pb.go new file mode 100644 index 000000000..83c969121 --- /dev/null +++ b/x/dex/types/short_book.pb.go @@ -0,0 +1,380 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/short_book.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 ShortBook struct { + Price github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,1,opt,name=price,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"price" yaml:"price"` + Entry *OrderEntry `protobuf:"bytes,2,opt,name=entry,proto3" json:"entry"` +} + +func (m *ShortBook) Reset() { *m = ShortBook{} } +func (m *ShortBook) String() string { return proto.CompactTextString(m) } +func (*ShortBook) ProtoMessage() {} +func (*ShortBook) Descriptor() ([]byte, []int) { + return fileDescriptor_2554593a991dd89d, []int{0} +} +func (m *ShortBook) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ShortBook) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ShortBook.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 *ShortBook) XXX_Merge(src proto.Message) { + xxx_messageInfo_ShortBook.Merge(m, src) +} +func (m *ShortBook) XXX_Size() int { + return m.Size() +} +func (m *ShortBook) XXX_DiscardUnknown() { + xxx_messageInfo_ShortBook.DiscardUnknown(m) +} + +var xxx_messageInfo_ShortBook proto.InternalMessageInfo + +func (m *ShortBook) GetEntry() *OrderEntry { + if m != nil { + return m.Entry + } + return nil +} + +func init() { + proto.RegisterType((*ShortBook)(nil), "seiprotocol.seichain.dex.ShortBook") +} + +func init() { proto.RegisterFile("dex/short_book.proto", fileDescriptor_2554593a991dd89d) } + +var fileDescriptor_2554593a991dd89d = []byte{ + // 278 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x49, 0x49, 0xad, 0xd0, + 0x2f, 0xce, 0xc8, 0x2f, 0x2a, 0x89, 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, 0x44, 0x41, 0xea, 0xf3, 0x8b, 0x52, 0x52, 0x8b, + 0xe2, 0x53, 0xf3, 0x4a, 0x8a, 0x2a, 0x21, 0x1a, 0xa4, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x4c, + 0x7d, 0x10, 0x0b, 0x22, 0xaa, 0xb4, 0x91, 0x91, 0x8b, 0x33, 0x18, 0x64, 0xb6, 0x53, 0x7e, 0x7e, + 0xb6, 0x50, 0x2c, 0x17, 0x6b, 0x41, 0x51, 0x66, 0x72, 0xaa, 0x04, 0xa3, 0x02, 0xa3, 0x06, 0xa7, + 0x93, 0xfb, 0x89, 0x7b, 0xf2, 0x0c, 0xb7, 0xee, 0xc9, 0xab, 0xa5, 0x67, 0x96, 0x64, 0x94, 0x26, + 0xe9, 0x25, 0xe7, 0xe7, 0xea, 0x27, 0xe7, 0x17, 0xe7, 0xe6, 0x17, 0x43, 0x29, 0xdd, 0xe2, 0x94, + 0x6c, 0xfd, 0x92, 0xca, 0x82, 0xd4, 0x62, 0x3d, 0x97, 0xd4, 0xe4, 0x57, 0xf7, 0xe4, 0x21, 0xda, + 0x3f, 0xdd, 0x93, 0xe7, 0xa9, 0x4c, 0xcc, 0xcd, 0xb1, 0x52, 0x02, 0x73, 0x95, 0x82, 0x20, 0xc2, + 0x42, 0xae, 0x5c, 0xac, 0x60, 0x17, 0x49, 0x30, 0x29, 0x30, 0x6a, 0x70, 0x1b, 0xa9, 0xe8, 0xe1, + 0xf2, 0x83, 0x9e, 0x3f, 0xc8, 0xf9, 0xae, 0x20, 0xb5, 0x4e, 0x9c, 0x20, 0x63, 0xc1, 0xda, 0x82, + 0x20, 0x94, 0x93, 0xfb, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, + 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0xe9, 0x22, + 0x39, 0xb4, 0x38, 0x35, 0x53, 0x17, 0x66, 0x38, 0x98, 0x03, 0x36, 0x5d, 0xbf, 0x42, 0x1f, 0x14, + 0x3c, 0x60, 0x37, 0x27, 0xb1, 0x81, 0xe5, 0x8d, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x90, 0x12, + 0x40, 0x1c, 0x62, 0x01, 0x00, 0x00, +} + +func (m *ShortBook) 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 *ShortBook) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ShortBook) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Entry != nil { + { + size, err := m.Entry.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintShortBook(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + { + size := m.Price.Size() + i -= size + if _, err := m.Price.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintShortBook(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func encodeVarintShortBook(dAtA []byte, offset int, v uint64) int { + offset -= sovShortBook(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *ShortBook) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = m.Price.Size() + n += 1 + l + sovShortBook(uint64(l)) + if m.Entry != nil { + l = m.Entry.Size() + n += 1 + l + sovShortBook(uint64(l)) + } + return n +} + +func sovShortBook(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozShortBook(x uint64) (n int) { + return sovShortBook(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *ShortBook) 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 ErrIntOverflowShortBook + } + 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: ShortBook: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ShortBook: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Price", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowShortBook + } + 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 ErrInvalidLengthShortBook + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthShortBook + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Price.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Entry", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowShortBook + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthShortBook + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthShortBook + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Entry == nil { + m.Entry = &OrderEntry{} + } + if err := m.Entry.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipShortBook(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthShortBook + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipShortBook(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, ErrIntOverflowShortBook + } + 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, ErrIntOverflowShortBook + } + 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, ErrIntOverflowShortBook + } + 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, ErrInvalidLengthShortBook + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupShortBook + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthShortBook + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthShortBook = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowShortBook = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupShortBook = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/tick_size.pb.go b/x/dex/types/tick_size.pb.go new file mode 100644 index 000000000..c6f6a6f1e --- /dev/null +++ b/x/dex/types/tick_size.pb.go @@ -0,0 +1,433 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/tick_size.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 TickSize struct { + Pair *Pair `protobuf:"bytes,1,opt,name=pair,proto3" json:"pair"` + Ticksize github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=ticksize,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"tick_size" yaml:"tick_size"` + ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr,proto3" json:"contract_addr" yaml:"tick_size"` +} + +func (m *TickSize) Reset() { *m = TickSize{} } +func (m *TickSize) String() string { return proto.CompactTextString(m) } +func (*TickSize) ProtoMessage() {} +func (*TickSize) Descriptor() ([]byte, []int) { + return fileDescriptor_17c2b52038d2f694, []int{0} +} +func (m *TickSize) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *TickSize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_TickSize.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 *TickSize) XXX_Merge(src proto.Message) { + xxx_messageInfo_TickSize.Merge(m, src) +} +func (m *TickSize) XXX_Size() int { + return m.Size() +} +func (m *TickSize) XXX_DiscardUnknown() { + xxx_messageInfo_TickSize.DiscardUnknown(m) +} + +var xxx_messageInfo_TickSize proto.InternalMessageInfo + +func (m *TickSize) GetPair() *Pair { + if m != nil { + return m.Pair + } + return nil +} + +func (m *TickSize) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func init() { + proto.RegisterType((*TickSize)(nil), "seiprotocol.seichain.dex.TickSize") +} + +func init() { proto.RegisterFile("dex/tick_size.proto", fileDescriptor_17c2b52038d2f694) } + +var fileDescriptor_17c2b52038d2f694 = []byte{ + // 307 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0x49, 0xad, 0xd0, + 0x2f, 0xc9, 0x4c, 0xce, 0x8e, 0x2f, 0xce, 0xac, 0x4a, 0xd5, 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, 0x40, 0xca, 0x0b, 0x12, 0x33, 0x8b, 0x20, 0x2a, + 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x4c, 0x7d, 0x10, 0x0b, 0x22, 0xaa, 0xd4, 0xc0, 0xc4, + 0xc5, 0x11, 0x92, 0x99, 0x9c, 0x1d, 0x9c, 0x59, 0x95, 0x2a, 0x64, 0xc3, 0xc5, 0x02, 0xd2, 0x20, + 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xa7, 0x87, 0xcb, 0x6c, 0xbd, 0x80, 0xc4, 0xcc, 0x22, + 0x27, 0x8e, 0x57, 0xf7, 0xe4, 0xc1, 0xea, 0x83, 0xc0, 0xa4, 0x50, 0x36, 0x17, 0x07, 0xc8, 0x75, + 0x20, 0xc7, 0x49, 0x30, 0x29, 0x30, 0x6a, 0x70, 0x3a, 0xf9, 0x9f, 0xb8, 0x27, 0xcf, 0x70, 0xeb, + 0x9e, 0xbc, 0x5a, 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x72, 0x7e, + 0x71, 0x6e, 0x7e, 0x31, 0x94, 0xd2, 0x2d, 0x4e, 0xc9, 0xd6, 0x2f, 0xa9, 0x2c, 0x48, 0x2d, 0xd6, + 0x73, 0x49, 0x4d, 0x7e, 0x75, 0x4f, 0x9e, 0x13, 0xee, 0xbf, 0x4f, 0xf7, 0xe4, 0x05, 0x2a, 0x13, + 0x73, 0x73, 0xac, 0x94, 0xe0, 0x42, 0x4a, 0x41, 0x70, 0x0b, 0x84, 0x3c, 0xb9, 0x78, 0x92, 0xf3, + 0xf3, 0x4a, 0x8a, 0x12, 0x93, 0x4b, 0x1c, 0x53, 0x52, 0x8a, 0x24, 0x98, 0xc1, 0x16, 0xaa, 0xbe, + 0xba, 0x27, 0xcf, 0x0b, 0x13, 0x8f, 0x4f, 0x4c, 0x49, 0x29, 0xc2, 0x6a, 0x0c, 0x8a, 0x56, 0x27, + 0xf7, 0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x71, 0xc2, 0x63, + 0x39, 0x86, 0x0b, 0x8f, 0xe5, 0x18, 0x6e, 0x3c, 0x96, 0x63, 0x88, 0xd2, 0x45, 0x72, 0x77, 0x71, + 0x6a, 0xa6, 0x2e, 0x2c, 0x30, 0xc0, 0x1c, 0x70, 0x68, 0xe8, 0x57, 0xe8, 0x83, 0x63, 0x05, 0xe4, + 0x85, 0x24, 0x36, 0xb0, 0xbc, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x04, 0x0d, 0x45, 0x14, 0xa9, + 0x01, 0x00, 0x00, +} + +func (m *TickSize) 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 *TickSize) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *TickSize) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintTickSize(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x1a + } + { + size := m.Ticksize.Size() + i -= size + if _, err := m.Ticksize.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTickSize(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.Pair != nil { + { + size, err := m.Pair.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTickSize(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintTickSize(dAtA []byte, offset int, v uint64) int { + offset -= sovTickSize(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *TickSize) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pair != nil { + l = m.Pair.Size() + n += 1 + l + sovTickSize(uint64(l)) + } + l = m.Ticksize.Size() + n += 1 + l + sovTickSize(uint64(l)) + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovTickSize(uint64(l)) + } + return n +} + +func sovTickSize(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTickSize(x uint64) (n int) { + return sovTickSize(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *TickSize) 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 ErrIntOverflowTickSize + } + 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: TickSize: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: TickSize: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pair", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTickSize + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTickSize + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTickSize + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pair == nil { + m.Pair = &Pair{} + } + if err := m.Pair.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ticksize", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTickSize + } + 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 ErrInvalidLengthTickSize + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTickSize + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Ticksize.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTickSize + } + 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 ErrInvalidLengthTickSize + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTickSize + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTickSize(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTickSize + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTickSize(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, ErrIntOverflowTickSize + } + 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, ErrIntOverflowTickSize + } + 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, ErrIntOverflowTickSize + } + 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, ErrInvalidLengthTickSize + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTickSize + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTickSize + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTickSize = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTickSize = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTickSize = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/twap.pb.go b/x/dex/types/twap.pb.go new file mode 100644 index 000000000..c1976c198 --- /dev/null +++ b/x/dex/types/twap.pb.go @@ -0,0 +1,416 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/twap.proto + +package types + +import ( + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + _ "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 Twap struct { + Pair *Pair `protobuf:"bytes,1,opt,name=pair,proto3" json:"pair"` + Twap github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,2,opt,name=twap,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"twap" yaml:"twap"` + LookbackSeconds uint64 `protobuf:"varint,3,opt,name=lookbackSeconds,proto3" json:"lookback_seconds"` +} + +func (m *Twap) Reset() { *m = Twap{} } +func (m *Twap) String() string { return proto.CompactTextString(m) } +func (*Twap) ProtoMessage() {} +func (*Twap) Descriptor() ([]byte, []int) { + return fileDescriptor_10aa4b136085207a, []int{0} +} +func (m *Twap) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Twap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Twap.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 *Twap) XXX_Merge(src proto.Message) { + xxx_messageInfo_Twap.Merge(m, src) +} +func (m *Twap) XXX_Size() int { + return m.Size() +} +func (m *Twap) XXX_DiscardUnknown() { + xxx_messageInfo_Twap.DiscardUnknown(m) +} + +var xxx_messageInfo_Twap proto.InternalMessageInfo + +func (m *Twap) GetPair() *Pair { + if m != nil { + return m.Pair + } + return nil +} + +func (m *Twap) GetLookbackSeconds() uint64 { + if m != nil { + return m.LookbackSeconds + } + return 0 +} + +func init() { + proto.RegisterType((*Twap)(nil), "seiprotocol.seichain.dex.Twap") +} + +func init() { proto.RegisterFile("dex/twap.proto", fileDescriptor_10aa4b136085207a) } + +var fileDescriptor_10aa4b136085207a = []byte{ + // 296 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4b, 0x49, 0xad, 0xd0, + 0x2f, 0x29, 0x4f, 0x2c, 0xd0, 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, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x52, 0xfa, 0x20, 0x16, 0x44, 0xbd, 0x14, 0x58, + 0x7f, 0x41, 0x62, 0x66, 0x11, 0x84, 0xaf, 0x74, 0x9f, 0x91, 0x8b, 0x25, 0xa4, 0x3c, 0xb1, 0x40, + 0xc8, 0x86, 0x8b, 0x05, 0x24, 0x2c, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x6d, 0x24, 0xa7, 0x87, 0xcb, + 0x5c, 0xbd, 0x80, 0xc4, 0xcc, 0x22, 0x27, 0x8e, 0x57, 0xf7, 0xe4, 0xc1, 0xea, 0x83, 0xc0, 0xa4, + 0x50, 0x24, 0x17, 0x0b, 0xc8, 0x51, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0x9c, 0x4e, 0xae, 0x27, 0xee, + 0xc9, 0x33, 0xdc, 0xba, 0x27, 0xaf, 0x96, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, + 0xab, 0x9f, 0x9c, 0x5f, 0x9c, 0x9b, 0x5f, 0x0c, 0xa5, 0x74, 0x8b, 0x53, 0xb2, 0xf5, 0x4b, 0x2a, + 0x0b, 0x52, 0x8b, 0xf5, 0x5c, 0x52, 0x93, 0x41, 0x66, 0x81, 0x74, 0x7f, 0xba, 0x27, 0xcf, 0x5d, + 0x99, 0x98, 0x9b, 0x63, 0xa5, 0x04, 0xe2, 0x29, 0x05, 0x81, 0x05, 0x85, 0xec, 0xb8, 0xf8, 0x73, + 0xf2, 0xf3, 0xb3, 0x93, 0x12, 0x93, 0xb3, 0x83, 0x53, 0x93, 0xf3, 0xf3, 0x52, 0x8a, 0x25, 0x98, + 0x15, 0x18, 0x35, 0x58, 0x9c, 0x44, 0x5e, 0xdd, 0x93, 0x17, 0x80, 0x49, 0xc5, 0x17, 0x43, 0xe4, + 0x82, 0xd0, 0x15, 0x3b, 0xb9, 0x9f, 0x78, 0x24, 0xc7, 0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, + 0x72, 0x8c, 0x13, 0x1e, 0xcb, 0x31, 0x5c, 0x78, 0x2c, 0xc7, 0x70, 0xe3, 0xb1, 0x1c, 0x43, 0x94, + 0x2e, 0x92, 0xf3, 0x8a, 0x53, 0x33, 0x75, 0x61, 0xfe, 0x05, 0x73, 0xc0, 0x1e, 0xd6, 0xaf, 0xd0, + 0x07, 0x87, 0x37, 0xc8, 0xa5, 0x49, 0x6c, 0x60, 0x79, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x6e, 0x96, 0x9d, 0x05, 0x83, 0x01, 0x00, 0x00, +} + +func (m *Twap) 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 *Twap) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Twap) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.LookbackSeconds != 0 { + i = encodeVarintTwap(dAtA, i, uint64(m.LookbackSeconds)) + i-- + dAtA[i] = 0x18 + } + { + size := m.Twap.Size() + i -= size + if _, err := m.Twap.MarshalTo(dAtA[i:]); err != nil { + return 0, err + } + i = encodeVarintTwap(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + if m.Pair != nil { + { + size, err := m.Pair.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTwap(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func encodeVarintTwap(dAtA []byte, offset int, v uint64) int { + offset -= sovTwap(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Twap) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pair != nil { + l = m.Pair.Size() + n += 1 + l + sovTwap(uint64(l)) + } + l = m.Twap.Size() + n += 1 + l + sovTwap(uint64(l)) + if m.LookbackSeconds != 0 { + n += 1 + sovTwap(uint64(m.LookbackSeconds)) + } + return n +} + +func sovTwap(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTwap(x uint64) (n int) { + return sovTwap(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *Twap) 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 ErrIntOverflowTwap + } + 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: Twap: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Twap: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pair", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTwap + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTwap + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTwap + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pair == nil { + m.Pair = &Pair{} + } + if err := m.Pair.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Twap", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTwap + } + 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 ErrInvalidLengthTwap + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTwap + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.Twap.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LookbackSeconds", wireType) + } + m.LookbackSeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTwap + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.LookbackSeconds |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipTwap(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTwap + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTwap(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, ErrIntOverflowTwap + } + 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, ErrIntOverflowTwap + } + 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, ErrIntOverflowTwap + } + 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, ErrInvalidLengthTwap + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTwap + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTwap + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTwap = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTwap = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTwap = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/tx.pb.go b/x/dex/types/tx.pb.go new file mode 100644 index 000000000..88c844095 --- /dev/null +++ b/x/dex/types/tx.pb.go @@ -0,0 +1,3884 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: dex/tx.proto + +package types + +import ( + context "context" + fmt "fmt" + github_com_cosmos_cosmos_sdk_types "github.com/cosmos/cosmos-sdk/types" + types "github.com/cosmos/cosmos-sdk/types" + _ "github.com/gogo/protobuf/gogoproto" + grpc1 "github.com/gogo/protobuf/grpc" + proto "github.com/gogo/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + 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 MsgPlaceOrders struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator"` + Orders []*Order `protobuf:"bytes,2,rep,name=orders,proto3" json:"orders"` + ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr,proto3" json:"contract_address"` + Funds github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,rep,name=funds,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"funds"` +} + +func (m *MsgPlaceOrders) Reset() { *m = MsgPlaceOrders{} } +func (m *MsgPlaceOrders) String() string { return proto.CompactTextString(m) } +func (*MsgPlaceOrders) ProtoMessage() {} +func (*MsgPlaceOrders) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{0} +} +func (m *MsgPlaceOrders) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgPlaceOrders) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgPlaceOrders.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 *MsgPlaceOrders) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgPlaceOrders.Merge(m, src) +} +func (m *MsgPlaceOrders) XXX_Size() int { + return m.Size() +} +func (m *MsgPlaceOrders) XXX_DiscardUnknown() { + xxx_messageInfo_MsgPlaceOrders.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgPlaceOrders proto.InternalMessageInfo + +func (m *MsgPlaceOrders) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgPlaceOrders) GetOrders() []*Order { + if m != nil { + return m.Orders + } + return nil +} + +func (m *MsgPlaceOrders) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *MsgPlaceOrders) GetFunds() github_com_cosmos_cosmos_sdk_types.Coins { + if m != nil { + return m.Funds + } + return nil +} + +type MsgPlaceOrdersResponse struct { + OrderIds []uint64 `protobuf:"varint,1,rep,packed,name=orderIds,proto3" json:"order_ids" yaml:"order_ids"` +} + +func (m *MsgPlaceOrdersResponse) Reset() { *m = MsgPlaceOrdersResponse{} } +func (m *MsgPlaceOrdersResponse) String() string { return proto.CompactTextString(m) } +func (*MsgPlaceOrdersResponse) ProtoMessage() {} +func (*MsgPlaceOrdersResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{1} +} +func (m *MsgPlaceOrdersResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgPlaceOrdersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgPlaceOrdersResponse.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 *MsgPlaceOrdersResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgPlaceOrdersResponse.Merge(m, src) +} +func (m *MsgPlaceOrdersResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgPlaceOrdersResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgPlaceOrdersResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgPlaceOrdersResponse proto.InternalMessageInfo + +func (m *MsgPlaceOrdersResponse) GetOrderIds() []uint64 { + if m != nil { + return m.OrderIds + } + return nil +} + +type MsgCancelOrders struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator"` + Cancellations []*Cancellation `protobuf:"bytes,2,rep,name=cancellations,proto3" json:"cancellations"` + ContractAddr string `protobuf:"bytes,3,opt,name=contractAddr,proto3" json:"contract_address"` +} + +func (m *MsgCancelOrders) Reset() { *m = MsgCancelOrders{} } +func (m *MsgCancelOrders) String() string { return proto.CompactTextString(m) } +func (*MsgCancelOrders) ProtoMessage() {} +func (*MsgCancelOrders) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{2} +} +func (m *MsgCancelOrders) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCancelOrders) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCancelOrders.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 *MsgCancelOrders) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCancelOrders.Merge(m, src) +} +func (m *MsgCancelOrders) XXX_Size() int { + return m.Size() +} +func (m *MsgCancelOrders) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCancelOrders.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCancelOrders proto.InternalMessageInfo + +func (m *MsgCancelOrders) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgCancelOrders) GetCancellations() []*Cancellation { + if m != nil { + return m.Cancellations + } + return nil +} + +func (m *MsgCancelOrders) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +type MsgCancelOrdersResponse struct { +} + +func (m *MsgCancelOrdersResponse) Reset() { *m = MsgCancelOrdersResponse{} } +func (m *MsgCancelOrdersResponse) String() string { return proto.CompactTextString(m) } +func (*MsgCancelOrdersResponse) ProtoMessage() {} +func (*MsgCancelOrdersResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{3} +} +func (m *MsgCancelOrdersResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgCancelOrdersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgCancelOrdersResponse.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 *MsgCancelOrdersResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgCancelOrdersResponse.Merge(m, src) +} +func (m *MsgCancelOrdersResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgCancelOrdersResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgCancelOrdersResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgCancelOrdersResponse proto.InternalMessageInfo + +type MsgRegisterContract struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + Contract *ContractInfoV2 `protobuf:"bytes,2,opt,name=contract,proto3" json:"contract,omitempty"` +} + +func (m *MsgRegisterContract) Reset() { *m = MsgRegisterContract{} } +func (m *MsgRegisterContract) String() string { return proto.CompactTextString(m) } +func (*MsgRegisterContract) ProtoMessage() {} +func (*MsgRegisterContract) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{4} +} +func (m *MsgRegisterContract) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRegisterContract) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRegisterContract.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 *MsgRegisterContract) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRegisterContract.Merge(m, src) +} +func (m *MsgRegisterContract) XXX_Size() int { + return m.Size() +} +func (m *MsgRegisterContract) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRegisterContract.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRegisterContract proto.InternalMessageInfo + +func (m *MsgRegisterContract) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgRegisterContract) GetContract() *ContractInfoV2 { + if m != nil { + return m.Contract + } + return nil +} + +type MsgRegisterContractResponse struct { +} + +func (m *MsgRegisterContractResponse) Reset() { *m = MsgRegisterContractResponse{} } +func (m *MsgRegisterContractResponse) String() string { return proto.CompactTextString(m) } +func (*MsgRegisterContractResponse) ProtoMessage() {} +func (*MsgRegisterContractResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{5} +} +func (m *MsgRegisterContractResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRegisterContractResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRegisterContractResponse.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 *MsgRegisterContractResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRegisterContractResponse.Merge(m, src) +} +func (m *MsgRegisterContractResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgRegisterContractResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRegisterContractResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRegisterContractResponse proto.InternalMessageInfo + +type MsgContractDepositRent struct { + ContractAddr string `protobuf:"bytes,1,opt,name=contractAddr,proto3" json:"contract_address"` + Amount uint64 `protobuf:"varint,2,opt,name=amount,proto3" json:"amount"` + Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender"` +} + +func (m *MsgContractDepositRent) Reset() { *m = MsgContractDepositRent{} } +func (m *MsgContractDepositRent) String() string { return proto.CompactTextString(m) } +func (*MsgContractDepositRent) ProtoMessage() {} +func (*MsgContractDepositRent) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{6} +} +func (m *MsgContractDepositRent) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgContractDepositRent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgContractDepositRent.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 *MsgContractDepositRent) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgContractDepositRent.Merge(m, src) +} +func (m *MsgContractDepositRent) XXX_Size() int { + return m.Size() +} +func (m *MsgContractDepositRent) XXX_DiscardUnknown() { + xxx_messageInfo_MsgContractDepositRent.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgContractDepositRent proto.InternalMessageInfo + +func (m *MsgContractDepositRent) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +func (m *MsgContractDepositRent) GetAmount() uint64 { + if m != nil { + return m.Amount + } + return 0 +} + +func (m *MsgContractDepositRent) GetSender() string { + if m != nil { + return m.Sender + } + return "" +} + +type MsgContractDepositRentResponse struct { +} + +func (m *MsgContractDepositRentResponse) Reset() { *m = MsgContractDepositRentResponse{} } +func (m *MsgContractDepositRentResponse) String() string { return proto.CompactTextString(m) } +func (*MsgContractDepositRentResponse) ProtoMessage() {} +func (*MsgContractDepositRentResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{7} +} +func (m *MsgContractDepositRentResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgContractDepositRentResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgContractDepositRentResponse.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 *MsgContractDepositRentResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgContractDepositRentResponse.Merge(m, src) +} +func (m *MsgContractDepositRentResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgContractDepositRentResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgContractDepositRentResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgContractDepositRentResponse proto.InternalMessageInfo + +type MsgUnregisterContract struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contract_address"` +} + +func (m *MsgUnregisterContract) Reset() { *m = MsgUnregisterContract{} } +func (m *MsgUnregisterContract) String() string { return proto.CompactTextString(m) } +func (*MsgUnregisterContract) ProtoMessage() {} +func (*MsgUnregisterContract) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{8} +} +func (m *MsgUnregisterContract) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUnregisterContract) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUnregisterContract.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 *MsgUnregisterContract) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUnregisterContract.Merge(m, src) +} +func (m *MsgUnregisterContract) XXX_Size() int { + return m.Size() +} +func (m *MsgUnregisterContract) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUnregisterContract.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUnregisterContract proto.InternalMessageInfo + +func (m *MsgUnregisterContract) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgUnregisterContract) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +type MsgUnregisterContractResponse struct { +} + +func (m *MsgUnregisterContractResponse) Reset() { *m = MsgUnregisterContractResponse{} } +func (m *MsgUnregisterContractResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUnregisterContractResponse) ProtoMessage() {} +func (*MsgUnregisterContractResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{9} +} +func (m *MsgUnregisterContractResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUnregisterContractResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUnregisterContractResponse.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 *MsgUnregisterContractResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUnregisterContractResponse.Merge(m, src) +} +func (m *MsgUnregisterContractResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUnregisterContractResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUnregisterContractResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUnregisterContractResponse proto.InternalMessageInfo + +type MsgRegisterPairs struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator,omitempty"` + Batchcontractpair []BatchContractPair `protobuf:"bytes,3,rep,name=batchcontractpair,proto3" json:"batch_contract_pair" yaml:"batch_contract_pair"` +} + +func (m *MsgRegisterPairs) Reset() { *m = MsgRegisterPairs{} } +func (m *MsgRegisterPairs) String() string { return proto.CompactTextString(m) } +func (*MsgRegisterPairs) ProtoMessage() {} +func (*MsgRegisterPairs) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{10} +} +func (m *MsgRegisterPairs) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRegisterPairs) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRegisterPairs.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 *MsgRegisterPairs) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRegisterPairs.Merge(m, src) +} +func (m *MsgRegisterPairs) XXX_Size() int { + return m.Size() +} +func (m *MsgRegisterPairs) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRegisterPairs.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRegisterPairs proto.InternalMessageInfo + +func (m *MsgRegisterPairs) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgRegisterPairs) GetBatchcontractpair() []BatchContractPair { + if m != nil { + return m.Batchcontractpair + } + return nil +} + +type MsgRegisterPairsResponse struct { +} + +func (m *MsgRegisterPairsResponse) Reset() { *m = MsgRegisterPairsResponse{} } +func (m *MsgRegisterPairsResponse) String() string { return proto.CompactTextString(m) } +func (*MsgRegisterPairsResponse) ProtoMessage() {} +func (*MsgRegisterPairsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{11} +} +func (m *MsgRegisterPairsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgRegisterPairsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgRegisterPairsResponse.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 *MsgRegisterPairsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgRegisterPairsResponse.Merge(m, src) +} +func (m *MsgRegisterPairsResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgRegisterPairsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgRegisterPairsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgRegisterPairsResponse proto.InternalMessageInfo + +type MsgUpdatePriceTickSize struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator"` + TickSizeList []TickSize `protobuf:"bytes,2,rep,name=tickSizeList,proto3" json:"tick_size_list" yaml:"tick_size_list"` +} + +func (m *MsgUpdatePriceTickSize) Reset() { *m = MsgUpdatePriceTickSize{} } +func (m *MsgUpdatePriceTickSize) String() string { return proto.CompactTextString(m) } +func (*MsgUpdatePriceTickSize) ProtoMessage() {} +func (*MsgUpdatePriceTickSize) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{12} +} +func (m *MsgUpdatePriceTickSize) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdatePriceTickSize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdatePriceTickSize.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 *MsgUpdatePriceTickSize) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdatePriceTickSize.Merge(m, src) +} +func (m *MsgUpdatePriceTickSize) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdatePriceTickSize) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdatePriceTickSize.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdatePriceTickSize proto.InternalMessageInfo + +func (m *MsgUpdatePriceTickSize) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgUpdatePriceTickSize) GetTickSizeList() []TickSize { + if m != nil { + return m.TickSizeList + } + return nil +} + +type MsgUpdateQuantityTickSize struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator"` + TickSizeList []TickSize `protobuf:"bytes,2,rep,name=tickSizeList,proto3" json:"tick_size_list" yaml:"tick_size_list"` +} + +func (m *MsgUpdateQuantityTickSize) Reset() { *m = MsgUpdateQuantityTickSize{} } +func (m *MsgUpdateQuantityTickSize) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateQuantityTickSize) ProtoMessage() {} +func (*MsgUpdateQuantityTickSize) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{13} +} +func (m *MsgUpdateQuantityTickSize) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateQuantityTickSize) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateQuantityTickSize.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 *MsgUpdateQuantityTickSize) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateQuantityTickSize.Merge(m, src) +} +func (m *MsgUpdateQuantityTickSize) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateQuantityTickSize) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateQuantityTickSize.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateQuantityTickSize proto.InternalMessageInfo + +func (m *MsgUpdateQuantityTickSize) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgUpdateQuantityTickSize) GetTickSizeList() []TickSize { + if m != nil { + return m.TickSizeList + } + return nil +} + +type MsgUpdateTickSizeResponse struct { +} + +func (m *MsgUpdateTickSizeResponse) Reset() { *m = MsgUpdateTickSizeResponse{} } +func (m *MsgUpdateTickSizeResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUpdateTickSizeResponse) ProtoMessage() {} +func (*MsgUpdateTickSizeResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{14} +} +func (m *MsgUpdateTickSizeResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUpdateTickSizeResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUpdateTickSizeResponse.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 *MsgUpdateTickSizeResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUpdateTickSizeResponse.Merge(m, src) +} +func (m *MsgUpdateTickSizeResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUpdateTickSizeResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUpdateTickSizeResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUpdateTickSizeResponse proto.InternalMessageInfo + +type MsgUnsuspendContract struct { + Creator string `protobuf:"bytes,1,opt,name=creator,proto3" json:"creator"` + ContractAddr string `protobuf:"bytes,2,opt,name=contractAddr,proto3" json:"contract_address"` +} + +func (m *MsgUnsuspendContract) Reset() { *m = MsgUnsuspendContract{} } +func (m *MsgUnsuspendContract) String() string { return proto.CompactTextString(m) } +func (*MsgUnsuspendContract) ProtoMessage() {} +func (*MsgUnsuspendContract) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{15} +} +func (m *MsgUnsuspendContract) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUnsuspendContract) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUnsuspendContract.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 *MsgUnsuspendContract) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUnsuspendContract.Merge(m, src) +} +func (m *MsgUnsuspendContract) XXX_Size() int { + return m.Size() +} +func (m *MsgUnsuspendContract) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUnsuspendContract.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUnsuspendContract proto.InternalMessageInfo + +func (m *MsgUnsuspendContract) GetCreator() string { + if m != nil { + return m.Creator + } + return "" +} + +func (m *MsgUnsuspendContract) GetContractAddr() string { + if m != nil { + return m.ContractAddr + } + return "" +} + +type MsgUnsuspendContractResponse struct { +} + +func (m *MsgUnsuspendContractResponse) Reset() { *m = MsgUnsuspendContractResponse{} } +func (m *MsgUnsuspendContractResponse) String() string { return proto.CompactTextString(m) } +func (*MsgUnsuspendContractResponse) ProtoMessage() {} +func (*MsgUnsuspendContractResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_463701e671e5a5e0, []int{16} +} +func (m *MsgUnsuspendContractResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MsgUnsuspendContractResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MsgUnsuspendContractResponse.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 *MsgUnsuspendContractResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_MsgUnsuspendContractResponse.Merge(m, src) +} +func (m *MsgUnsuspendContractResponse) XXX_Size() int { + return m.Size() +} +func (m *MsgUnsuspendContractResponse) XXX_DiscardUnknown() { + xxx_messageInfo_MsgUnsuspendContractResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_MsgUnsuspendContractResponse proto.InternalMessageInfo + +func init() { + proto.RegisterType((*MsgPlaceOrders)(nil), "seiprotocol.seichain.dex.MsgPlaceOrders") + proto.RegisterType((*MsgPlaceOrdersResponse)(nil), "seiprotocol.seichain.dex.MsgPlaceOrdersResponse") + proto.RegisterType((*MsgCancelOrders)(nil), "seiprotocol.seichain.dex.MsgCancelOrders") + proto.RegisterType((*MsgCancelOrdersResponse)(nil), "seiprotocol.seichain.dex.MsgCancelOrdersResponse") + proto.RegisterType((*MsgRegisterContract)(nil), "seiprotocol.seichain.dex.MsgRegisterContract") + proto.RegisterType((*MsgRegisterContractResponse)(nil), "seiprotocol.seichain.dex.MsgRegisterContractResponse") + proto.RegisterType((*MsgContractDepositRent)(nil), "seiprotocol.seichain.dex.MsgContractDepositRent") + proto.RegisterType((*MsgContractDepositRentResponse)(nil), "seiprotocol.seichain.dex.MsgContractDepositRentResponse") + proto.RegisterType((*MsgUnregisterContract)(nil), "seiprotocol.seichain.dex.MsgUnregisterContract") + proto.RegisterType((*MsgUnregisterContractResponse)(nil), "seiprotocol.seichain.dex.MsgUnregisterContractResponse") + proto.RegisterType((*MsgRegisterPairs)(nil), "seiprotocol.seichain.dex.MsgRegisterPairs") + proto.RegisterType((*MsgRegisterPairsResponse)(nil), "seiprotocol.seichain.dex.MsgRegisterPairsResponse") + proto.RegisterType((*MsgUpdatePriceTickSize)(nil), "seiprotocol.seichain.dex.MsgUpdatePriceTickSize") + proto.RegisterType((*MsgUpdateQuantityTickSize)(nil), "seiprotocol.seichain.dex.MsgUpdateQuantityTickSize") + proto.RegisterType((*MsgUpdateTickSizeResponse)(nil), "seiprotocol.seichain.dex.MsgUpdateTickSizeResponse") + proto.RegisterType((*MsgUnsuspendContract)(nil), "seiprotocol.seichain.dex.MsgUnsuspendContract") + proto.RegisterType((*MsgUnsuspendContractResponse)(nil), "seiprotocol.seichain.dex.MsgUnsuspendContractResponse") +} + +func init() { proto.RegisterFile("dex/tx.proto", fileDescriptor_463701e671e5a5e0) } + +var fileDescriptor_463701e671e5a5e0 = []byte{ + // 962 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x57, 0x41, 0x6f, 0xe3, 0x44, + 0x14, 0xae, 0x9b, 0x52, 0xba, 0xaf, 0xdd, 0x6e, 0xeb, 0x74, 0x17, 0xd7, 0xcb, 0xda, 0xc1, 0x12, + 0x28, 0x80, 0x6a, 0xd3, 0xac, 0x80, 0x05, 0x89, 0x03, 0xc9, 0x4a, 0x68, 0x25, 0x22, 0x8a, 0x61, + 0x41, 0xe2, 0x12, 0x39, 0xf6, 0xac, 0x3b, 0x34, 0xf5, 0x44, 0x9e, 0x09, 0x9b, 0x2e, 0x08, 0x09, + 0x7e, 0x01, 0x07, 0x4e, 0x1c, 0x39, 0xf2, 0x0b, 0x90, 0x38, 0x72, 0xd9, 0x0b, 0xd2, 0x4a, 0x5c, + 0x38, 0x19, 0xd4, 0xde, 0x72, 0xec, 0x2f, 0x40, 0x1e, 0xdb, 0x43, 0xec, 0x38, 0xc1, 0xd9, 0x03, + 0x12, 0x27, 0x8f, 0x5f, 0xde, 0xf7, 0xbe, 0xf7, 0xbe, 0x37, 0xf3, 0xc6, 0x81, 0x2d, 0x0f, 0x8d, + 0x2d, 0x36, 0x36, 0x87, 0x21, 0x61, 0x44, 0x56, 0x28, 0xc2, 0x7c, 0xe5, 0x92, 0x81, 0x49, 0x11, + 0x76, 0x8f, 0x1d, 0x1c, 0x98, 0x1e, 0x1a, 0xab, 0x9a, 0x4b, 0xe8, 0x29, 0xa1, 0x56, 0xdf, 0xa1, + 0xc8, 0xfa, 0xe2, 0xb0, 0x8f, 0x98, 0x73, 0x68, 0xb9, 0x04, 0x07, 0x09, 0x52, 0xdd, 0xf3, 0x89, + 0x4f, 0xf8, 0xd2, 0x8a, 0x57, 0xa9, 0x55, 0x8e, 0xa3, 0xbb, 0x24, 0x60, 0xa1, 0xe3, 0xb2, 0xd4, + 0x76, 0x2d, 0xb6, 0x91, 0xd0, 0x43, 0x61, 0x6a, 0xd8, 0x8e, 0x0d, 0x43, 0x07, 0x67, 0xef, 0x75, + 0x9e, 0x12, 0x76, 0x4f, 0x7a, 0x14, 0x3f, 0x42, 0x89, 0xd1, 0xf8, 0x71, 0x15, 0xb6, 0xbb, 0xd4, + 0x3f, 0x1a, 0x38, 0x2e, 0xfa, 0x20, 0x06, 0x53, 0xf9, 0x45, 0x78, 0xd6, 0x0d, 0x91, 0xc3, 0x48, + 0xa8, 0x48, 0x0d, 0xa9, 0x79, 0xa5, 0xbd, 0x39, 0x89, 0xf4, 0xcc, 0x64, 0x67, 0x0b, 0xb9, 0x03, + 0xeb, 0x9c, 0x8d, 0x2a, 0xab, 0x8d, 0x5a, 0x73, 0xb3, 0xa5, 0x9b, 0xf3, 0x8a, 0x34, 0x79, 0xe0, + 0x36, 0x4c, 0x22, 0x3d, 0x85, 0xd8, 0xe9, 0x53, 0xbe, 0x03, 0x5b, 0x59, 0x19, 0xef, 0x7a, 0x5e, + 0xa8, 0xd4, 0x38, 0xe1, 0xde, 0x24, 0xd2, 0x77, 0x32, 0x7b, 0xcf, 0xf1, 0xbc, 0x10, 0x51, 0x6a, + 0xe7, 0x3c, 0xe5, 0xcf, 0xe1, 0x99, 0x07, 0xa3, 0xc0, 0xa3, 0xca, 0x1a, 0x67, 0xdf, 0x37, 0x13, + 0x21, 0xcd, 0x58, 0x48, 0x33, 0x15, 0xd2, 0xec, 0x10, 0x1c, 0xb4, 0xdf, 0x7a, 0x1c, 0xe9, 0x2b, + 0x93, 0x48, 0x4f, 0xfc, 0x7f, 0xfa, 0x53, 0x6f, 0xfa, 0x98, 0x1d, 0x8f, 0xfa, 0xa6, 0x4b, 0x4e, + 0xad, 0x54, 0xfe, 0xe4, 0x71, 0x40, 0xbd, 0x13, 0x8b, 0x9d, 0x0d, 0x11, 0xe5, 0x48, 0x6a, 0x27, + 0x10, 0xe3, 0x53, 0xb8, 0x91, 0xd7, 0xc8, 0x46, 0x74, 0x48, 0x02, 0x8a, 0xe4, 0x77, 0x60, 0x83, + 0x57, 0x72, 0xcf, 0xa3, 0x8a, 0xd4, 0xa8, 0x35, 0xd7, 0xda, 0x2f, 0x4c, 0x22, 0xfd, 0x0a, 0xb7, + 0xf5, 0xb0, 0x47, 0x2f, 0x23, 0x7d, 0xe7, 0xcc, 0x39, 0x1d, 0xbc, 0x6d, 0x08, 0x93, 0x61, 0x0b, + 0x88, 0xf1, 0xbb, 0x04, 0xd7, 0xba, 0xd4, 0xef, 0x38, 0x81, 0x8b, 0x06, 0xcb, 0xc9, 0xdf, 0x83, + 0xab, 0x2e, 0x87, 0x0d, 0x1c, 0x86, 0x49, 0x90, 0x75, 0xe1, 0xa5, 0xf9, 0x5d, 0xe8, 0x4c, 0xb9, + 0xb7, 0x77, 0x27, 0x91, 0x9e, 0x0f, 0x60, 0xe7, 0x5f, 0x9f, 0xbe, 0x35, 0xc6, 0x3e, 0x3c, 0x57, + 0x28, 0x2a, 0xd3, 0xcb, 0x18, 0x41, 0xbd, 0x4b, 0x7d, 0x1b, 0xf9, 0x98, 0x32, 0x14, 0x76, 0x52, + 0x94, 0xac, 0x14, 0x6a, 0xfe, 0xa7, 0xcc, 0xbb, 0xb0, 0x91, 0xc5, 0x56, 0x56, 0x1b, 0x52, 0x73, + 0xb3, 0xd5, 0x5c, 0x50, 0x61, 0xea, 0x79, 0x2f, 0x78, 0x40, 0x3e, 0x69, 0xd9, 0x02, 0x69, 0xdc, + 0x82, 0x9b, 0x25, 0xb4, 0x22, 0xab, 0x1f, 0x24, 0xde, 0xe0, 0xcc, 0x7e, 0x17, 0x0d, 0x09, 0xc5, + 0xcc, 0x46, 0x01, 0x9b, 0x51, 0x41, 0xaa, 0xbc, 0x41, 0x0d, 0x58, 0x77, 0x4e, 0xc9, 0x28, 0x48, + 0xf2, 0x5e, 0x4b, 0xb6, 0x7f, 0x62, 0xb1, 0xd3, 0x67, 0xec, 0x43, 0x51, 0xe0, 0xa1, 0x4c, 0x5d, + 0xee, 0x93, 0x58, 0xec, 0xf4, 0x69, 0x34, 0x40, 0x2b, 0xcf, 0x4d, 0xa4, 0x3f, 0x86, 0xeb, 0x5d, + 0xea, 0xdf, 0x0f, 0xc2, 0xa2, 0xac, 0x15, 0xb7, 0x52, 0xb1, 0xc6, 0xd5, 0xca, 0x9d, 0xd6, 0xe1, + 0x56, 0x29, 0xb3, 0x48, 0xed, 0x57, 0x09, 0x76, 0xa6, 0x94, 0x3f, 0x72, 0x70, 0x48, 0x17, 0x74, + 0xfb, 0x7b, 0x09, 0x76, 0xfb, 0x0e, 0x73, 0x8f, 0x33, 0x96, 0x78, 0x7c, 0x29, 0x35, 0xbe, 0xb3, + 0x5f, 0x9d, 0xdf, 0xf7, 0x76, 0x0c, 0xc9, 0xb8, 0x63, 0x0e, 0x71, 0xe6, 0xeb, 0x3c, 0x5a, 0x4f, + 0x94, 0x11, 0xc7, 0xbb, 0x8c, 0x74, 0x35, 0x39, 0x93, 0x25, 0x3f, 0x1a, 0xf6, 0x6c, 0x02, 0x86, + 0x0a, 0x4a, 0xb1, 0x08, 0x51, 0xe1, 0xcf, 0xc9, 0xde, 0xb9, 0x3f, 0xf4, 0x1c, 0x86, 0x8e, 0x42, + 0xec, 0xa2, 0x8f, 0xb1, 0x7b, 0xf2, 0x11, 0x7e, 0x84, 0xaa, 0xca, 0xff, 0x10, 0xb6, 0x58, 0x0a, + 0x79, 0x1f, 0x53, 0x96, 0x1e, 0x64, 0x63, 0x7e, 0xb9, 0x19, 0x41, 0xdb, 0x4a, 0xab, 0xdc, 0x16, + 0x53, 0xbd, 0x37, 0xc0, 0x94, 0x5d, 0x46, 0xfa, 0xf5, 0xa4, 0xc0, 0xbc, 0xdd, 0xb0, 0x73, 0x44, + 0xc6, 0x2f, 0x12, 0xec, 0x8b, 0xd4, 0x3f, 0x1c, 0x39, 0x01, 0xc3, 0xec, 0xec, 0x7f, 0x93, 0xfd, + 0xcd, 0xa9, 0xe4, 0xb3, 0x98, 0xa2, 0x2b, 0x0f, 0x61, 0x8f, 0x6f, 0x4c, 0x3a, 0xa2, 0x43, 0x14, + 0x78, 0xff, 0xdd, 0x89, 0xd0, 0xe0, 0xf9, 0x32, 0xe2, 0x2c, 0xb1, 0xd6, 0x6f, 0x1b, 0x50, 0xeb, + 0x52, 0x5f, 0xc6, 0xb0, 0x39, 0x7d, 0xe7, 0x2e, 0x18, 0x6a, 0xf9, 0x9b, 0x47, 0x7d, 0xad, 0xaa, + 0xa7, 0xb8, 0xa3, 0x06, 0xb0, 0x95, 0xbb, 0x60, 0x5e, 0x5e, 0x18, 0x61, 0xda, 0x55, 0x3d, 0xac, + 0xec, 0x2a, 0xd8, 0xc6, 0xb0, 0x33, 0x33, 0xde, 0x0f, 0x16, 0x86, 0x29, 0xba, 0xab, 0xaf, 0x2f, + 0xe5, 0x2e, 0x98, 0xbf, 0x91, 0xa0, 0x5e, 0x36, 0xc2, 0x17, 0x2b, 0x56, 0x82, 0x50, 0xef, 0x2c, + 0x8b, 0x10, 0x39, 0x7c, 0x0d, 0x72, 0xc9, 0x1c, 0xb6, 0x16, 0xc6, 0x9b, 0x05, 0xa8, 0x6f, 0x2e, + 0x09, 0x10, 0xfc, 0x04, 0xae, 0xe6, 0x67, 0xed, 0x2b, 0x95, 0xb4, 0xe4, 0xbe, 0x6a, 0xab, 0xba, + 0xaf, 0x20, 0xfc, 0x0a, 0xea, 0x65, 0xa3, 0x6f, 0xb1, 0xe6, 0x25, 0x08, 0xf5, 0x76, 0x05, 0x44, + 0xf1, 0x98, 0xcb, 0xdf, 0x4a, 0x70, 0x63, 0xce, 0xf8, 0xaa, 0x12, 0xaf, 0x08, 0x7a, 0xba, 0x24, + 0xbe, 0x84, 0xdd, 0xd9, 0x41, 0x63, 0xfe, 0x4b, 0x07, 0x0b, 0xfe, 0xea, 0x1b, 0xcb, 0xf9, 0x67, + 0xe4, 0xed, 0xf7, 0x1e, 0x9f, 0x6b, 0xd2, 0x93, 0x73, 0x4d, 0xfa, 0xeb, 0x5c, 0x93, 0xbe, 0xbb, + 0xd0, 0x56, 0x9e, 0x5c, 0x68, 0x2b, 0x7f, 0x5c, 0x68, 0x2b, 0x9f, 0x1d, 0x4c, 0x7d, 0xe5, 0x52, + 0x84, 0x0f, 0xb2, 0xe0, 0xfc, 0x85, 0x47, 0xb7, 0xc6, 0x16, 0xff, 0x4b, 0x10, 0x7f, 0xf0, 0xf6, + 0xd7, 0xf9, 0xef, 0xb7, 0xff, 0x0e, 0x00, 0x00, 0xff, 0xff, 0x87, 0xb0, 0xd3, 0x48, 0xb9, 0x0c, + 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// MsgClient is the client API for Msg service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MsgClient interface { + PlaceOrders(ctx context.Context, in *MsgPlaceOrders, opts ...grpc.CallOption) (*MsgPlaceOrdersResponse, error) + CancelOrders(ctx context.Context, in *MsgCancelOrders, opts ...grpc.CallOption) (*MsgCancelOrdersResponse, error) + RegisterContract(ctx context.Context, in *MsgRegisterContract, opts ...grpc.CallOption) (*MsgRegisterContractResponse, error) + ContractDepositRent(ctx context.Context, in *MsgContractDepositRent, opts ...grpc.CallOption) (*MsgContractDepositRentResponse, error) + UnregisterContract(ctx context.Context, in *MsgUnregisterContract, opts ...grpc.CallOption) (*MsgUnregisterContractResponse, error) + RegisterPairs(ctx context.Context, in *MsgRegisterPairs, opts ...grpc.CallOption) (*MsgRegisterPairsResponse, error) + UpdatePriceTickSize(ctx context.Context, in *MsgUpdatePriceTickSize, opts ...grpc.CallOption) (*MsgUpdateTickSizeResponse, error) + UpdateQuantityTickSize(ctx context.Context, in *MsgUpdateQuantityTickSize, opts ...grpc.CallOption) (*MsgUpdateTickSizeResponse, error) + UnsuspendContract(ctx context.Context, in *MsgUnsuspendContract, opts ...grpc.CallOption) (*MsgUnsuspendContractResponse, error) +} + +type msgClient struct { + cc grpc1.ClientConn +} + +func NewMsgClient(cc grpc1.ClientConn) MsgClient { + return &msgClient{cc} +} + +func (c *msgClient) PlaceOrders(ctx context.Context, in *MsgPlaceOrders, opts ...grpc.CallOption) (*MsgPlaceOrdersResponse, error) { + out := new(MsgPlaceOrdersResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Msg/PlaceOrders", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) CancelOrders(ctx context.Context, in *MsgCancelOrders, opts ...grpc.CallOption) (*MsgCancelOrdersResponse, error) { + out := new(MsgCancelOrdersResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Msg/CancelOrders", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) RegisterContract(ctx context.Context, in *MsgRegisterContract, opts ...grpc.CallOption) (*MsgRegisterContractResponse, error) { + out := new(MsgRegisterContractResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Msg/RegisterContract", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) ContractDepositRent(ctx context.Context, in *MsgContractDepositRent, opts ...grpc.CallOption) (*MsgContractDepositRentResponse, error) { + out := new(MsgContractDepositRentResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Msg/ContractDepositRent", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UnregisterContract(ctx context.Context, in *MsgUnregisterContract, opts ...grpc.CallOption) (*MsgUnregisterContractResponse, error) { + out := new(MsgUnregisterContractResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Msg/UnregisterContract", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) RegisterPairs(ctx context.Context, in *MsgRegisterPairs, opts ...grpc.CallOption) (*MsgRegisterPairsResponse, error) { + out := new(MsgRegisterPairsResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Msg/RegisterPairs", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdatePriceTickSize(ctx context.Context, in *MsgUpdatePriceTickSize, opts ...grpc.CallOption) (*MsgUpdateTickSizeResponse, error) { + out := new(MsgUpdateTickSizeResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Msg/UpdatePriceTickSize", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UpdateQuantityTickSize(ctx context.Context, in *MsgUpdateQuantityTickSize, opts ...grpc.CallOption) (*MsgUpdateTickSizeResponse, error) { + out := new(MsgUpdateTickSizeResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Msg/UpdateQuantityTickSize", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *msgClient) UnsuspendContract(ctx context.Context, in *MsgUnsuspendContract, opts ...grpc.CallOption) (*MsgUnsuspendContractResponse, error) { + out := new(MsgUnsuspendContractResponse) + err := c.cc.Invoke(ctx, "/seiprotocol.seichain.dex.Msg/UnsuspendContract", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MsgServer is the server API for Msg service. +type MsgServer interface { + PlaceOrders(context.Context, *MsgPlaceOrders) (*MsgPlaceOrdersResponse, error) + CancelOrders(context.Context, *MsgCancelOrders) (*MsgCancelOrdersResponse, error) + RegisterContract(context.Context, *MsgRegisterContract) (*MsgRegisterContractResponse, error) + ContractDepositRent(context.Context, *MsgContractDepositRent) (*MsgContractDepositRentResponse, error) + UnregisterContract(context.Context, *MsgUnregisterContract) (*MsgUnregisterContractResponse, error) + RegisterPairs(context.Context, *MsgRegisterPairs) (*MsgRegisterPairsResponse, error) + UpdatePriceTickSize(context.Context, *MsgUpdatePriceTickSize) (*MsgUpdateTickSizeResponse, error) + UpdateQuantityTickSize(context.Context, *MsgUpdateQuantityTickSize) (*MsgUpdateTickSizeResponse, error) + UnsuspendContract(context.Context, *MsgUnsuspendContract) (*MsgUnsuspendContractResponse, error) +} + +// UnimplementedMsgServer can be embedded to have forward compatible implementations. +type UnimplementedMsgServer struct { +} + +func (*UnimplementedMsgServer) PlaceOrders(ctx context.Context, req *MsgPlaceOrders) (*MsgPlaceOrdersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PlaceOrders not implemented") +} +func (*UnimplementedMsgServer) CancelOrders(ctx context.Context, req *MsgCancelOrders) (*MsgCancelOrdersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CancelOrders not implemented") +} +func (*UnimplementedMsgServer) RegisterContract(ctx context.Context, req *MsgRegisterContract) (*MsgRegisterContractResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterContract not implemented") +} +func (*UnimplementedMsgServer) ContractDepositRent(ctx context.Context, req *MsgContractDepositRent) (*MsgContractDepositRentResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ContractDepositRent not implemented") +} +func (*UnimplementedMsgServer) UnregisterContract(ctx context.Context, req *MsgUnregisterContract) (*MsgUnregisterContractResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnregisterContract not implemented") +} +func (*UnimplementedMsgServer) RegisterPairs(ctx context.Context, req *MsgRegisterPairs) (*MsgRegisterPairsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RegisterPairs not implemented") +} +func (*UnimplementedMsgServer) UpdatePriceTickSize(ctx context.Context, req *MsgUpdatePriceTickSize) (*MsgUpdateTickSizeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdatePriceTickSize not implemented") +} +func (*UnimplementedMsgServer) UpdateQuantityTickSize(ctx context.Context, req *MsgUpdateQuantityTickSize) (*MsgUpdateTickSizeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateQuantityTickSize not implemented") +} +func (*UnimplementedMsgServer) UnsuspendContract(ctx context.Context, req *MsgUnsuspendContract) (*MsgUnsuspendContractResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UnsuspendContract not implemented") +} + +func RegisterMsgServer(s grpc1.Server, srv MsgServer) { + s.RegisterService(&_Msg_serviceDesc, srv) +} + +func _Msg_PlaceOrders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgPlaceOrders) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).PlaceOrders(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Msg/PlaceOrders", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).PlaceOrders(ctx, req.(*MsgPlaceOrders)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_CancelOrders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgCancelOrders) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).CancelOrders(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Msg/CancelOrders", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).CancelOrders(ctx, req.(*MsgCancelOrders)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_RegisterContract_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgRegisterContract) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).RegisterContract(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Msg/RegisterContract", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RegisterContract(ctx, req.(*MsgRegisterContract)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_ContractDepositRent_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgContractDepositRent) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).ContractDepositRent(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Msg/ContractDepositRent", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).ContractDepositRent(ctx, req.(*MsgContractDepositRent)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UnregisterContract_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUnregisterContract) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UnregisterContract(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Msg/UnregisterContract", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UnregisterContract(ctx, req.(*MsgUnregisterContract)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_RegisterPairs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgRegisterPairs) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).RegisterPairs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Msg/RegisterPairs", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).RegisterPairs(ctx, req.(*MsgRegisterPairs)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdatePriceTickSize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdatePriceTickSize) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdatePriceTickSize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Msg/UpdatePriceTickSize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdatePriceTickSize(ctx, req.(*MsgUpdatePriceTickSize)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UpdateQuantityTickSize_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUpdateQuantityTickSize) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UpdateQuantityTickSize(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Msg/UpdateQuantityTickSize", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UpdateQuantityTickSize(ctx, req.(*MsgUpdateQuantityTickSize)) + } + return interceptor(ctx, in, info, handler) +} + +func _Msg_UnsuspendContract_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MsgUnsuspendContract) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MsgServer).UnsuspendContract(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/seiprotocol.seichain.dex.Msg/UnsuspendContract", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MsgServer).UnsuspendContract(ctx, req.(*MsgUnsuspendContract)) + } + return interceptor(ctx, in, info, handler) +} + +var _Msg_serviceDesc = grpc.ServiceDesc{ + ServiceName: "seiprotocol.seichain.dex.Msg", + HandlerType: (*MsgServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PlaceOrders", + Handler: _Msg_PlaceOrders_Handler, + }, + { + MethodName: "CancelOrders", + Handler: _Msg_CancelOrders_Handler, + }, + { + MethodName: "RegisterContract", + Handler: _Msg_RegisterContract_Handler, + }, + { + MethodName: "ContractDepositRent", + Handler: _Msg_ContractDepositRent_Handler, + }, + { + MethodName: "UnregisterContract", + Handler: _Msg_UnregisterContract_Handler, + }, + { + MethodName: "RegisterPairs", + Handler: _Msg_RegisterPairs_Handler, + }, + { + MethodName: "UpdatePriceTickSize", + Handler: _Msg_UpdatePriceTickSize_Handler, + }, + { + MethodName: "UpdateQuantityTickSize", + Handler: _Msg_UpdateQuantityTickSize_Handler, + }, + { + MethodName: "UnsuspendContract", + Handler: _Msg_UnsuspendContract_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "dex/tx.proto", +} + +func (m *MsgPlaceOrders) 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 *MsgPlaceOrders) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgPlaceOrders) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Funds) > 0 { + for iNdEx := len(m.Funds) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Funds[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x1a + } + if len(m.Orders) > 0 { + for iNdEx := len(m.Orders) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Orders[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgPlaceOrdersResponse) 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 *MsgPlaceOrdersResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgPlaceOrdersResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.OrderIds) > 0 { + dAtA2 := make([]byte, len(m.OrderIds)*10) + var j1 int + for _, num := range m.OrderIds { + for num >= 1<<7 { + dAtA2[j1] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j1++ + } + dAtA2[j1] = uint8(num) + j1++ + } + i -= j1 + copy(dAtA[i:], dAtA2[:j1]) + i = encodeVarintTx(dAtA, i, uint64(j1)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgCancelOrders) 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 *MsgCancelOrders) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCancelOrders) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x1a + } + if len(m.Cancellations) > 0 { + for iNdEx := len(m.Cancellations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Cancellations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgCancelOrdersResponse) 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 *MsgCancelOrdersResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgCancelOrdersResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgRegisterContract) 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 *MsgRegisterContract) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRegisterContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Contract != nil { + { + size, err := m.Contract.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgRegisterContractResponse) 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 *MsgRegisterContractResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRegisterContractResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgContractDepositRent) 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 *MsgContractDepositRent) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgContractDepositRent) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Sender) > 0 { + i -= len(m.Sender) + copy(dAtA[i:], m.Sender) + i = encodeVarintTx(dAtA, i, uint64(len(m.Sender))) + i-- + dAtA[i] = 0x1a + } + if m.Amount != 0 { + i = encodeVarintTx(dAtA, i, uint64(m.Amount)) + i-- + dAtA[i] = 0x10 + } + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgContractDepositRentResponse) 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 *MsgContractDepositRentResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgContractDepositRentResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgUnregisterContract) 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 *MsgUnregisterContract) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUnregisterContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUnregisterContractResponse) 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 *MsgUnregisterContractResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUnregisterContractResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgRegisterPairs) 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 *MsgRegisterPairs) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRegisterPairs) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Batchcontractpair) > 0 { + for iNdEx := len(m.Batchcontractpair) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Batchcontractpair[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgRegisterPairsResponse) 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 *MsgRegisterPairsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgRegisterPairsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgUpdatePriceTickSize) 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 *MsgUpdatePriceTickSize) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdatePriceTickSize) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.TickSizeList) > 0 { + for iNdEx := len(m.TickSizeList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.TickSizeList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateQuantityTickSize) 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 *MsgUpdateQuantityTickSize) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateQuantityTickSize) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.TickSizeList) > 0 { + for iNdEx := len(m.TickSizeList) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.TickSizeList[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintTx(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUpdateTickSizeResponse) 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 *MsgUpdateTickSizeResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUpdateTickSizeResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *MsgUnsuspendContract) 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 *MsgUnsuspendContract) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUnsuspendContract) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.ContractAddr) > 0 { + i -= len(m.ContractAddr) + copy(dAtA[i:], m.ContractAddr) + i = encodeVarintTx(dAtA, i, uint64(len(m.ContractAddr))) + i-- + dAtA[i] = 0x12 + } + if len(m.Creator) > 0 { + i -= len(m.Creator) + copy(dAtA[i:], m.Creator) + i = encodeVarintTx(dAtA, i, uint64(len(m.Creator))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *MsgUnsuspendContractResponse) 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 *MsgUnsuspendContractResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MsgUnsuspendContractResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func encodeVarintTx(dAtA []byte, offset int, v uint64) int { + offset -= sovTx(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *MsgPlaceOrders) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.Orders) > 0 { + for _, e := range m.Orders { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.Funds) > 0 { + for _, e := range m.Funds { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *MsgPlaceOrdersResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.OrderIds) > 0 { + l = 0 + for _, e := range m.OrderIds { + l += sovTx(uint64(e)) + } + n += 1 + sovTx(uint64(l)) + l + } + return n +} + +func (m *MsgCancelOrders) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.Cancellations) > 0 { + for _, e := range m.Cancellations { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgCancelOrdersResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgRegisterContract) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Contract != nil { + l = m.Contract.Size() + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgRegisterContractResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgContractDepositRent) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if m.Amount != 0 { + n += 1 + sovTx(uint64(m.Amount)) + } + l = len(m.Sender) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgContractDepositRentResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgUnregisterContract) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgUnregisterContractResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgRegisterPairs) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.Batchcontractpair) > 0 { + for _, e := range m.Batchcontractpair { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *MsgRegisterPairsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgUpdatePriceTickSize) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.TickSizeList) > 0 { + for _, e := range m.TickSizeList { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *MsgUpdateQuantityTickSize) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + if len(m.TickSizeList) > 0 { + for _, e := range m.TickSizeList { + l = e.Size() + n += 1 + l + sovTx(uint64(l)) + } + } + return n +} + +func (m *MsgUpdateTickSizeResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *MsgUnsuspendContract) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Creator) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + l = len(m.ContractAddr) + if l > 0 { + n += 1 + l + sovTx(uint64(l)) + } + return n +} + +func (m *MsgUnsuspendContractResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func sovTx(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozTx(x uint64) (n int) { + return sovTx(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *MsgPlaceOrders) 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 ErrIntOverflowTx + } + 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: MsgPlaceOrders: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgPlaceOrders: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Orders", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Orders = append(m.Orders, &Order{}) + if err := m.Orders[len(m.Orders)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Funds", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Funds = append(m.Funds, types.Coin{}) + if err := m.Funds[len(m.Funds)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgPlaceOrdersResponse) 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 ErrIntOverflowTx + } + 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: MsgPlaceOrdersResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgPlaceOrdersResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.OrderIds = append(m.OrderIds, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.OrderIds) == 0 { + m.OrderIds = make([]uint64, 0, elementCount) + } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.OrderIds = append(m.OrderIds, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field OrderIds", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCancelOrders) 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 ErrIntOverflowTx + } + 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: MsgCancelOrders: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCancelOrders: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Cancellations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Cancellations = append(m.Cancellations, &Cancellation{}) + if err := m.Cancellations[len(m.Cancellations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgCancelOrdersResponse) 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 ErrIntOverflowTx + } + 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: MsgCancelOrdersResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgCancelOrdersResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRegisterContract) 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 ErrIntOverflowTx + } + 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: MsgRegisterContract: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRegisterContract: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Contract", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Contract == nil { + m.Contract = &ContractInfoV2{} + } + if err := m.Contract.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRegisterContractResponse) 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 ErrIntOverflowTx + } + 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: MsgRegisterContractResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRegisterContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgContractDepositRent) 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 ErrIntOverflowTx + } + 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: MsgContractDepositRent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgContractDepositRent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Amount", wireType) + } + m.Amount = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Amount |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Sender", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Sender = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgContractDepositRentResponse) 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 ErrIntOverflowTx + } + 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: MsgContractDepositRentResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgContractDepositRentResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUnregisterContract) 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 ErrIntOverflowTx + } + 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: MsgUnregisterContract: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUnregisterContract: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUnregisterContractResponse) 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 ErrIntOverflowTx + } + 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: MsgUnregisterContractResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUnregisterContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRegisterPairs) 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 ErrIntOverflowTx + } + 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: MsgRegisterPairs: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRegisterPairs: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Batchcontractpair", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Batchcontractpair = append(m.Batchcontractpair, BatchContractPair{}) + if err := m.Batchcontractpair[len(m.Batchcontractpair)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgRegisterPairsResponse) 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 ErrIntOverflowTx + } + 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: MsgRegisterPairsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgRegisterPairsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdatePriceTickSize) 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 ErrIntOverflowTx + } + 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: MsgUpdatePriceTickSize: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdatePriceTickSize: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TickSizeList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TickSizeList = append(m.TickSizeList, TickSize{}) + if err := m.TickSizeList[len(m.TickSizeList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateQuantityTickSize) 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 ErrIntOverflowTx + } + 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: MsgUpdateQuantityTickSize: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateQuantityTickSize: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TickSizeList", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.TickSizeList = append(m.TickSizeList, TickSize{}) + if err := m.TickSizeList[len(m.TickSizeList)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUpdateTickSizeResponse) 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 ErrIntOverflowTx + } + 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: MsgUpdateTickSizeResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUpdateTickSizeResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUnsuspendContract) 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 ErrIntOverflowTx + } + 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: MsgUnsuspendContract: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUnsuspendContract: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Creator", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Creator = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContractAddr", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + 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 ErrInvalidLengthTx + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ContractAddr = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MsgUnsuspendContractResponse) 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 ErrIntOverflowTx + } + 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: MsgUnsuspendContractResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MsgUnsuspendContractResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipTx(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthTx + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipTx(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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrIntOverflowTx + } + 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, ErrInvalidLengthTx + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupTx + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthTx + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthTx = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowTx = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupTx = fmt.Errorf("proto: unexpected end of group") +) diff --git a/x/dex/types/types.go b/x/dex/types/types.go new file mode 100644 index 000000000..7cc81e44f --- /dev/null +++ b/x/dex/types/types.go @@ -0,0 +1,6 @@ +package types + +var OppositePositionDirection = map[PositionDirection]PositionDirection{ + PositionDirection_LONG: PositionDirection_SHORT, + PositionDirection_SHORT: PositionDirection_LONG, +} diff --git a/x/dex/types/utils.go b/x/dex/types/utils.go new file mode 100644 index 000000000..2d5587813 --- /dev/null +++ b/x/dex/types/utils.go @@ -0,0 +1,14 @@ +package types + +import ( + "golang.org/x/text/cases" + "golang.org/x/text/language" +) + +func GetContractPositionDirection(direction PositionDirection) string { + return cases.Title(language.English).String(cases.Lower(language.English).String(PositionDirection_name[int32(direction)])) +} + +func GetContractOrderType(orderType OrderType) string { + return cases.Title(language.English).String(cases.Lower(language.English).String(OrderType_name[int32(orderType)])) +} diff --git a/x/dex/utils/context.go b/x/dex/utils/context.go new file mode 100644 index 000000000..7c7ca2740 --- /dev/null +++ b/x/dex/utils/context.go @@ -0,0 +1,18 @@ +package utils + +import ( + "context" + + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" +) + +type MemStateKeyType string + +const DexMemStateContextKey MemStateKeyType = MemStateKeyType("dex-memstate") + +func GetMemState(ctx context.Context) *dexcache.MemState { + if val := ctx.Value(DexMemStateContextKey); val != nil { + return val.(*dexcache.MemState) + } + return nil +} diff --git a/x/dex/utils/dec.go b/x/dex/utils/dec.go new file mode 100644 index 000000000..b43b70898 --- /dev/null +++ b/x/dex/utils/dec.go @@ -0,0 +1,71 @@ +package utils + +import ( + "encoding/binary" + "math/big" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func DecToBigEndian(d sdk.Dec) (res []byte) { + i := d.BigInt() + words := i.Bits() + // words are little-endian but we want big-endian so we start from the back + for idx := len(words) - 1; idx >= 0; idx-- { + bz := make([]byte, 8) + word := uint64(words[idx]) + if d.IsNegative() { + word = ^word + } + binary.BigEndian.PutUint64(bz, word) + res = append(res, bz...) + } + lastZeroByteIdx := -1 + for i := 0; i < len(res); i++ { + if res[i] != 0 { + break + } + lastZeroByteIdx = i + } + numNonZeroBytes := uint32(len(res) - lastZeroByteIdx - 1) + if d.IsNegative() { + numNonZeroBytes = ^numNonZeroBytes + } + lengthHeaderBz := make([]byte, 4) + binary.BigEndian.PutUint32(lengthHeaderBz, numNonZeroBytes) + res = append(lengthHeaderBz, res[lastZeroByteIdx+1:]...) + if d.IsNegative() { + res = append([]byte{0}, res...) + } else { + res = append([]byte{1}, res...) + } + return res +} + +func BytesToDec(bz []byte) sdk.Dec { + neg := bz[0] == 0 + length := binary.BigEndian.Uint32(bz[1:5]) + if neg { + length = ^length + } + paddingLength := 0 + if length%8 != 0 { + paddingLength = 8 - int(length)%8 + } + padding := make([]byte, paddingLength) + bz = append(padding, bz[5:]...) + words := []big.Word{} + for i := 0; i < len(bz); i += 8 { + word := binary.BigEndian.Uint64(bz[i : i+8]) + if neg { + word = ^word + } + words = append([]big.Word{big.Word(word)}, words...) + } + bi := &big.Int{} + bi.SetBits(words) + if neg { + bi.Neg(bi) + } + return sdk.NewDecFromBigIntWithPrec(bi, sdk.Precision) +} diff --git a/x/dex/utils/dec_test.go b/x/dex/utils/dec_test.go new file mode 100644 index 000000000..7d170cc42 --- /dev/null +++ b/x/dex/utils/dec_test.go @@ -0,0 +1,54 @@ +package utils + +import ( + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/stretchr/testify/require" +) + +var DECS = []sdk.Dec{ + sdk.MustNewDecFromStr("90.0"), + sdk.MustNewDecFromStr("10.01"), + sdk.MustNewDecFromStr("10"), + sdk.MustNewDecFromStr("9.99"), + sdk.MustNewDecFromStr("9.9"), + sdk.MustNewDecFromStr("9.0"), + sdk.MustNewDecFromStr("1"), + sdk.MustNewDecFromStr("0.001"), + sdk.MustNewDecFromStr("0"), + sdk.MustNewDecFromStr("-0.001"), + sdk.MustNewDecFromStr("-1"), + sdk.MustNewDecFromStr("-9.0"), + sdk.MustNewDecFromStr("-9.9"), + sdk.MustNewDecFromStr("-9.99"), + sdk.MustNewDecFromStr("-10"), + sdk.MustNewDecFromStr("-10.01"), + sdk.MustNewDecFromStr("-90.0"), +} + +func TestDecToBigEndian(t *testing.T) { + for i := 1; i < len(DECS); i++ { + require.True(t, compBz(DecToBigEndian(DECS[i-1]), DecToBigEndian(DECS[i]))) + } +} + +func TestBytesToDec(t *testing.T) { + for _, dec := range DECS { + require.Equal(t, dec, BytesToDec(DecToBigEndian(dec))) + } +} + +func compBz(b1 []byte, b2 []byte) bool { + ptr := 0 + for ; ptr < len(b1) && ptr < len(b2); ptr++ { + if b1[ptr] < b2[ptr] { + return false + } + if b1[ptr] > b2[ptr] { + return true + } + } + + return ptr >= len(b2) +} diff --git a/x/dex/utils/errors.go b/x/dex/utils/errors.go new file mode 100644 index 000000000..6139efd4f --- /dev/null +++ b/x/dex/utils/errors.go @@ -0,0 +1,11 @@ +package utils + +const ErrorByteLimit = 50 + +func GetTruncatedErrors(err error) string { + errStr := err.Error() + if len(errStr) <= ErrorByteLimit { + return errStr + } + return errStr[:ErrorByteLimit] +} diff --git a/x/epoch/module.go b/x/epoch/module.go index b030dfce5..f978e5919 100644 --- a/x/epoch/module.go +++ b/x/epoch/module.go @@ -74,6 +74,17 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo return genState.Validate() } +// ValidateGenesisStream performs genesis state validation for the capability module in a streaming fashion. +func (am AppModuleBasic) ValidateGenesisStream(cdc codec.JSONCodec, config client.TxEncodingConfig, genesisCh <-chan json.RawMessage) error { + for genesis := range genesisCh { + err := am.ValidateGenesis(cdc, config, genesis) + if err != nil { + return err + } + } + return nil +} + // RegisterRESTRoutes registers the capability module's REST service handlers. func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} @@ -164,6 +175,16 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw return cdc.MustMarshalJSON(genState) } +// ExportGenesisStream returns the capability module's exported genesis state as raw JSON bytes in a streaming fashion. +func (am AppModule) ExportGenesisStream(ctx sdk.Context, cdc codec.JSONCodec) <-chan json.RawMessage { + ch := make(chan json.RawMessage) + go func() { + ch <- am.ExportGenesis(ctx, cdc) + close(ch) + }() + return ch +} + // ConsensusVersion implements ConsensusVersion. func (AppModule) ConsensusVersion() uint64 { return 2 } diff --git a/x/evm/genesis.go b/x/evm/genesis.go index 7e3802b31..c90d3bf70 100644 --- a/x/evm/genesis.go +++ b/x/evm/genesis.go @@ -83,6 +83,91 @@ func ExportGenesis(ctx sdk.Context, k *keeper.Keeper) *types.GenesisState { return genesis } +// TODO: move to better location +var GENESIS_EXPORT_STREAM_SERIALIZED_LEN_MAX = 1000 + +func ExportGenesisStream(ctx sdk.Context, k *keeper.Keeper) <-chan *types.GenesisState { + ch := make(chan *types.GenesisState) + go func() { + genesis := types.DefaultGenesis() + genesis.Params = k.GetParams(ctx) + ch <- genesis + + k.IterateSeiAddressMapping(ctx, func(evmAddr common.Address, seiAddr sdk.AccAddress) bool { + var genesis types.GenesisState + genesis.Params = k.GetParams(ctx) + genesis.AddressAssociations = append(genesis.AddressAssociations, &types.AddressAssociation{ + SeiAddress: seiAddr.String(), + EthAddress: evmAddr.Hex(), + }) + ch <- &genesis + return false + }) + + k.IterateAllCode(ctx, func(addr common.Address, code []byte) bool { + var genesis types.GenesisState + genesis.Params = k.GetParams(ctx) + genesis.Codes = append(genesis.Codes, &types.Code{ + Address: addr.Hex(), + Code: code, + }) + ch <- &genesis + return false + }) + + k.IterateState(ctx, func(addr common.Address, key, val common.Hash) bool { + var genesis types.GenesisState + genesis.Params = k.GetParams(ctx) + genesis.States = append(genesis.States, &types.ContractState{ + Address: addr.Hex(), + Key: key[:], + Value: val[:], + }) + ch <- &genesis + return false + }) + + k.IterateAllNonces(ctx, func(addr common.Address, nonce uint64) bool { + var genesis types.GenesisState + genesis.Params = k.GetParams(ctx) + genesis.Nonces = append(genesis.Nonces, &types.Nonce{ + Address: addr.Hex(), + Nonce: nonce, + }) + ch <- &genesis + return false + }) + + for _, prefix := range [][]byte{ + types.ReceiptKeyPrefix, + types.BlockBloomPrefix, + types.TxHashesPrefix, + types.PointerRegistryPrefix, + types.PointerCWCodePrefix, + types.PointerReverseRegistryPrefix, + } { + genesis := types.DefaultGenesis() + genesis.Params = k.GetParams(ctx) + k.IterateAll(ctx, prefix, func(key, val []byte) bool { + genesis.Serialized = append(genesis.Serialized, &types.Serialized{ + Prefix: prefix, + Key: key, + Value: val, + }) + if len(genesis.Serialized) > GENESIS_EXPORT_STREAM_SERIALIZED_LEN_MAX { + ch <- genesis + genesis = types.DefaultGenesis() + genesis.Params = k.GetParams(ctx) + } + return false + }) + ch <- genesis + } + close(ch) + }() + return ch +} + // GetGenesisStateFromAppState returns x/evm GenesisState given raw application // genesis state. func GetGenesisStateFromAppState(cdc codec.JSONCodec, appState map[string]json.RawMessage) *types.GenesisState { diff --git a/x/evm/keeper/address.go b/x/evm/keeper/address.go index ac043e33c..a9c946b8b 100644 --- a/x/evm/keeper/address.go +++ b/x/evm/keeper/address.go @@ -74,3 +74,13 @@ func (k *Keeper) IterateSeiAddressMapping(ctx sdk.Context, cb func(evmAddr commo } } } + +// A sdk.AccAddress may not receive funds from bank if it's the result of direct-casting +// from an EVM address AND the originating EVM address has already been associated with +// a true (i.e. derived from the same pubkey) sdk.AccAddress. +func (k *Keeper) CanAddressReceive(ctx sdk.Context, addr sdk.AccAddress) bool { + directCast := common.BytesToAddress(addr) // casting goes both directions since both address formats have 20 bytes + associatedAddr, isAssociated := k.GetSeiAddress(ctx, directCast) + // if the associated address is the cast address itself, allow the address to receive (e.g. EVM contract addresses) + return associatedAddr.Equals(addr) || !isAssociated // this means it's either a cast address that's not associated yet, or not a cast address at all. +} diff --git a/x/evm/keeper/address_test.go b/x/evm/keeper/address_test.go index 825dfb565..25f341cfa 100644 --- a/x/evm/keeper/address_test.go +++ b/x/evm/keeper/address_test.go @@ -4,6 +4,7 @@ import ( "bytes" "testing" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/sei-protocol/sei-chain/testutil/keeper" "github.com/stretchr/testify/require" ) @@ -50,3 +51,22 @@ func TestGetAddressOrDefault(t *testing.T) { defaultSeiAddr := k.GetSeiAddressOrDefault(ctx, evmAddr) require.True(t, bytes.Equal(defaultSeiAddr, evmAddr[:])) } + +func TestSendingToCastAddress(t *testing.T) { + a := keeper.EVMTestApp + ctx := a.GetContextForDeliverTx([]byte{}) + seiAddr, evmAddr := keeper.MockAddressPair() + castAddr := sdk.AccAddress(evmAddr[:]) + sourceAddr, _ := keeper.MockAddressPair() + require.Nil(t, a.BankKeeper.MintCoins(ctx, "evm", sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(10))))) + require.Nil(t, a.BankKeeper.SendCoinsFromModuleToAccount(ctx, "evm", sourceAddr, sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(5))))) + amt := sdk.NewCoins(sdk.NewCoin("usei", sdk.NewInt(1))) + require.Nil(t, a.BankKeeper.SendCoinsFromModuleToAccount(ctx, "evm", castAddr, amt)) + require.Nil(t, a.BankKeeper.SendCoins(ctx, sourceAddr, castAddr, amt)) + require.Nil(t, a.BankKeeper.SendCoinsAndWei(ctx, sourceAddr, castAddr, sdk.OneInt(), sdk.OneInt())) + + a.EvmKeeper.SetAddressMapping(ctx, seiAddr, evmAddr) + require.NotNil(t, a.BankKeeper.SendCoinsFromModuleToAccount(ctx, "evm", castAddr, amt)) + require.NotNil(t, a.BankKeeper.SendCoins(ctx, sourceAddr, castAddr, amt)) + require.NotNil(t, a.BankKeeper.SendCoinsAndWei(ctx, sourceAddr, castAddr, sdk.OneInt(), sdk.OneInt())) +} diff --git a/x/evm/keeper/coinbase.go b/x/evm/keeper/coinbase.go index 378f4b9ca..39115f3bd 100644 --- a/x/evm/keeper/coinbase.go +++ b/x/evm/keeper/coinbase.go @@ -20,7 +20,8 @@ func (k *Keeper) GetFeeCollectorAddress(ctx sdk.Context) (common.Address, error) return *cache, nil } moduleAddr := k.accountKeeper.GetModuleAddress(authtypes.FeeCollectorName) - evmAddr, ok := k.GetEVMAddress(ctx, moduleAddr) + // we don't want to charge gas for this query, since it could cause non-determinism + evmAddr, ok := k.GetEVMAddress(ctx.WithGasMeter(sdk.NewInfiniteGasMeterWithMultiplier(ctx)), moduleAddr) if !ok { return common.Address{}, errors.New("fee collector's EVM address not found") } diff --git a/x/evm/keeper/deferred.go b/x/evm/keeper/deferred.go index 0a49bc5bd..06382b6f5 100644 --- a/x/evm/keeper/deferred.go +++ b/x/evm/keeper/deferred.go @@ -25,6 +25,9 @@ func (k *Keeper) GetAllEVMTxDeferredInfo(ctx sdk.Context) (res []*types.Deferred // this means the transaction got reverted during execution, either in ante handler // or due to a panic in msg server etx, _ := msg.AsTransaction() + if etx == nil { + panic("etx is nil for EVM DeferredInfo msg.AsTransaction(). This should never happen.") + } if txRes.Code == 0 { ctx.Logger().Error(fmt.Sprintf("transaction %s has code 0 but no deferred info", etx.Hash().Hex())) } diff --git a/x/evm/keeper/evm.go b/x/evm/keeper/evm.go index 3892b37d5..97695dc14 100644 --- a/x/evm/keeper/evm.go +++ b/x/evm/keeper/evm.go @@ -87,7 +87,7 @@ func (k *Keeper) CallEVM(ctx sdk.Context, from common.Address, to *common.Addres value = val.BigInt() } // This call was not part of an existing StateTransition, so it should trigger one - executionCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeterWithMultiplier(ctx)).WithIsEVM(true) + executionCtx := ctx.WithGasMeter(sdk.NewInfiniteGasMeterWithMultiplier(ctx)) stateDB := state.NewDBImpl(executionCtx, k, false) gp := k.GetGasPool() evmMsg := &core.Message{ diff --git a/x/evm/keeper/keeper.go b/x/evm/keeper/keeper.go index 895baf7b5..889f1c167 100644 --- a/x/evm/keeper/keeper.go +++ b/x/evm/keeper/keeper.go @@ -211,7 +211,7 @@ func (k *Keeper) GetVMBlockContext(ctx sdk.Context, gp core.GasPool) (*vm.BlockC Time: uint64(ctx.BlockHeader().Time.Unix()), Difficulty: utils.Big0, // only needed for PoW BaseFee: k.GetBaseFeePerGas(ctx).TruncateInt().BigInt(), // feemarket not enabled - BlobBaseFee: utils.Big0, // Cancun not enabled + BlobBaseFee: utils.Big1, // Cancun not enabled Random: &rh, }, nil } diff --git a/x/evm/keeper/msg_server.go b/x/evm/keeper/msg_server.go index db2737b5b..17bb8675d 100644 --- a/x/evm/keeper/msg_server.go +++ b/x/evm/keeper/msg_server.go @@ -63,6 +63,7 @@ func (server msgServer) EVMTransaction(goCtx context.Context, msg *types.MsgEVMT gp := server.GetGasPool() defer func() { + defer stateDB.Cleanup() if pe := recover(); pe != nil { if !strings.Contains(fmt.Sprintf("%s", pe), occtypes.ErrReadEstimate.Error()) { debug.PrintStack() diff --git a/x/evm/keeper/msg_server_test.go b/x/evm/keeper/msg_server_test.go index 79c68ce43..f8663da65 100644 --- a/x/evm/keeper/msg_server_test.go +++ b/x/evm/keeper/msg_server_test.go @@ -2,6 +2,7 @@ package keeper_test import ( "bytes" + "context" "crypto/sha256" "encoding/hex" "math/big" @@ -20,6 +21,8 @@ import ( "github.com/sei-protocol/sei-chain/example/contracts/sendall" "github.com/sei-protocol/sei-chain/example/contracts/simplestorage" testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" "github.com/sei-protocol/sei-chain/x/evm/ante" "github.com/sei-protocol/sei-chain/x/evm/artifacts/erc20" "github.com/sei-protocol/sei-chain/x/evm/artifacts/erc721" @@ -738,6 +741,9 @@ func TestAssociateContractAddress(t *testing.T) { func TestAssociate(t *testing.T) { ctx := testkeeper.EVMTestApp.GetContextForDeliverTx([]byte{}).WithChainID("sei-test").WithBlockHeight(1) + ctx = ctx.WithContext( + context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, &dexcache.MemState{}), + ) privKey := testkeeper.MockPrivateKey() seiAddr, evmAddr := testkeeper.PrivateKeyToAddresses(privKey) acc := testkeeper.EVMTestApp.AccountKeeper.NewAccountWithAddress(ctx, seiAddr) diff --git a/x/evm/migrations/migrate_cast_address_balances.go b/x/evm/migrations/migrate_cast_address_balances.go new file mode 100644 index 000000000..a620cb304 --- /dev/null +++ b/x/evm/migrations/migrate_cast_address_balances.go @@ -0,0 +1,31 @@ +package migrations + +import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/ethereum/go-ethereum/common" + "github.com/sei-protocol/sei-chain/x/evm/keeper" +) + +func MigrateCastAddressBalances(ctx sdk.Context, k *keeper.Keeper) (rerr error) { + k.IterateSeiAddressMapping(ctx, func(evmAddr common.Address, seiAddr sdk.AccAddress) bool { + castAddr := sdk.AccAddress(evmAddr[:]) + if balances := k.BankKeeper().SpendableCoins(ctx, castAddr); !balances.IsZero() { + if err := k.BankKeeper().SendCoins(ctx, castAddr, seiAddr, balances); err != nil { + ctx.Logger().Error(fmt.Sprintf("error migrating balances from cast address to real address for %s due to %s", evmAddr.Hex(), err)) + rerr = err + return true + } + } + if wei := k.BankKeeper().GetWeiBalance(ctx, castAddr); !wei.IsZero() { + if err := k.BankKeeper().SendCoinsAndWei(ctx, castAddr, seiAddr, sdk.ZeroInt(), wei); err != nil { + ctx.Logger().Error(fmt.Sprintf("error migrating wei from cast address to real address for %s due to %s", evmAddr.Hex(), err)) + rerr = err + return true + } + } + return false + }) + return +} diff --git a/x/evm/migrations/migrate_cast_address_balances_test.go b/x/evm/migrations/migrate_cast_address_balances_test.go new file mode 100644 index 000000000..e770637fa --- /dev/null +++ b/x/evm/migrations/migrate_cast_address_balances_test.go @@ -0,0 +1,37 @@ +package migrations_test + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + testkeeper "github.com/sei-protocol/sei-chain/testutil/keeper" + "github.com/sei-protocol/sei-chain/x/evm/migrations" + "github.com/sei-protocol/sei-chain/x/evm/types" + "github.com/stretchr/testify/require" +) + +func TestMigrateCastAddressBalances(t *testing.T) { + k := testkeeper.EVMTestApp.EvmKeeper + ctx := testkeeper.EVMTestApp.GetContextForDeliverTx([]byte{}).WithBlockTime(time.Now()) + require.Nil(t, k.BankKeeper().MintCoins(ctx, types.ModuleName, testkeeper.UseiCoins(100))) + // unassociated account with funds + seiAddr1, evmAddr1 := testkeeper.MockAddressPair() + require.Nil(t, k.BankKeeper().SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdk.AccAddress(evmAddr1[:]), testkeeper.UseiCoins(10))) + // associated account without funds + seiAddr2, evmAddr2 := testkeeper.MockAddressPair() + k.SetAddressMapping(ctx, seiAddr2, evmAddr2) + // associated account with funds + seiAddr3, evmAddr3 := testkeeper.MockAddressPair() + require.Nil(t, k.BankKeeper().SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdk.AccAddress(evmAddr3[:]), testkeeper.UseiCoins(10))) + k.SetAddressMapping(ctx, seiAddr3, evmAddr3) + + require.Nil(t, migrations.MigrateCastAddressBalances(ctx, &k)) + + require.Equal(t, sdk.NewInt(10), k.BankKeeper().GetBalance(ctx, sdk.AccAddress(evmAddr1[:]), "usei").Amount) + require.Equal(t, sdk.ZeroInt(), k.BankKeeper().GetBalance(ctx, seiAddr1, "usei").Amount) + require.Equal(t, sdk.ZeroInt(), k.BankKeeper().GetBalance(ctx, sdk.AccAddress(evmAddr2[:]), "usei").Amount) + require.Equal(t, sdk.ZeroInt(), k.BankKeeper().GetBalance(ctx, seiAddr2, "usei").Amount) + require.Equal(t, sdk.ZeroInt(), k.BankKeeper().GetBalance(ctx, sdk.AccAddress(evmAddr3[:]), "usei").Amount) + require.Equal(t, sdk.NewInt(10), k.BankKeeper().GetBalance(ctx, seiAddr3, "usei").Amount) +} diff --git a/x/evm/module.go b/x/evm/module.go index e877cfc20..b01858a70 100644 --- a/x/evm/module.go +++ b/x/evm/module.go @@ -64,7 +64,7 @@ func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage { return cdc.MustMarshalJSON(types.DefaultGenesis()) } -// ValidateGenesis performs genesis state validation for the capability module. +// ValidateGenesis performs genesis state validation for the evm module. func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingConfig, bz json.RawMessage) error { var genState types.GenesisState if err := cdc.UnmarshalJSON(bz, &genState); err != nil { @@ -73,6 +73,32 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo return genState.Validate() } +// ValidateGenesisStream performs genesis state validation for the evm module in a streaming fashion. +func (am AppModuleBasic) ValidateGenesisStream(cdc codec.JSONCodec, config client.TxEncodingConfig, genesisCh <-chan json.RawMessage) error { + genesisStateCh := make(chan types.GenesisState) + var err error + doneCh := make(chan struct{}) + go func() { + err = types.ValidateStream(genesisStateCh) + doneCh <- struct{}{} + }() + go func() { + defer close(genesisStateCh) + for genesis := range genesisCh { + var data types.GenesisState + err_ := cdc.UnmarshalJSON(genesis, &data) + if err_ != nil { + err = err_ + doneCh <- struct{}{} + return + } + genesisStateCh <- data + } + }() + <-doneCh + return err +} + // RegisterRESTRoutes registers the capability module's REST service handlers. func (AppModuleBasic) RegisterRESTRoutes(_ client.Context, _ *mux.Router) {} @@ -179,6 +205,10 @@ func (am AppModule) RegisterServices(cfg module.Configurator) { } return migrations.MigrateCWERC721Pointers(ctx, am.keeper) }) + + _ = cfg.RegisterMigration(types.ModuleName, 10, func(ctx sdk.Context) error { + return migrations.MigrateCastAddressBalances(ctx, am.keeper) + }) } // RegisterInvariants registers the capability module's invariants. @@ -202,8 +232,21 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw return cdc.MustMarshalJSON(genState) } +// ExportGenesisStream returns the evm module's exported genesis state as raw JSON bytes in a streaming fashion. +func (am AppModule) ExportGenesisStream(ctx sdk.Context, cdc codec.JSONCodec) <-chan json.RawMessage { + ch := ExportGenesisStream(ctx, am.keeper) + chRaw := make(chan json.RawMessage) + go func() { + for genState := range ch { + chRaw <- cdc.MustMarshalJSON(genState) + } + close(chRaw) + }() + return chRaw +} + // ConsensusVersion implements ConsensusVersion. -func (AppModule) ConsensusVersion() uint64 { return 10 } +func (AppModule) ConsensusVersion() uint64 { return 11 } // BeginBlock executes all ABCI BeginBlock logic respective to the capability module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { diff --git a/x/evm/module_test.go b/x/evm/module_test.go index 5f18e8624..cc59d3afc 100644 --- a/x/evm/module_test.go +++ b/x/evm/module_test.go @@ -63,7 +63,7 @@ func TestModuleExportGenesis(t *testing.T) { func TestConsensusVersion(t *testing.T) { k, _ := testkeeper.MockEVMKeeper() module := evm.NewAppModule(nil, k) - assert.Equal(t, uint64(10), module.ConsensusVersion()) + assert.Equal(t, uint64(11), module.ConsensusVersion()) } func TestABCI(t *testing.T) { diff --git a/x/evm/state/accesslist.go b/x/evm/state/accesslist.go index 21b98fd3a..f3c558e01 100644 --- a/x/evm/state/accesslist.go +++ b/x/evm/state/accesslist.go @@ -1,41 +1,61 @@ package state import ( - "encoding/json" - "github.com/ethereum/go-ethereum/common" ethtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" ) +// all custom precompiles have an address greater than or equal to this address +var CustomPrecompileStartingAddr = common.HexToAddress("0x0000000000000000000000000000000000001001") + // Forked from go-ethereum, except journaling logic which is unnecessary with cacheKV type accessList struct { - Addresses map[common.Address]int `json:"addresses"` - Slots []map[common.Hash]struct{} `json:"slots"` + Addresses map[common.Address]int + Slots []map[common.Hash]struct{} } func (s *DBImpl) AddressInAccessList(addr common.Address) bool { s.k.PrepareReplayedAddr(s.ctx, addr) - _, ok := s.getAccessList().Addresses[addr] - return ok + _, ok := s.getCurrentAccessList().Addresses[addr] + if ok { + return true + } + for _, ts := range s.tempStatesHist { + if _, ok := ts.transientAccessLists.Addresses[addr]; ok { + return true + } + } + return false } func (s *DBImpl) SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool) { s.k.PrepareReplayedAddr(s.ctx, addr) - al := s.getAccessList() - idx, ok := al.Addresses[addr] - if ok && idx != -1 { + al := s.getCurrentAccessList() + idx, addrOk := al.Addresses[addr] + if addrOk && idx != -1 { _, slotOk := al.Slots[idx][slot] - return ok, slotOk + if slotOk { + return true, true + } + } + for _, ts := range s.tempStatesHist { + idx, ok := ts.transientAccessLists.Addresses[addr] + addrOk = addrOk || ok + if ok && idx != -1 { + _, slotOk := ts.transientAccessLists.Slots[idx][slot] + if slotOk { + return true, true + } + } } - return ok, false + return addrOk, false } func (s *DBImpl) AddAddressToAccessList(addr common.Address) { s.k.PrepareReplayedAddr(s.ctx, addr) - al := s.getAccessList() - defer s.saveAccessList(al) + al := s.getCurrentAccessList() if _, present := al.Addresses[addr]; present { return } @@ -44,8 +64,7 @@ func (s *DBImpl) AddAddressToAccessList(addr common.Address) { func (s *DBImpl) AddSlotToAccessList(addr common.Address, slot common.Hash) { s.k.PrepareReplayedAddr(s.ctx, addr) - al := s.getAccessList() - defer s.saveAccessList(al) + al := s.getCurrentAccessList() idx, addrPresent := al.Addresses[addr] if !addrPresent || idx == -1 { // Address not present, or addr present but no slots there @@ -74,6 +93,10 @@ func (s *DBImpl) Prepare(_ params.Rules, sender, coinbase common.Address, dest * // If it's a create-tx, the destination will be added inside evm.create } for _, addr := range precompiles { + // skip any custom precompile + if addr.Cmp(CustomPrecompileStartingAddr) >= 0 { + continue + } s.AddAddressToAccessList(addr) } for _, el := range txAccesses { @@ -85,22 +108,6 @@ func (s *DBImpl) Prepare(_ params.Rules, sender, coinbase common.Address, dest * s.AddAddressToAccessList(coinbase) } -func (s *DBImpl) getAccessList() *accessList { - bz, found := s.getTransientModule(AccessListKey) - al := accessList{Addresses: make(map[common.Address]int)} - if !found || bz == nil { - return &al - } - if err := json.Unmarshal(bz, &al); err != nil { - panic(err) - } - return &al -} - -func (s *DBImpl) saveAccessList(al *accessList) { - albz, err := json.Marshal(al) - if err != nil { - panic(err) - } - s.tempStateCurrent.transientModuleStates[string(AccessListKey)] = albz +func (s *DBImpl) getCurrentAccessList() *accessList { + return s.tempStateCurrent.transientAccessLists } diff --git a/x/evm/state/keys.go b/x/evm/state/keys.go index f99ec0769..6404c1366 100644 --- a/x/evm/state/keys.go +++ b/x/evm/state/keys.go @@ -9,9 +9,8 @@ var ( // If evm module balance is higher than this value at the end of // the transaction, we need to burn from module balance in order // for this number to align. - GasRefundKey = []byte{0x01} - LogsKey = []byte{0x02} - AccessListKey = []byte{0x03} + GasRefundKey = []byte{0x01} + LogsKey = []byte{0x02} ) /* diff --git a/x/evm/state/statedb.go b/x/evm/state/statedb.go index 7cd888e82..101735618 100644 --- a/x/evm/state/statedb.go +++ b/x/evm/state/statedb.go @@ -81,6 +81,13 @@ func (s *DBImpl) SetEVM(evm *vm.EVM) {} // to the database. func (s *DBImpl) AddPreimage(_ common.Hash, _ []byte) {} +func (s *DBImpl) Cleanup() { + s.tempStateCurrent = nil + s.tempStatesHist = []*TemporaryState{} + s.logger = nil + s.snapshottedCtxs = nil +} + func (s *DBImpl) Finalize() (surplus sdk.Int, err error) { if s.simulation { panic("should never call finalize on a simulation DB") @@ -199,6 +206,7 @@ type TemporaryState struct { transientStates map[string]map[string]common.Hash transientAccounts map[string][]byte transientModuleStates map[string][]byte + transientAccessLists *accessList surplus sdk.Int // in wei } @@ -208,6 +216,7 @@ func NewTemporaryState() *TemporaryState { transientStates: make(map[string]map[string]common.Hash), transientAccounts: make(map[string][]byte), transientModuleStates: make(map[string][]byte), + transientAccessLists: &accessList{Addresses: make(map[common.Address]int), Slots: []map[common.Hash]struct{}{}}, surplus: utils.Sdk0, } } diff --git a/x/evm/types/genesis.go b/x/evm/types/genesis.go index 22bf94966..9b5228c98 100644 --- a/x/evm/types/genesis.go +++ b/x/evm/types/genesis.go @@ -9,3 +9,19 @@ func DefaultGenesis() *GenesisState { func (gs GenesisState) Validate() error { return gs.Params.Validate() } + +func ValidateStream(gensisStateCh <-chan GenesisState) error { + passedParamCheck := false + var paramCheckErr error + for genesisState := range gensisStateCh { + if err := genesisState.Validate(); err != nil { + paramCheckErr = err + } else { + passedParamCheck = true + } + } + if !passedParamCheck { + return paramCheckErr + } + return nil +} diff --git a/x/mint/keeper/hooks_test.go b/x/mint/keeper/hooks_test.go index 787bfe504..760eea3dd 100644 --- a/x/mint/keeper/hooks_test.go +++ b/x/mint/keeper/hooks_test.go @@ -1,10 +1,14 @@ package keeper_test import ( + "context" "testing" "time" keepertest "github.com/sei-protocol/sei-chain/testutil/keeper" + dexcache "github.com/sei-protocol/sei-chain/x/dex/cache" + dextypes "github.com/sei-protocol/sei-chain/x/dex/types" + dexutils "github.com/sei-protocol/sei-chain/x/dex/utils" "github.com/sei-protocol/sei-chain/x/epoch/types" minttypes "github.com/sei-protocol/sei-chain/x/mint/types" "github.com/stretchr/testify/require" @@ -34,6 +38,7 @@ func TestEndOfEpochMintedCoinDistribution(t *testing.T) { t.Run("Initial should be zero", func(t *testing.T) { seiApp := keepertest.TestApp() ctx := seiApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(seiApp.GetMemKey(dextypes.MemStoreKey)))) header := tmproto.Header{ Height: seiApp.LastBlockHeight() + 1, @@ -46,6 +51,7 @@ func TestEndOfEpochMintedCoinDistribution(t *testing.T) { t.Run("even full release", func(t *testing.T) { seiApp := keepertest.TestApp() ctx := seiApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(seiApp.GetMemKey(dextypes.MemStoreKey)))) header := tmproto.Header{ Height: seiApp.LastBlockHeight() + 1, @@ -91,6 +97,7 @@ func TestEndOfEpochMintedCoinDistribution(t *testing.T) { t.Run("uneven full release", func(t *testing.T) { seiApp := keepertest.TestApp() ctx := seiApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(seiApp.GetMemKey(dextypes.MemStoreKey)))) header := tmproto.Header{ Height: seiApp.LastBlockHeight() + 1, @@ -137,6 +144,7 @@ func TestEndOfEpochMintedCoinDistribution(t *testing.T) { t.Run("multiple full releases", func(t *testing.T) { seiApp := keepertest.TestApp() ctx := seiApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(seiApp.GetMemKey(dextypes.MemStoreKey)))) header := tmproto.Header{ Height: seiApp.LastBlockHeight() + 1, @@ -195,6 +203,7 @@ func TestEndOfEpochMintedCoinDistribution(t *testing.T) { t.Run("outage during release", func(t *testing.T) { seiApp := keepertest.TestApp() ctx := seiApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(seiApp.GetMemKey(dextypes.MemStoreKey)))) header := tmproto.Header{ Height: seiApp.LastBlockHeight() + 1, @@ -269,6 +278,7 @@ func TestEndOfEpochMintedCoinDistribution(t *testing.T) { func TestNoEpochPassedNoDistribution(t *testing.T) { seiApp := keepertest.TestApp() ctx := seiApp.BaseApp.NewContext(false, tmproto.Header{Time: time.Now()}) + ctx = ctx.WithContext(context.WithValue(ctx.Context(), dexutils.DexMemStateContextKey, dexcache.NewMemState(seiApp.GetMemKey(dextypes.MemStoreKey)))) header := tmproto.Header{Height: seiApp.LastBlockHeight() + 1} seiApp.BeginBlock(ctx, abci.RequestBeginBlock{Header: header}) diff --git a/x/mint/module.go b/x/mint/module.go index d563d9221..661a61578 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -71,6 +71,17 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo return types.ValidateGenesis(data) } +// ValidateGenesisStream performs genesis state validation for the mint module in a streaming fashion. +func (am AppModuleBasic) ValidateGenesisStream(cdc codec.JSONCodec, config client.TxEncodingConfig, genesisCh <-chan json.RawMessage) error { + for genesis := range genesisCh { + err := am.ValidateGenesis(cdc, config, genesis) + if err != nil { + return err + } + } + return nil +} + // RegisterRESTRoutes registers the REST routes for the mint module. func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { rest.RegisterRoutes(clientCtx, rtr) @@ -155,6 +166,16 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw return cdc.MustMarshalJSON(gs) } +// ExportGenesisStream returns the mint module's exported genesis state as raw JSON bytes in a streaming fashion. +func (am AppModule) ExportGenesisStream(ctx sdk.Context, cdc codec.JSONCodec) <-chan json.RawMessage { + ch := make(chan json.RawMessage) + go func() { + ch <- am.ExportGenesis(ctx, cdc) + close(ch) + }() + return ch +} + // ConsensusVersion implements AppModule/ConsensusVersion. func (AppModule) ConsensusVersion() uint64 { return 3 } diff --git a/x/mint/types/gov.pb.go b/x/mint/types/gov.pb.go index 32a3d8c9a..4ebcd8a7e 100644 --- a/x/mint/types/gov.pb.go +++ b/x/mint/types/gov.pb.go @@ -23,6 +23,8 @@ var _ = math.Inf // proto package needs to be updated. const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package +// AddAssetMetadataProposal is a gov Content type for adding a new asset +// to the dex module's asset list. type UpdateMinterProposal struct { Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty" yaml:"title"` Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` diff --git a/x/oracle/module.go b/x/oracle/module.go index e69d68ad0..02c6f9cc0 100644 --- a/x/oracle/module.go +++ b/x/oracle/module.go @@ -68,6 +68,17 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, _ client.TxEncodingCo return types.ValidateGenesis(&data) } +// ValidateGenesisStream performs genesis state validation for the oracle module in a streaming fashion. +func (am AppModuleBasic) ValidateGenesisStream(cdc codec.JSONCodec, config client.TxEncodingConfig, genesisCh <-chan json.RawMessage) error { + for genesis := range genesisCh { + err := am.ValidateGenesis(cdc, config, genesis) + if err != nil { + return err + } + } + return nil +} + // RegisterRESTRoutes registers the REST routes for the oracle module. func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router) { rest.RegisterRoutes(clientCtx, rtr) @@ -163,6 +174,16 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw return cdc.MustMarshalJSON(gs) } +// ExportGenesisStream returns the oracle module's exported genesis state as raw JSON bytes in a streaming fashion. +func (am AppModule) ExportGenesisStream(ctx sdk.Context, cdc codec.JSONCodec) <-chan json.RawMessage { + ch := make(chan json.RawMessage) + go func() { + ch <- am.ExportGenesis(ctx, cdc) + close(ch) + }() + return ch +} + // ConsensusVersion implements AppModule/ConsensusVersion. func (AppModule) ConsensusVersion() uint64 { return 6 } diff --git a/x/tokenfactory/module.go b/x/tokenfactory/module.go index 89a97560d..c9279e187 100644 --- a/x/tokenfactory/module.go +++ b/x/tokenfactory/module.go @@ -172,6 +172,27 @@ func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.Raw return cdc.MustMarshalJSON(genState) } +// ExportGenesisStream returns the tokenfactory module's exported genesis state as raw JSON bytes in a streaming fashion. +func (am AppModule) ExportGenesisStream(ctx sdk.Context, cdc codec.JSONCodec) <-chan json.RawMessage { + ch := make(chan json.RawMessage) + go func() { + ch <- am.ExportGenesis(ctx, cdc) + close(ch) + }() + return ch +} + +// ValidateGenesisStream performs genesis state validation for the x/tokenfactory module in a streaming fashion. +func (am AppModuleBasic) ValidateGenesisStream(cdc codec.JSONCodec, config client.TxEncodingConfig, genesisCh <-chan json.RawMessage) error { + for genesis := range genesisCh { + err := am.ValidateGenesis(cdc, config, genesis) + if err != nil { + return err + } + } + return nil +} + // ConsensusVersion implements ConsensusVersion. func (AppModule) ConsensusVersion() uint64 { return 4 }