Skip to content

Commit 9720c80

Browse files
authored
Merge pull request #300 from InjectiveLabs/fix/sync_dev_with_master_1_12_0
Fix/sync dev with master 1.12.0
2 parents 9105d5b + f31992d commit 9720c80

File tree

293 files changed

+6207
-6144
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

293 files changed

+6207
-6144
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [1.2.0] - 2024-01-25
6+
### Changed
7+
- Updated reference gas cost for all messages in the gas estimator
8+
- Included different calculation for Post Only orders
9+
- Updated all proto definitions for Injective Core 1.12.1
10+
11+
## [1.1.1] - 2024-01-18
12+
### Changed
13+
- Updated the logic to create a `MsgLiquidatePosition` message
14+
515
## [1.1.0] - 2024-01-15
616
### Added
717
- Added new functions in all Market classes to convert values from extended chain format (the ones provided by chain streams) into human-readable format

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ clean-all:
2828
$(call clean_repos)
2929

3030
clone-injective-core:
31-
git clone https://github.com/InjectiveLabs/injective-core.git -b v1.12.0 --depth 1 --single-branch
31+
git clone https://github.com/InjectiveLabs/injective-core.git -b v1.12.1 --depth 1 --single-branch
3232

3333
clone-injective-indexer:
3434
git clone https://github.com/InjectiveLabs/injective-indexer.git -b v1.12.79.1 --depth 1 --single-branch
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import asyncio
2+
import uuid
3+
4+
from grpc import RpcError
5+
6+
from pyinjective.async_client import AsyncClient
7+
from pyinjective.constant import GAS_FEE_BUFFER_AMOUNT, GAS_PRICE
8+
from pyinjective.core.network import Network
9+
from pyinjective.transaction import Transaction
10+
from pyinjective.wallet import PrivateKey
11+
12+
13+
async def main() -> None:
14+
# select network: local, testnet, mainnet
15+
network = Network.testnet()
16+
17+
# initialize grpc client
18+
client = AsyncClient(network)
19+
composer = await client.composer()
20+
await client.sync_timeout_height()
21+
22+
# load account
23+
priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3")
24+
pub_key = priv_key.to_public_key()
25+
address = pub_key.to_address()
26+
await client.fetch_account(address.to_acc_bech32())
27+
subaccount_id = address.get_subaccount_id(index=0)
28+
29+
# prepare trade info
30+
market_id = "0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
31+
fee_recipient = "inj1hkhdaj2a2clmq5jq6mspsggqs32vynpk228q3r"
32+
cid = str(uuid.uuid4())
33+
34+
order = composer.DerivativeOrder(
35+
market_id=market_id,
36+
subaccount_id=subaccount_id,
37+
fee_recipient=fee_recipient,
38+
price=39.01, # This should be the liquidation price
39+
quantity=0.147,
40+
leverage=1,
41+
cid=cid,
42+
is_buy=False,
43+
)
44+
45+
# prepare tx msg
46+
msg = composer.MsgLiquidatePosition(
47+
sender=address.to_acc_bech32(),
48+
subaccount_id="0x156df4d5bc8e7dd9191433e54bd6a11eeb390921000000000000000000000000",
49+
market_id=market_id,
50+
order=order,
51+
)
52+
53+
# build sim tx
54+
tx = (
55+
Transaction()
56+
.with_messages(msg)
57+
.with_sequence(client.get_sequence())
58+
.with_account_num(client.get_number())
59+
.with_chain_id(network.chain_id)
60+
)
61+
sim_sign_doc = tx.get_sign_doc(pub_key)
62+
sim_sig = priv_key.sign(sim_sign_doc.SerializeToString())
63+
sim_tx_raw_bytes = tx.get_tx_data(sim_sig, pub_key)
64+
65+
# simulate tx
66+
try:
67+
sim_res = await client.simulate(sim_tx_raw_bytes)
68+
except RpcError as ex:
69+
print(ex)
70+
return
71+
72+
sim_res_msg = sim_res["result"]["msgResponses"]
73+
print("---Simulation Response---")
74+
print(sim_res_msg)
75+
76+
# build tx
77+
gas_price = GAS_PRICE
78+
gas_limit = int(sim_res["gasInfo"]["gasUsed"]) + GAS_FEE_BUFFER_AMOUNT # add buffer for gas fee computation
79+
gas_fee = "{:.18f}".format((gas_price * gas_limit) / pow(10, 18)).rstrip("0")
80+
fee = [
81+
composer.Coin(
82+
amount=gas_price * gas_limit,
83+
denom=network.fee_denom,
84+
)
85+
]
86+
tx = tx.with_gas(gas_limit).with_fee(fee).with_memo("").with_timeout_height(client.timeout_height)
87+
sign_doc = tx.get_sign_doc(pub_key)
88+
sig = priv_key.sign(sign_doc.SerializeToString())
89+
tx_raw_bytes = tx.get_tx_data(sig, pub_key)
90+
91+
# broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
92+
res = await client.broadcast_tx_sync_mode(tx_raw_bytes)
93+
print("---Transaction Response---")
94+
print(res)
95+
print("gas wanted: {}".format(gas_limit))
96+
print("gas fee: {} INJ".format(gas_fee))
97+
print(f"\n\ncid: {cid}")
98+
99+
100+
if __name__ == "__main__":
101+
asyncio.get_event_loop().run_until_complete(main())

examples/exchange_client/oracle_rpc/1_StreamPrices.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@ async def main() -> None:
2323
# select network: local, testnet, mainnet
2424
network = Network.testnet()
2525
client = AsyncClient(network)
26-
base_symbol = "INJ"
27-
quote_symbol = "USDT"
28-
oracle_type = "bandibc"
26+
market = (await client.all_derivative_markets())[
27+
"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
28+
]
29+
30+
base_symbol = market.oracle_base
31+
quote_symbol = market.oracle_quote
32+
oracle_type = market.oracle_type
2933

3034
task = asyncio.get_event_loop().create_task(
3135
client.listen_oracle_prices_updates(

examples/exchange_client/oracle_rpc/2_Price.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,18 @@ async def main() -> None:
88
# select network: local, testnet, mainnet
99
network = Network.testnet()
1010
client = AsyncClient(network)
11-
base_symbol = "BTC"
12-
quote_symbol = "USDT"
13-
oracle_type = "bandibc"
14-
oracle_scale_factor = 6
11+
market = (await client.all_derivative_markets())[
12+
"0x17ef48032cb24375ba7c2e39f384e56433bcab20cbee9a7357e4cba2eb00abe6"
13+
]
14+
15+
base_symbol = market.oracle_base
16+
quote_symbol = market.oracle_quote
17+
oracle_type = market.oracle_type
18+
1519
oracle_prices = await client.fetch_oracle_price(
1620
base_symbol=base_symbol,
1721
quote_symbol=quote_symbol,
1822
oracle_type=oracle_type,
19-
oracle_scale_factor=oracle_scale_factor,
2023
)
2124
print(oracle_prices)
2225

pyinjective/composer.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,9 +671,15 @@ def MsgBatchUpdateOrders(self, sender: str, **kwargs):
671671
binary_options_orders_to_create=kwargs.get("binary_options_orders_to_create"),
672672
)
673673

674-
def MsgLiquidatePosition(self, sender: str, subaccount_id: str, market_id: str):
674+
def MsgLiquidatePosition(
675+
self,
676+
sender: str,
677+
subaccount_id: str,
678+
market_id: str,
679+
order: Optional[injective_dot_exchange_dot_v1beta1_dot_exchange__pb2.DerivativeOrder] = None,
680+
):
675681
return injective_exchange_tx_pb.MsgLiquidatePosition(
676-
sender=sender, subaccount_id=subaccount_id, market_id=market_id
682+
sender=sender, subaccount_id=subaccount_id, market_id=market_id, order=order
677683
)
678684

679685
def MsgIncreasePositionMargin(

pyinjective/core/gas_limit_estimator.py

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,28 @@
1+
import math
12
from abc import ABC, abstractmethod
3+
from typing import List, Union
24

35
from google.protobuf import any_pb2
46

57
from pyinjective.proto.cosmos.authz.v1beta1 import tx_pb2 as cosmos_authz_tx_pb
68
from pyinjective.proto.cosmos.gov.v1beta1 import tx_pb2 as gov_tx_pb
79
from pyinjective.proto.cosmwasm.wasm.v1 import tx_pb2 as wasm_tx_pb
8-
from pyinjective.proto.injective.exchange.v1beta1 import tx_pb2 as injective_exchange_tx_pb
10+
from pyinjective.proto.injective.exchange.v1beta1 import (
11+
exchange_pb2 as injective_exchange_pb,
12+
tx_pb2 as injective_exchange_tx_pb,
13+
)
14+
15+
SPOT_ORDER_CREATION_GAS_LIMIT = 50_000
16+
DERIVATIVE_ORDER_CREATION_GAS_LIMIT = 70_000
17+
SPOT_ORDER_CANCELATION_GAS_LIMIT = 50_000
18+
DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT = 60_000
19+
# POST ONLY orders take around 50% more gas to create than normal orders due to the required validations
20+
SPOT_POST_ONLY_ORDER_MULTIPLIER = 0.5
21+
DERIVATIVE_POST_ONLY_ORDER_MULTIPLIER = 0.5
922

1023

1124
class GasLimitEstimator(ABC):
12-
GENERAL_MESSAGE_GAS_LIMIT = 5_000
25+
GENERAL_MESSAGE_GAS_LIMIT = 15_000
1326
BASIC_REFERENCE_GAS_LIMIT = 150_000
1427

1528
@classmethod
@@ -57,6 +70,16 @@ def _parsed_message(self, message: any_pb2.Any) -> any_pb2.Any:
5770
parsed_message = message
5871
return parsed_message
5972

73+
def _select_post_only_orders(
74+
self,
75+
orders: List[Union[injective_exchange_pb.SpotOrder, injective_exchange_pb.DerivativeOrder]],
76+
) -> List[Union[injective_exchange_pb.SpotOrder, injective_exchange_pb.DerivativeOrder]]:
77+
return [
78+
order
79+
for order in orders
80+
if order.order_type in [injective_exchange_pb.OrderType.BUY_PO, injective_exchange_pb.OrderType.SELL_PO]
81+
]
82+
6083

6184
class DefaultGasLimitEstimator(GasLimitEstimator):
6285
DEFAULT_GAS_LIMIT = 150_000
@@ -74,8 +97,6 @@ def _message_class(self, message: any_pb2.Any):
7497

7598

7699
class BatchCreateSpotLimitOrdersGasLimitEstimator(GasLimitEstimator):
77-
ORDER_GAS_LIMIT = 45_000
78-
79100
def __init__(self, message: any_pb2.Any):
80101
self._message = self._parsed_message(message=message)
81102

@@ -84,9 +105,12 @@ def applies_to(cls, message: any_pb2.Any):
84105
return cls.message_type(message=message).endswith("MsgBatchCreateSpotLimitOrders")
85106

86107
def gas_limit(self) -> int:
108+
post_only_orders = self._select_post_only_orders(orders=self._message.orders)
109+
87110
total = 0
88111
total += self.GENERAL_MESSAGE_GAS_LIMIT
89-
total += len(self._message.orders) * self.ORDER_GAS_LIMIT
112+
total += len(self._message.orders) * SPOT_ORDER_CREATION_GAS_LIMIT
113+
total += math.ceil(len(post_only_orders) * SPOT_ORDER_CREATION_GAS_LIMIT * SPOT_POST_ONLY_ORDER_MULTIPLIER)
90114

91115
return total
92116

@@ -95,8 +119,6 @@ def _message_class(self, message: any_pb2.Any):
95119

96120

97121
class BatchCancelSpotOrdersGasLimitEstimator(GasLimitEstimator):
98-
ORDER_GAS_LIMIT = 45_000
99-
100122
def __init__(self, message: any_pb2.Any):
101123
self._message = self._parsed_message(message=message)
102124

@@ -107,7 +129,7 @@ def applies_to(cls, message: any_pb2.Any):
107129
def gas_limit(self) -> int:
108130
total = 0
109131
total += self.GENERAL_MESSAGE_GAS_LIMIT
110-
total += len(self._message.data) * self.ORDER_GAS_LIMIT
132+
total += len(self._message.data) * SPOT_ORDER_CANCELATION_GAS_LIMIT
111133

112134
return total
113135

@@ -116,8 +138,6 @@ def _message_class(self, message: any_pb2.Any):
116138

117139

118140
class BatchCreateDerivativeLimitOrdersGasLimitEstimator(GasLimitEstimator):
119-
ORDER_GAS_LIMIT = 60_000
120-
121141
def __init__(self, message: any_pb2.Any):
122142
self._message = self._parsed_message(message=message)
123143

@@ -126,9 +146,14 @@ def applies_to(cls, message: any_pb2.Any):
126146
return cls.message_type(message=message).endswith("MsgBatchCreateDerivativeLimitOrders")
127147

128148
def gas_limit(self) -> int:
149+
post_only_orders = self._select_post_only_orders(orders=self._message.orders)
150+
129151
total = 0
130152
total += self.GENERAL_MESSAGE_GAS_LIMIT
131-
total += len(self._message.orders) * self.ORDER_GAS_LIMIT
153+
total += len(self._message.orders) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT
154+
total += math.ceil(
155+
len(post_only_orders) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT * DERIVATIVE_POST_ONLY_ORDER_MULTIPLIER
156+
)
132157

133158
return total
134159

@@ -137,8 +162,6 @@ def _message_class(self, message: any_pb2.Any):
137162

138163

139164
class BatchCancelDerivativeOrdersGasLimitEstimator(GasLimitEstimator):
140-
ORDER_GAS_LIMIT = 55_000
141-
142165
def __init__(self, message: any_pb2.Any):
143166
self._message = self._parsed_message(message=message)
144167

@@ -149,7 +172,7 @@ def applies_to(cls, message: any_pb2.Any):
149172
def gas_limit(self) -> int:
150173
total = 0
151174
total += self.GENERAL_MESSAGE_GAS_LIMIT
152-
total += len(self._message.data) * self.ORDER_GAS_LIMIT
175+
total += len(self._message.data) * DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT
153176

154177
return total
155178

@@ -158,13 +181,9 @@ def _message_class(self, message: any_pb2.Any):
158181

159182

160183
class BatchUpdateOrdersGasLimitEstimator(GasLimitEstimator):
161-
SPOT_ORDER_CREATION_GAS_LIMIT = 40_000
162-
DERIVATIVE_ORDER_CREATION_GAS_LIMIT = 60_000
163-
SPOT_ORDER_CANCELATION_GAS_LIMIT = 45_000
164-
DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT = 55_000
165-
CANCEL_ALL_SPOT_MARKET_GAS_LIMIT = 35_000
166-
CANCEL_ALL_DERIVATIVE_MARKET_GAS_LIMIT = 45_000
167-
MESSAGE_GAS_LIMIT = 10_000
184+
CANCEL_ALL_SPOT_MARKET_GAS_LIMIT = 40_000
185+
CANCEL_ALL_DERIVATIVE_MARKET_GAS_LIMIT = 50_000
186+
MESSAGE_GAS_LIMIT = 15_000
168187

169188
AVERAGE_CANCEL_ALL_AFFECTED_ORDERS = 20
170189

@@ -176,14 +195,33 @@ def applies_to(cls, message: any_pb2.Any):
176195
return cls.message_type(message=message).endswith("MsgBatchUpdateOrders")
177196

178197
def gas_limit(self) -> int:
198+
post_only_spot_orders = self._select_post_only_orders(orders=self._message.spot_orders_to_create)
199+
post_only_derivative_orders = self._select_post_only_orders(orders=self._message.derivative_orders_to_create)
200+
post_only_binary_options_orders = self._select_post_only_orders(
201+
orders=self._message.binary_options_orders_to_create
202+
)
203+
179204
total = 0
180205
total += self.MESSAGE_GAS_LIMIT
181-
total += len(self._message.spot_orders_to_create) * self.SPOT_ORDER_CREATION_GAS_LIMIT
182-
total += len(self._message.derivative_orders_to_create) * self.DERIVATIVE_ORDER_CREATION_GAS_LIMIT
183-
total += len(self._message.binary_options_orders_to_create) * self.DERIVATIVE_ORDER_CREATION_GAS_LIMIT
184-
total += len(self._message.spot_orders_to_cancel) * self.SPOT_ORDER_CANCELATION_GAS_LIMIT
185-
total += len(self._message.derivative_orders_to_cancel) * self.DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT
186-
total += len(self._message.binary_options_orders_to_cancel) * self.DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT
206+
total += len(self._message.spot_orders_to_create) * SPOT_ORDER_CREATION_GAS_LIMIT
207+
total += len(self._message.derivative_orders_to_create) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT
208+
total += len(self._message.binary_options_orders_to_create) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT
209+
210+
total += math.ceil(len(post_only_spot_orders) * SPOT_ORDER_CREATION_GAS_LIMIT * SPOT_POST_ONLY_ORDER_MULTIPLIER)
211+
total += math.ceil(
212+
len(post_only_derivative_orders)
213+
* DERIVATIVE_ORDER_CREATION_GAS_LIMIT
214+
* DERIVATIVE_POST_ONLY_ORDER_MULTIPLIER
215+
)
216+
total += math.ceil(
217+
len(post_only_binary_options_orders)
218+
* DERIVATIVE_ORDER_CREATION_GAS_LIMIT
219+
* DERIVATIVE_POST_ONLY_ORDER_MULTIPLIER
220+
)
221+
222+
total += len(self._message.spot_orders_to_cancel) * SPOT_ORDER_CANCELATION_GAS_LIMIT
223+
total += len(self._message.derivative_orders_to_cancel) * DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT
224+
total += len(self._message.binary_options_orders_to_cancel) * DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT
187225

188226
total += (
189227
len(self._message.spot_market_ids_to_cancel_all)
@@ -208,7 +246,7 @@ def _message_class(self, message: any_pb2.Any):
208246

209247

210248
class ExecGasLimitEstimator(GasLimitEstimator):
211-
DEFAULT_GAS_LIMIT = 5_000
249+
DEFAULT_GAS_LIMIT = 8_000
212250

213251
def __init__(self, message: any_pb2.Any):
214252
self._message = self._parsed_message(message=message)
@@ -297,7 +335,7 @@ def _message_class(self, message: any_pb2.Any):
297335

298336

299337
class GenericExchangeGasLimitEstimator(GasLimitEstimator):
300-
BASIC_REFERENCE_GAS_LIMIT = 100_000
338+
BASIC_REFERENCE_GAS_LIMIT = 120_000
301339

302340
def __init__(self, message: any_pb2.Any):
303341
self._message = message

0 commit comments

Comments
 (0)