Skip to content

Commit

Permalink
(fix) Added extra logic to increase the gas cost for post only order
Browse files Browse the repository at this point in the history
  • Loading branch information
abel committed Jan 24, 2024
1 parent ae051f4 commit 6eefa4c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
## [1.2.0] - 2024-01-24
### Changed
- Updated reference gas cost for all messages in the gas estimator
- Included different calculation for Post Only orders
- Updated all proto definitions for Injective Core 1.12.1

## [1.1.1] - 2024-01-18
Expand Down
79 changes: 55 additions & 24 deletions pyinjective/core/gas_limit_estimator.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
import math
from abc import ABC, abstractmethod
from typing import List, Union

from google.protobuf import any_pb2

from pyinjective.proto.cosmos.authz.v1beta1 import tx_pb2 as cosmos_authz_tx_pb
from pyinjective.proto.cosmos.gov.v1beta1 import tx_pb2 as gov_tx_pb
from pyinjective.proto.cosmwasm.wasm.v1 import tx_pb2 as wasm_tx_pb
from pyinjective.proto.injective.exchange.v1beta1 import tx_pb2 as injective_exchange_tx_pb
from pyinjective.proto.injective.exchange.v1beta1 import (
exchange_pb2 as injective_exchange_pb,
tx_pb2 as injective_exchange_tx_pb,
)

SPOT_ORDER_CREATION_GAS_LIMIT = 45_000
DERIVATIVE_ORDER_CREATION_GAS_LIMIT = 70_000
SPOT_ORDER_CANCELATION_GAS_LIMIT = 50_000
DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT = 60_000
# POST ONLY orders take around 50% more gas to create than normal orders, due to the validations
POST_ONLY_ORDER_MULTIPLIER = 0.5


class GasLimitEstimator(ABC):
GENERAL_MESSAGE_GAS_LIMIT = 10_000
GENERAL_MESSAGE_GAS_LIMIT = 15_000
BASIC_REFERENCE_GAS_LIMIT = 150_000

@classmethod
Expand Down Expand Up @@ -57,6 +69,16 @@ def _parsed_message(self, message: any_pb2.Any) -> any_pb2.Any:
parsed_message = message
return parsed_message

def _select_post_only_orders(
self,
orders: List[Union[injective_exchange_pb.SpotOrder, injective_exchange_pb.DerivativeOrder]],
) -> List[Union[injective_exchange_pb.SpotOrder, injective_exchange_pb.DerivativeOrder]]:
return [
order
for order in orders
if order.order_type in [injective_exchange_pb.OrderType.BUY_PO, injective_exchange_pb.OrderType.SELL_PO]
]


class DefaultGasLimitEstimator(GasLimitEstimator):
DEFAULT_GAS_LIMIT = 150_000
Expand All @@ -74,8 +96,6 @@ def _message_class(self, message: any_pb2.Any):


class BatchCreateSpotLimitOrdersGasLimitEstimator(GasLimitEstimator):
ORDER_GAS_LIMIT = 50_000

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

Expand All @@ -84,9 +104,12 @@ def applies_to(cls, message: any_pb2.Any):
return cls.message_type(message=message).endswith("MsgBatchCreateSpotLimitOrders")

def gas_limit(self) -> int:
post_only_orders = self._select_post_only_orders(orders=self._message.orders)

total = 0
total += self.GENERAL_MESSAGE_GAS_LIMIT
total += len(self._message.orders) * self.ORDER_GAS_LIMIT
total += len(self._message.orders) * SPOT_ORDER_CREATION_GAS_LIMIT
total += math.ceil(len(post_only_orders) * SPOT_ORDER_CREATION_GAS_LIMIT * POST_ONLY_ORDER_MULTIPLIER)

return total

Expand All @@ -95,8 +118,6 @@ def _message_class(self, message: any_pb2.Any):


class BatchCancelSpotOrdersGasLimitEstimator(GasLimitEstimator):
ORDER_GAS_LIMIT = 50_000

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

Expand All @@ -107,7 +128,7 @@ def applies_to(cls, message: any_pb2.Any):
def gas_limit(self) -> int:
total = 0
total += self.GENERAL_MESSAGE_GAS_LIMIT
total += len(self._message.data) * self.ORDER_GAS_LIMIT
total += len(self._message.data) * SPOT_ORDER_CANCELATION_GAS_LIMIT

return total

Expand All @@ -116,8 +137,6 @@ def _message_class(self, message: any_pb2.Any):


class BatchCreateDerivativeLimitOrdersGasLimitEstimator(GasLimitEstimator):
ORDER_GAS_LIMIT = 66_000

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

Expand All @@ -126,9 +145,12 @@ def applies_to(cls, message: any_pb2.Any):
return cls.message_type(message=message).endswith("MsgBatchCreateDerivativeLimitOrders")

def gas_limit(self) -> int:
post_only_orders = self._select_post_only_orders(orders=self._message.orders)

total = 0
total += self.GENERAL_MESSAGE_GAS_LIMIT
total += len(self._message.orders) * self.ORDER_GAS_LIMIT
total += len(self._message.orders) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT
total += math.ceil(len(post_only_orders) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT * POST_ONLY_ORDER_MULTIPLIER)

return total

Expand All @@ -137,8 +159,6 @@ def _message_class(self, message: any_pb2.Any):


class BatchCancelDerivativeOrdersGasLimitEstimator(GasLimitEstimator):
ORDER_GAS_LIMIT = 60_000

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

Expand All @@ -149,7 +169,7 @@ def applies_to(cls, message: any_pb2.Any):
def gas_limit(self) -> int:
total = 0
total += self.GENERAL_MESSAGE_GAS_LIMIT
total += len(self._message.data) * self.ORDER_GAS_LIMIT
total += len(self._message.data) * DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT

return total

Expand All @@ -158,10 +178,6 @@ def _message_class(self, message: any_pb2.Any):


class BatchUpdateOrdersGasLimitEstimator(GasLimitEstimator):
SPOT_ORDER_CREATION_GAS_LIMIT = 45_000
DERIVATIVE_ORDER_CREATION_GAS_LIMIT = 66_000
SPOT_ORDER_CANCELATION_GAS_LIMIT = 50_000
DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT = 60_000
CANCEL_ALL_SPOT_MARKET_GAS_LIMIT = 40_000
CANCEL_ALL_DERIVATIVE_MARKET_GAS_LIMIT = 50_000
MESSAGE_GAS_LIMIT = 15_000
Expand All @@ -176,14 +192,29 @@ def applies_to(cls, message: any_pb2.Any):
return cls.message_type(message=message).endswith("MsgBatchUpdateOrders")

def gas_limit(self) -> int:
post_only_spot_orders = self._select_post_only_orders(orders=self._message.spot_orders_to_create)
post_only_derivative_orders = self._select_post_only_orders(orders=self._message.derivative_orders_to_create)
post_only_binary_options_orders = self._select_post_only_orders(
orders=self._message.binary_options_orders_to_create
)

total = 0
total += self.MESSAGE_GAS_LIMIT
total += len(self._message.spot_orders_to_create) * self.SPOT_ORDER_CREATION_GAS_LIMIT
total += len(self._message.derivative_orders_to_create) * self.DERIVATIVE_ORDER_CREATION_GAS_LIMIT
total += len(self._message.binary_options_orders_to_create) * self.DERIVATIVE_ORDER_CREATION_GAS_LIMIT
total += len(self._message.spot_orders_to_cancel) * self.SPOT_ORDER_CANCELATION_GAS_LIMIT
total += len(self._message.derivative_orders_to_cancel) * self.DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT
total += len(self._message.binary_options_orders_to_cancel) * self.DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT
total += len(self._message.spot_orders_to_create) * SPOT_ORDER_CREATION_GAS_LIMIT
total += len(self._message.derivative_orders_to_create) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT
total += len(self._message.binary_options_orders_to_create) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT

total += math.ceil(len(post_only_spot_orders) * SPOT_ORDER_CREATION_GAS_LIMIT * POST_ONLY_ORDER_MULTIPLIER)
total += math.ceil(
len(post_only_derivative_orders) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT * POST_ONLY_ORDER_MULTIPLIER
)
total += math.ceil(
len(post_only_binary_options_orders) * DERIVATIVE_ORDER_CREATION_GAS_LIMIT * POST_ONLY_ORDER_MULTIPLIER
)

total += len(self._message.spot_orders_to_cancel) * SPOT_ORDER_CANCELATION_GAS_LIMIT
total += len(self._message.derivative_orders_to_cancel) * DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT
total += len(self._message.binary_options_orders_to_cancel) * DERIVATIVE_ORDER_CANCELATION_GAS_LIMIT

total += (
len(self._message.spot_market_ids_to_cancel_all)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "injective-py"
version = "1.2.0-rc1"
version = "1.2.0-rc2"
description = "Injective Python SDK, with Exchange API Client"
authors = ["Injective Labs <[email protected]>"]
license = "Apache-2.0"
Expand Down
16 changes: 8 additions & 8 deletions tests/core/test_gas_limit_estimator.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ def test_estimation_for_batch_create_spot_limit_orders(self):
message = composer.MsgBatchCreateSpotLimitOrders(sender="sender", orders=orders)
estimator = GasLimitEstimator.for_message(message=message)

expected_order_gas_limit = 50000
expected_message_gas_limit = 10000
expected_order_gas_limit = 45000
expected_message_gas_limit = 15000

assert (expected_order_gas_limit * 2) + expected_message_gas_limit == estimator.gas_limit()

Expand Down Expand Up @@ -75,7 +75,7 @@ def test_estimation_for_batch_cancel_spot_orders(self):
estimator = GasLimitEstimator.for_message(message=message)

expected_order_gas_limit = 50000
expected_message_gas_limit = 10000
expected_message_gas_limit = 15000

assert (expected_order_gas_limit * 3) + expected_message_gas_limit == estimator.gas_limit()

Expand Down Expand Up @@ -107,8 +107,8 @@ def test_estimation_for_batch_create_derivative_limit_orders(self):
message = composer.MsgBatchCreateDerivativeLimitOrders(sender="sender", orders=orders)
estimator = GasLimitEstimator.for_message(message=message)

expected_order_gas_limit = 66_000
expected_message_gas_limit = 10000
expected_order_gas_limit = 70_000
expected_message_gas_limit = 15000

assert (expected_order_gas_limit * 2) + expected_message_gas_limit == estimator.gas_limit()

Expand Down Expand Up @@ -136,7 +136,7 @@ def test_estimation_for_batch_cancel_derivative_orders(self):
estimator = GasLimitEstimator.for_message(message=message)

expected_order_gas_limit = 60_000
expected_message_gas_limit = 10000
expected_message_gas_limit = 15000

assert (expected_order_gas_limit * 3) + expected_message_gas_limit == estimator.gas_limit()

Expand Down Expand Up @@ -211,7 +211,7 @@ def test_estimation_for_batch_update_orders_to_create_derivative_orders(self):
)
estimator = GasLimitEstimator.for_message(message=message)

expected_order_gas_limit = 66_000
expected_order_gas_limit = 70_000
expected_message_gas_limit = 15_000

assert (expected_order_gas_limit * 2) + expected_message_gas_limit == estimator.gas_limit()
Expand Down Expand Up @@ -269,7 +269,7 @@ def test_estimation_for_batch_update_orders_to_create_binary_orders(self, usdt_t
)
estimator = GasLimitEstimator.for_message(message=message)

expected_order_gas_limit = 66_000
expected_order_gas_limit = 70_000
expected_message_gas_limit = 15_000

assert (expected_order_gas_limit * 2) + expected_message_gas_limit == estimator.gas_limit()
Expand Down

0 comments on commit 6eefa4c

Please sign in to comment.