Skip to content

Commit

Permalink
Merge pull request #313 from InjectiveLabs/feat/tendermint_module_que…
Browse files Browse the repository at this point in the history
…ries

Feat/tendermint module queries
  • Loading branch information
aarmoa authored Mar 14, 2024
2 parents 54e4622 + cdd4bb9 commit 8adf955
Show file tree
Hide file tree
Showing 22 changed files with 995 additions and 45 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

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

## [1.5.0] - 9999-99-99
### Added
- Added support for all queries in the chain 'tendermint' module

## [1.4.1] - 2024-03-12
### Changed
- Updates example scripts that were still using deprecated methods

## [1.4.0] - 2024-03-11
### Added
- Added support for all queries and messages in the chain 'distribution' module
Expand Down
2 changes: 1 addition & 1 deletion examples/chain_client/3_MessageBroadcaster.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async def main() -> None:
]

# prepare tx msg
msg = composer.MsgBatchUpdateOrders(
msg = composer.msg_batch_update_orders(
sender=address.to_acc_bech32(),
spot_orders_to_create=spot_orders_to_create,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ async def main() -> None:
]

# prepare tx msg
msg = composer.MsgBatchUpdateOrders(
msg = composer.msg_batch_update_orders(
sender=address.to_acc_bech32(),
spot_orders_to_create=spot_orders_to_create,
)
Expand Down
2 changes: 1 addition & 1 deletion examples/chain_client/exchange/8_MsgCancelSpotOrder.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async def main() -> None:
order_hash = "0x52888d397d5ae821869c8acde5823dfd8018802d2ef642d3aa639e5308173fcf"

# prepare tx msg
msg = composer.MsgCancelSpotOrder(
msg = composer.msg_cancel_spot_order(
sender=address.to_acc_bech32(), market_id=market_id, subaccount_id=subaccount_id, order_hash=order_hash
)

Expand Down
2 changes: 1 addition & 1 deletion examples/chain_client/exchange/9_MsgBatchUpdateOrders.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ async def main() -> None:
]

# prepare tx msg
msg = composer.MsgBatchUpdateOrders(
msg = composer.msg_batch_update_orders(
sender=address.to_acc_bech32(),
derivative_orders_to_create=derivative_orders_to_create,
spot_orders_to_create=spot_orders_to_create,
Expand Down
16 changes: 16 additions & 0 deletions examples/chain_client/tendermint/query/1_GetNodeInfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import asyncio

from pyinjective.async_client import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

node_info = await client.fetch_node_info()
print(node_info)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
16 changes: 16 additions & 0 deletions examples/chain_client/tendermint/query/2_GetSyncing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import asyncio

from pyinjective.async_client import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

syncing = await client.fetch_syncing()
print(syncing)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
16 changes: 16 additions & 0 deletions examples/chain_client/tendermint/query/3_GetLatestBlock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import asyncio

from pyinjective.async_client import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

latest_block = await client.fetch_latest_block()
print(latest_block)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
16 changes: 16 additions & 0 deletions examples/chain_client/tendermint/query/4_GetBlockByHeight.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import asyncio

from pyinjective.async_client import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

block = await client.fetch_block_by_height(height=15793860)
print(block)


if __name__ == "__main__":
asyncio.get_event_loop().run_until_complete(main())
19 changes: 19 additions & 0 deletions examples/chain_client/tendermint/query/5_GetLatestValidatorSet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client import AsyncClient
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

validator_set = await client.fetch_latest_validator_set()
print(validator_set)


if __name__ == "__main__":
symbol_db = symbol_database.Default()
asyncio.get_event_loop().run_until_complete(main())
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import asyncio

from google.protobuf import symbol_database

from pyinjective.async_client import AsyncClient
from pyinjective.client.model.pagination import PaginationOption
from pyinjective.core.network import Network


async def main() -> None:
network = Network.testnet()
client = AsyncClient(network)

pagination = PaginationOption(skip=2, limit=4)

validator_set = await client.fetch_validator_set_by_height(height=23040174, pagination=pagination)
print(validator_set)


if __name__ == "__main__":
symbol_db = symbol_database.Default()
asyncio.get_event_loop().run_until_complete(main())
57 changes: 50 additions & 7 deletions pyinjective/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
from pyinjective.core.market import BinaryOptionMarket, DerivativeMarket, SpotMarket
from pyinjective.core.network import Network
from pyinjective.core.token import Token
from pyinjective.core.tx.grpc.tendermint_grpc_api import TendermintGrpcApi
from pyinjective.core.tx.grpc.tx_grpc_api import TxGrpcApi
from pyinjective.exceptions import NotFoundError
from pyinjective.proto.cosmos.auth.v1beta1 import query_pb2 as auth_query, query_pb2_grpc as auth_query_grpc
Expand All @@ -49,6 +50,7 @@
query_pb2 as tendermint_query,
query_pb2_grpc as tendermint_query_grpc,
)
from pyinjective.proto.cosmos.crypto.ed25519 import keys_pb2 as ed25519_keys # noqa: F401 for validator set responses
from pyinjective.proto.cosmos.tx.v1beta1 import service_pb2 as tx_service, service_pb2_grpc as tx_service_grpc
from pyinjective.proto.exchange import (
injective_accounts_rpc_pb2 as exchange_accounts_rpc_pb,
Expand Down Expand Up @@ -192,6 +194,12 @@ def __init__(
metadata_query_provider=self._chain_cookie_metadata_requestor
),
)
self.tendermint_api = TendermintGrpcApi(
channel=self.chain_channel,
metadata_provider=lambda: self.network.chain_metadata(
metadata_query_provider=self._chain_cookie_metadata_requestor
),
)
self.token_factory_api = ChainGrpcTokenFactoryApi(
channel=self.chain_channel,
metadata_provider=lambda: self.network.chain_metadata(
Expand Down Expand Up @@ -379,18 +387,15 @@ async def close_chain_channel(self):

async def sync_timeout_height(self):
try:
block = await self.get_latest_block()
self.timeout_height = block.block.header.height + DEFAULT_TIMEOUTHEIGHT
block = await self.fetch_latest_block()
self.timeout_height = int(block["block"]["header"]["height"]) + DEFAULT_TIMEOUTHEIGHT
except Exception as e:
LoggerProvider().logger_for_class(logging_class=self.__class__).debug(
f"error while fetching latest block, setting timeout height to 0: {e}"
)
self.timeout_height = 0

# default client methods
async def get_latest_block(self) -> tendermint_query.GetLatestBlockResponse:
req = tendermint_query.GetLatestBlockRequest()
return await self.stubCosmosTendermint.GetLatestBlock(req)

async def get_account(self, address: str) -> Optional[account_pb2.EthAccount]:
"""
Expand Down Expand Up @@ -500,8 +505,8 @@ async def send_tx_block_mode(self, tx_byte: bytes) -> abci_type.TxResponse:
return result.tx_response

async def get_chain_id(self) -> str:
latest_block = await self.get_latest_block()
return latest_block.block.header.chain_id
latest_block = await self.fetch_latest_block()
return latest_block["block"]["header"]["chainId"]

async def get_grants(self, granter: str, grantee: str, **kwargs):
"""
Expand Down Expand Up @@ -1225,6 +1230,44 @@ async def fetch_denoms_from_creator(
async def fetch_tokenfactory_module_state(self) -> Dict[str, Any]:
return await self.token_factory_api.fetch_tokenfactory_module_state()

# ------------------------------
# region Tendermint module
async def fetch_node_info(self) -> Dict[str, Any]:
return await self.tendermint_api.fetch_node_info()

async def fetch_syncing(self) -> Dict[str, Any]:
return await self.tendermint_api.fetch_syncing()

async def get_latest_block(self) -> tendermint_query.GetLatestBlockResponse:
"""
This method is deprecated and will be removed soon. Please use `fetch_latest_block` instead
"""
warn("This method is deprecated. Use fetch_latest_block instead", DeprecationWarning, stacklevel=2)
req = tendermint_query.GetLatestBlockRequest()
return await self.stubCosmosTendermint.GetLatestBlock(req)

async def fetch_latest_block(self) -> Dict[str, Any]:
return await self.tendermint_api.fetch_latest_block()

async def fetch_block_by_height(self, height: int) -> Dict[str, Any]:
return await self.tendermint_api.fetch_block_by_height(height=height)

async def fetch_latest_validator_set(self) -> Dict[str, Any]:
return await self.tendermint_api.fetch_latest_validator_set()

async def fetch_validator_set_by_height(
self, height: int, pagination: Optional[PaginationOption] = None
) -> Dict[str, Any]:
return await self.tendermint_api.fetch_validator_set_by_height(height=height, pagination=pagination)

async def abci_query(
self, path: str, data: Optional[bytes] = None, height: Optional[int] = None, prove: bool = False
) -> Dict[str, Any]:
return await self.tendermint_api.abci_query(path=path, data=data, height=height, prove=prove)

# endregion

# ------------------------------
# Explorer RPC

async def get_tx_by_hash(self, tx_hash: str):
Expand Down
69 changes: 69 additions & 0 deletions pyinjective/core/tx/grpc/tendermint_grpc_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from typing import Any, Callable, Dict, Optional

from grpc.aio import Channel

from pyinjective.client.model.pagination import PaginationOption
from pyinjective.proto.cosmos.base.tendermint.v1beta1 import (
query_pb2 as tendermint_query,
query_pb2_grpc as tendermint_query_grpc,
)
from pyinjective.utils.grpc_api_request_assistant import GrpcApiRequestAssistant


class TendermintGrpcApi:
def __init__(self, channel: Channel, metadata_provider: Callable):
self._stub = tendermint_query_grpc.ServiceStub(channel)
self._assistant = GrpcApiRequestAssistant(metadata_provider=metadata_provider)

async def fetch_node_info(self) -> Dict[str, Any]:
request = tendermint_query.GetNodeInfoRequest()
response = await self._execute_call(call=self._stub.GetNodeInfo, request=request)

return response

async def fetch_syncing(self) -> Dict[str, Any]:
request = tendermint_query.GetSyncingRequest()
response = await self._execute_call(call=self._stub.GetSyncing, request=request)

return response

async def fetch_latest_block(self) -> Dict[str, Any]:
request = tendermint_query.GetLatestBlockRequest()
response = await self._execute_call(call=self._stub.GetLatestBlock, request=request)

return response

async def fetch_block_by_height(self, height: int) -> Dict[str, Any]:
request = tendermint_query.GetBlockByHeightRequest(height=height)
response = await self._execute_call(call=self._stub.GetBlockByHeight, request=request)

return response

async def fetch_latest_validator_set(self) -> Dict[str, Any]:
request = tendermint_query.GetLatestValidatorSetRequest()
response = await self._execute_call(call=self._stub.GetLatestValidatorSet, request=request)

return response

async def fetch_validator_set_by_height(
self, height: int, pagination: Optional[PaginationOption] = None
) -> Dict[str, Any]:
if pagination is None:
pagination = PaginationOption()
request = tendermint_query.GetValidatorSetByHeightRequest(
height=height, pagination=pagination.create_pagination_request()
)
response = await self._execute_call(call=self._stub.GetValidatorSetByHeight, request=request)

return response

async def abci_query(
self, path: str, data: Optional[bytes] = None, height: Optional[int] = None, prove: bool = False
) -> Dict[str, Any]:
request = tendermint_query.ABCIQueryRequest(path=path, data=data, height=height, prove=prove)
response = await self._execute_call(call=self._stub.ABCIQuery, request=request)

return response

async def _execute_call(self, call: Callable, request) -> Dict[str, Any]:
return await self._assistant.execute_call(call=call, request=request)
34 changes: 30 additions & 4 deletions pyinjective/denoms_devnet.ini
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ min_display_quantity_tick_size = 0.00001
description = 'Devnet Spot PROJ/INJ'
base = 18
quote = 18
min_price_tick_size = 0.001
min_display_price_tick_size = 0.001
min_quantity_tick_size = 10000000000000
min_display_quantity_tick_size = 0.00001
min_price_tick_size = 0.00000001
min_display_price_tick_size = 0.00000001
min_quantity_tick_size = 1000000000000000000000
min_display_quantity_tick_size = 1000

[0x2d3b8d8833dda54a717adea9119134556848105fd6028e9a4a526e4e5a122a57]
description = 'Devnet Spot KIRA/INJ'
Expand All @@ -178,6 +178,24 @@ min_display_price_tick_size = 0.00000001
min_quantity_tick_size = 1000000000
min_display_quantity_tick_size = 1000

[0x42edf70cc37e155e9b9f178e04e18999bc8c404bd7b638cc4cbf41da8ef45a21]
description = 'Devnet Spot QUNT/INJ'
base = 6
quote = 18
min_price_tick_size = 10000
min_display_price_tick_size = 0.00000001
min_quantity_tick_size = 1000000000
min_display_quantity_tick_size = 1000

[0xc8fafa1fcab27e16da20e98b4dc9dda45320418c27db80663b21edac72f3b597]
description = 'Devnet Spot HDRO/INJ'
base = 6
quote = 18
min_price_tick_size = 1000000
min_display_price_tick_size = 0.000001
min_quantity_tick_size = 1000000
min_display_quantity_tick_size = 1

[0x1422a13427d5eabd4d8de7907c8340f7e58cb15553a9fd4ad5c90406561886f9]
description = 'Devnet Derivative COMP/USDT PERP'
base = 0
Expand Down Expand Up @@ -296,6 +314,10 @@ decimals = 18
peggy_denom = peggy0xAaEf88cEa01475125522e117BFe45cF32044E238
decimals = 18

[HDRO]
peggy_denom = factory/inj1etz0laas6h7vemg3qtd67jpr6lh8v7xz7gfzqw/hdro
decimals = 6

[INJ]
peggy_denom = inj
decimals = 18
Expand All @@ -316,6 +338,10 @@ decimals = 18
peggy_denom = proj
decimals = 18

[QUNT]
peggy_denom = factory/inj127l5a2wmkyvucxdlupqyac3y0v6wqfhq03ka64/qunt
decimals = 6

[SOMM]
peggy_denom = ibc/34346A60A95EB030D62D6F5BDD4B745BE18E8A693372A8A347D5D53DBBB1328B
decimals = 6
Expand Down
Loading

0 comments on commit 8adf955

Please sign in to comment.