From 6eefa4cd559113c9400da0be0fafafcacd098a94 Mon Sep 17 00:00:00 2001 From: abel Date: Wed, 24 Jan 2024 00:33:58 -0300 Subject: [PATCH] (fix) Added extra logic to increase the gas cost for post only order --- CHANGELOG.md | 1 + pyinjective/core/gas_limit_estimator.py | 79 +++++++++++++++++-------- pyproject.toml | 2 +- tests/core/test_gas_limit_estimator.py | 16 ++--- 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20ae791c..0069fe6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/pyinjective/core/gas_limit_estimator.py b/pyinjective/core/gas_limit_estimator.py index 6eadeb67..7de11d63 100644 --- a/pyinjective/core/gas_limit_estimator.py +++ b/pyinjective/core/gas_limit_estimator.py @@ -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 @@ -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 @@ -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) @@ -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 @@ -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) @@ -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 @@ -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) @@ -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 @@ -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) @@ -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 @@ -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 @@ -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) diff --git a/pyproject.toml b/pyproject.toml index a024299a..7c315858 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -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 "] license = "Apache-2.0" diff --git a/tests/core/test_gas_limit_estimator.py b/tests/core/test_gas_limit_estimator.py index 345f8c6a..b1cd4bb6 100644 --- a/tests/core/test_gas_limit_estimator.py +++ b/tests/core/test_gas_limit_estimator.py @@ -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() @@ -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() @@ -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() @@ -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() @@ -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() @@ -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()