Skip to content

feat/add_ibc_transfer_support#317

Merged
aarmoa merged 2 commits intodevfrom
feat/add_ibc_transfer_support
Apr 11, 2024
Merged

feat/add_ibc_transfer_support#317
aarmoa merged 2 commits intodevfrom
feat/add_ibc_transfer_support

Conversation

@aarmoa
Copy link
Copy Markdown
Collaborator

@aarmoa aarmoa commented Apr 10, 2024

  • Added support for IBC Transfer module queries
  • Added support in Composer to create the IBC transfer message
  • Added unit tests
  • Added example scripts

Solves CHAIN-74

Summary by CodeRabbit

  • New Features

    • Added support for IBC Transfer module queries, enhancing interaction with the Injective Protocol.
    • Introduced Python scripts for token transfers, querying denomination traces, hashes, escrow addresses, and total escrow amounts.
    • Enhanced async client capabilities with methods for IBC-related operations.
  • Refactor

    • Improved cookies management logic for all gRPC calls.
  • Tests

    • Added test cases for new IBC Transfer module functionalities and message creation.

@aarmoa aarmoa requested a review from nicolasbaum April 10, 2024 18:43
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 10, 2024

Walkthrough

This update significantly enhances the capabilities of the platform by integrating comprehensive support for IBC Transfer module queries, alongside the existing support for the 'tendermint' module. It streamlines the cookies management logic for gRPC calls and introduces a suite of functionalities for handling token transfers, querying denomination traces, hashes, and escrow information within the Injective Protocol environment.

Changes

File Path Change Summary
CHANGELOG.md Added support for IBC Transfer module queries; refactored cookies management.
examples/chain_client/ibc/transfer/1_MsgTransfer.py
examples/chain_client/ibc/transfer/query/...
Introduced scripts for token transfers and querying denomination traces, hashes, escrow addresses, and total escrow amounts in Injective Protocol.
pyinjective/async_client.py
pyinjective/composer.py
pyinjective/core/tx/grpc/ibc_transfer_grpc_api.py
Enhanced async client with IBC Transfer module functionalities; added methods for interacting with the IBCTransferGrpcApi.
tests/core/tx/grpc/...
tests/test_composer.py
Added tests for IBC Transfer module functionalities, including denom traces, hashes, escrow addresses, and message creation.

🐰✨
In the digital fields where data streams flow,
A rabbit hopped in, its eyes aglow.
With a flick and a hop, new paths it weaved,
Through IBC transfers, much was achieved.
"To the moon!" it cheered, with no delay,
As it bounded off, leading the way.
🚀🌕


Recent Review Details

Configuration used: .coderabbit.yaml

Commits Files that changed from the base of the PR and between 1fae35f and 3d9761d.
Files selected for processing (13)
  • CHANGELOG.md (1 hunks)
  • examples/chain_client/ibc/transfer/1_MsgTransfer.py (1 hunks)
  • examples/chain_client/ibc/transfer/query/1_DenomTrace.py (1 hunks)
  • examples/chain_client/ibc/transfer/query/2_DenomTraces.py (1 hunks)
  • examples/chain_client/ibc/transfer/query/3_DenomHash.py (1 hunks)
  • examples/chain_client/ibc/transfer/query/4_EscrowAddress.py (1 hunks)
  • examples/chain_client/ibc/transfer/query/5_TotalEscrowForDenom.py (1 hunks)
  • pyinjective/async_client.py (3 hunks)
  • pyinjective/composer.py (3 hunks)
  • pyinjective/core/tx/grpc/ibc_transfer_grpc_api.py (1 hunks)
  • tests/core/tx/grpc/configurable_ibc_transfer_query_servicer.py (1 hunks)
  • tests/core/tx/grpc/test_ibc_transfer_grpc_api.py (1 hunks)
  • tests/test_composer.py (1 hunks)
Additional comments not posted (17)
examples/chain_client/ibc/transfer/query/5_TotalEscrowForDenom.py (1)

3-3: Consider removing the unused symbol_database import to clean up the code.

examples/chain_client/ibc/transfer/query/4_EscrowAddress.py (1)

3-3: Consider removing the unused symbol_database import to clean up the code.

examples/chain_client/ibc/transfer/query/3_DenomHash.py (1)

3-3: Consider removing the unused symbol_database import to clean up the code.

examples/chain_client/ibc/transfer/query/2_DenomTraces.py (1)

3-3: Consider removing the unused symbol_database import to clean up the code.

examples/chain_client/ibc/transfer/query/1_DenomTrace.py (1)

3-3: Consider removing the unused symbol_database import to clean up the code.

tests/core/tx/grpc/configurable_ibc_transfer_query_servicer.py (1)

1-37: LGTM! The mock gRPC servicer implementation for IBC transfer queries is well-structured and serves its intended purpose effectively.

examples/chain_client/ibc/transfer/1_MsgTransfer.py (1)

1-61: LGTM! The script for creating and broadcasting an IBC transfer message is well-structured and demonstrates the intended functionality effectively.

pyinjective/core/tx/grpc/ibc_transfer_grpc_api.py (1)

1-58: LGTM! The IBCTransferGrpcApi class implementation is well-structured and provides a clean interface for interacting with the IBC Transfer module via gRPC.

tests/core/tx/grpc/test_ibc_transfer_grpc_api.py (4)

15-17: Consider using a more descriptive name for the fixture.

A more descriptive name for the ibc_transfer_servicer fixture could improve readability. For example, mock_ibc_transfer_servicer would immediately convey that this is a mock object used for testing.


44-70: Validate input parameters in test_fetch_denom_trace.

It's important to ensure that the hash parameter passed to api.fetch_denom_trace is validated or sanitized before use, especially since it interacts with external systems or libraries. Consider adding a check or a note to verify that this is handled appropriately upstream.


72-116: Optimize pagination handling in test_fetch_denom_traces.

The pagination handling in test_fetch_denom_traces could be optimized by abstracting the pagination logic into a utility function or class. This would improve code reuse and maintainability, especially if pagination is a common pattern in your tests or application logic.


138-156: Review error handling in test_fetch_escrow_address.

Ensure that the test_fetch_escrow_address method properly handles errors or exceptions that may arise from the api.fetch_escrow_address call. This is crucial for resilience and reliability, especially in network-related operations.

CHANGELOG.md (2)

Line range hint 63-63: Clarify the addition of logic for Client Order ID.

The entry for version 1.0 mentions "Added logic to support use of Client Order ID (CID) new identifier in OrderInfo". It would be helpful to briefly explain why this addition is significant or how it improves the project, enhancing the changelog's informativeness.


Line range hint 71-71: Clarify the removal of aiocron dependency.

The entry for version 1.0 mentions the removal of the aiocron dependency. Expanding on the reason for this removal and its impact on the project could provide valuable context to the readers of the changelog.

tests/test_composer.py (1)

1434-1472: The new test method test_msg_ibc_transfer is correctly implemented and thoroughly tests the IBC transfer message creation.

pyinjective/composer.py (1)

2148-2175: Consider adding a docstring to msg_ibc_transfer.

The msg_ibc_transfer method lacks a docstring, which is crucial for understanding the purpose, parameters, and expected behavior of the method, especially for such a critical functionality as IBC transfers. Adding a comprehensive docstring would improve code maintainability and readability.

pyinjective/async_client.py (1)

3021-3036: Consider adding error handling for IBC Transfer module methods.

The newly added methods for interacting with the IBC Transfer module (fetch_denom_trace, fetch_denom_traces, fetch_denom_hash, fetch_escrow_address, fetch_total_escrow_for_denom) currently do not include explicit error handling. It's advisable to implement error handling to manage potential exceptions or errors that may arise during the execution of these methods, ensuring the robustness and reliability of the application.


Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Actionable comments outside the diff hunks (8)
CHANGELOG.md (2)

Line range hint 52-52: Use hyphenated compound adjectives for clarity.

In the changelog entry for version 1.0.1, the phrase "low level API components" could be clearer if hyphenated to indicate that "low-level" is a compound adjective modifying "API components".

- - Added low level API components for all modules
+ - Added low-level API components for all modules

Line range hint 68-68: Address potential missing preposition in the changelog entry.

The entry for version 1.0 about removing support for sentry nodes might be missing a preposition that clarifies the context. Consider rephrasing for better readability.

- - Remove support for `sentry` nodes in mainnet network.
+ - Removed support for `sentry` nodes from the mainnet network.
tests/test_composer.py (6)

Line range hint 24-24: Remove duplicate import of inj_usdt_spot_market to improve code clarity.


Line range hint 24-24: Remove duplicate import of btc_usdt_perp_market to improve code clarity.


Line range hint 24-24: Remove duplicate import of first_match_bet_market to improve code clarity.


Line range hint 42-42: Remove duplicate import of inj_token to improve code clarity.


Line range hint 1191-1191: Ensure that the redefinition of test_msg_cancel_derivative_order is intentional. If both versions are needed, consider renaming one to avoid overshadowing.


Line range hint 1355-1355: Ensure that the redefinition of test_msg_external_transfer is intentional. Consider renaming one of the methods to ensure both are executed and serve their intended purpose.

Comment thread pyinjective/composer.py
Comment on lines +25 to +26
from pyinjective.proto.ibc.applications.transfer.v1 import tx_pb2 as ibc_transfer_tx_pb
from pyinjective.proto.ibc.core.client.v1 import client_pb2 as ibc_core_client_pb
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider grouping imports from the same module.

- from pyinjective.proto.ibc.applications.transfer.v1 import tx_pb2 as ibc_transfer_tx_pb
- from pyinjective.proto.ibc.core.client.v1 import client_pb2 as ibc_core_client_pb
+ from pyinjective.proto.ibc.applications.transfer.v1 import tx_pb2 as ibc_transfer_tx_pb
+ from pyinjective.proto.ibc.core.client.v1 import client_pb2 as ibc_core_client_pb

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
from pyinjective.proto.ibc.applications.transfer.v1 import tx_pb2 as ibc_transfer_tx_pb
from pyinjective.proto.ibc.core.client.v1 import client_pb2 as ibc_core_client_pb
from pyinjective.proto.ibc.applications.transfer.v1 import tx_pb2 as ibc_transfer_tx_pb
from pyinjective.proto.ibc.core.client.v1 import client_pb2 as ibc_core_client_pb

Comment thread pyinjective/composer.py
return base_coin_pb.Coin(amount=str(amount), denom=denom)

def coin(self, amount: int, denom: str):
def coin(self, amount: int, denom: str) -> base_coin_pb.Coin:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure return type annotation consistency.

The coin method lacks a return type annotation, which is present in other newly added methods like create_coin_amount. For consistency and clarity, consider adding a return type annotation.

- def coin(self, amount: int, denom: str):
+ def coin(self, amount: int, denom: str) -> base_coin_pb.Coin:

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def coin(self, amount: int, denom: str) -> base_coin_pb.Coin:
def coin(self, amount: int, denom: str) -> base_coin_pb.Coin:

Comment thread pyinjective/composer.py
Comment on lines +2148 to +2175
def msg_ibc_transfer(
self,
source_port: str,
source_channel: str,
token_amount: base_coin_pb.Coin,
sender: str,
receiver: str,
timeout_height: Optional[int] = None,
timeout_timestamp: Optional[int] = None,
memo: Optional[str] = None,
) -> ibc_transfer_tx_pb.MsgTransfer:
if timeout_height is None and timeout_timestamp is None:
raise ValueError("IBC Transfer error: Either timeout_height or timeout_timestamp must be provided")
parsed_timeout_height = None
if timeout_height:
parsed_timeout_height = ibc_core_client_pb.Height(
revision_number=timeout_height, revision_height=timeout_height
)
return ibc_transfer_tx_pb.MsgTransfer(
source_port=source_port,
source_channel=source_channel,
token=token_amount,
sender=sender,
receiver=receiver,
timeout_height=parsed_timeout_height,
timeout_timestamp=timeout_timestamp,
memo=memo,
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validate timeout_height and timeout_timestamp parameters in msg_ibc_transfer.

The method msg_ibc_transfer checks if both timeout_height and timeout_timestamp are None but does not validate the scenario where both are provided, which might not be intended or supported by the underlying IBC protocol. Consider adding a validation to ensure only one of them is provided, or clearly document the expected behavior if both are provided.

+ if timeout_height is not None and timeout_timestamp is not None:
+     raise ValueError("IBC Transfer error: Only one of timeout_height or timeout_timestamp should be provided")

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
def msg_ibc_transfer(
self,
source_port: str,
source_channel: str,
token_amount: base_coin_pb.Coin,
sender: str,
receiver: str,
timeout_height: Optional[int] = None,
timeout_timestamp: Optional[int] = None,
memo: Optional[str] = None,
) -> ibc_transfer_tx_pb.MsgTransfer:
if timeout_height is None and timeout_timestamp is None:
raise ValueError("IBC Transfer error: Either timeout_height or timeout_timestamp must be provided")
parsed_timeout_height = None
if timeout_height:
parsed_timeout_height = ibc_core_client_pb.Height(
revision_number=timeout_height, revision_height=timeout_height
)
return ibc_transfer_tx_pb.MsgTransfer(
source_port=source_port,
source_channel=source_channel,
token=token_amount,
sender=sender,
receiver=receiver,
timeout_height=parsed_timeout_height,
timeout_timestamp=timeout_timestamp,
memo=memo,
)
def msg_ibc_transfer(
self,
source_port: str,
source_channel: str,
token_amount: base_coin_pb.Coin,
sender: str,
receiver: str,
timeout_height: Optional[int] = None,
timeout_timestamp: Optional[int] = None,
memo: Optional[str] = None,
) -> ibc_transfer_tx_pb.MsgTransfer:
if timeout_height is None and timeout_timestamp is None:
raise ValueError("IBC Transfer error: Either timeout_height or timeout_timestamp must be provided")
if timeout_height is not None and timeout_timestamp is not None:
raise ValueError("IBC Transfer error: Only one of timeout_height or timeout_timestamp should be provided")
parsed_timeout_height = None
if timeout_height:
parsed_timeout_height = ibc_core_client_pb.Height(
revision_number=timeout_height, revision_height=timeout_height
)
return ibc_transfer_tx_pb.MsgTransfer(
source_port=source_port,
source_channel=source_channel,
token=token_amount,
sender=sender,
receiver=receiver,
timeout_height=parsed_timeout_height,
timeout_timestamp=timeout_timestamp,
memo=memo,
)

Comment on lines +22 to +42
async def test_fetch_params(
self,
ibc_transfer_servicer,
):
params = ibc_transfer.Params(
send_enabled=True,
receive_enabled=False,
)

ibc_transfer_servicer.params_responses.append(
ibc_transfer_query.QueryParamsResponse(
params=params,
)
)

api = self._api_instance(servicer=ibc_transfer_servicer)

result_params = await api.fetch_params()
expected_params = {"params": {"sendEnabled": params.send_enabled, "receiveEnabled": params.receive_enabled}}

assert result_params == expected_params
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure consistent use of single quotes for strings.

Throughout the file, there's an inconsistent use of single and double quotes for strings. It's a good practice to stick to one style for consistency. The Python community often prefers single quotes unless the string contains a single quote character.

- expected_params = {"params": {"sendEnabled": params.send_enabled, "receiveEnabled": params.receive_enabled}}
+ expected_params = {'params': {'sendEnabled': params.send_enabled, 'receiveEnabled': params.receive_enabled}}

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
async def test_fetch_params(
self,
ibc_transfer_servicer,
):
params = ibc_transfer.Params(
send_enabled=True,
receive_enabled=False,
)
ibc_transfer_servicer.params_responses.append(
ibc_transfer_query.QueryParamsResponse(
params=params,
)
)
api = self._api_instance(servicer=ibc_transfer_servicer)
result_params = await api.fetch_params()
expected_params = {"params": {"sendEnabled": params.send_enabled, "receiveEnabled": params.receive_enabled}}
assert result_params == expected_params
async def test_fetch_params(
self,
ibc_transfer_servicer,
):
params = ibc_transfer.Params(
send_enabled=True,
receive_enabled=False,
)
ibc_transfer_servicer.params_responses.append(
ibc_transfer_query.QueryParamsResponse(
params=params,
)
)
api = self._api_instance(servicer=ibc_transfer_servicer)
result_params = await api.fetch_params()
expected_params = {'params': {'sendEnabled': params.send_enabled, 'receiveEnabled': params.receive_enabled}}
assert result_params == expected_params

Comment on lines +118 to +136
@pytest.mark.asyncio
async def test_fetch_denom_hash(
self,
ibc_transfer_servicer,
):
denom_hash = "97498452BF27CC90656FD7D6EFDA287FA2BFFFF3E84691C84CB9E0451F6DF0A4"

ibc_transfer_servicer.denom_hash_responses.append(
ibc_transfer_query.QueryDenomHashResponse(
hash=denom_hash,
)
)

api = self._api_instance(servicer=ibc_transfer_servicer)

result_hash = await api.fetch_denom_hash(trace="transfer/channel-126/uluna")
expected_hash = {"hash": denom_hash}

assert result_hash == expected_hash
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding more test cases for test_fetch_denom_hash.

The current test case for test_fetch_denom_hash covers a basic scenario. It might be beneficial to add more test cases covering edge cases, such as invalid hash formats or empty strings, to ensure robust error handling and validation.
Would you like me to suggest some additional test cases?

Comment on lines +158 to +181
@pytest.mark.asyncio
async def test_fetch_total_escrow_for_denom(
self,
ibc_transfer_servicer,
):
coin = coin_pb.Coin(denom="inj", amount="988987297011197594664")

ibc_transfer_servicer.total_escrow_for_denom_responses.append(
ibc_transfer_query.QueryTotalEscrowForDenomResponse(
amount=coin,
)
)

api = self._api_instance(servicer=ibc_transfer_servicer)

result_escrow = await api.fetch_total_escrow_for_denom(denom="inj")
expected_escrow = {
"amount": {
"denom": coin.denom,
"amount": coin.amount,
}
}

assert result_escrow == expected_escrow
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enhance test coverage for edge cases in test_fetch_total_escrow_for_denom.

The test test_fetch_total_escrow_for_denom focuses on a successful scenario. Consider adding tests for edge cases, such as when the denom does not exist or the API returns an error. This would ensure the application gracefully handles such situations.
Would you like assistance in drafting these additional test scenarios?

Comment thread CHANGELOG.md
Comment on lines 5 to 11
## [1.5.0] - 9999-99-99
### Added
- Added support for all queries in the chain 'tendermint' module
- Added support for all queries in the IBC Transfer module

### Changed
- Refactored cookies management logic to use all gRPC calls' responses to update the current cookies
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 NOTE
This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-7]

Clarify the release date for version 1.5.0.

The release date for version 1.5.0 is marked as 9999-99-99, which seems to be a placeholder. Please update this with the actual release date to maintain an accurate and informative changelog.

Comment thread CHANGELOG.md
## [1.5.0] - 9999-99-99
### Added
- Added support for all queries in the chain 'tendermint' module
- Added support for all queries in the IBC Transfer module
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove duplicate word in the changelog entry.

There's a minor typographical issue with the repeated word "Added" in the entry for the IBC Transfer module support. Consider revising for clarity and conciseness.

- - Added support for all queries in the IBC Transfer module
+ - Support for all queries in the IBC Transfer module

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
- Added support for all queries in the IBC Transfer module
- Support for all queries in the IBC Transfer module

@aarmoa aarmoa merged commit 3165d58 into dev Apr 11, 2024
@aarmoa aarmoa deleted the feat/add_ibc_transfer_support branch April 11, 2024 13:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants