Skip to content

Cp 235/update gas estimator for fixed exchange gas #375

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Apr 8, 2025

Conversation

aarmoa
Copy link
Collaborator

@aarmoa aarmoa commented Mar 17, 2025

  • Update of all compiled protos for Indexer and Core
  • Updated the logic in the gas estimator to reflect the changes introduced on chain for the gas heuristics

Solves CP-235

Summary by CodeRabbit

  • New Features

    • Introduced dynamic gas price handling across the client, enabling real-time fee adjustments and improving transaction resilience.
    • Added new asynchronous endpoints to query transaction fee parameters and base fee information.
    • Enhanced TradingStrategy message with a new field for final data.
  • Refactor

    • Replaced static gas price constants with dynamic, on-demand retrieval and adjustment logic.
    • Streamlined asynchronous operations for composing and broadcasting transactions.
  • Tests

    • Enhanced test suites to validate new USD value fields and gas estimation logic.
    • Added tests for the new ChainGrpcTxfeesApi class, covering module parameters and EIP base fee retrieval.
    • Comprehensive tests for GasHeuristicsGasLimitEstimator to ensure accurate gas limit estimations.
  • Chores

    • Bumped version from 1.9.0-rc3 to 1.10.0-rc1 with various dependency and configuration updates.

Copy link
Contributor

coderabbitai bot commented Mar 17, 2025

Walkthrough

The update includes a version bump and several configuration revisions in the changelog, Makefile, and dependency settings. Significant modifications replace static gas price constants with asynchronous calls that fetch and adjust current gas prices in various transaction-handling modules. Gas fee calculations have been enhanced by renaming constants and adding an update interface, while market value conversions now incorporate quantization for improved precision. In addition, many protobuf and gRPC definitions have been updated—adding fields like usd_value and new RPC services—and tests and example clients are revised accordingly to work with the new asynchronous and dynamic logic.

Changes

File(s) Change Summary
CHANGELOG.md, Makefile, buf.gen.yaml Version bump (e.g., 1.9.0 → 1.10.0), updated dates and dependency tags, and new configuration sections.
pyinjective/async_client.py, examples/exchange_client/oracle_rpc/1_StreamPrices.py, examples/exchange_client/portfolio_rpc/1_AccountPortfolio.py, pyinjective/client/indexer/grpc/indexer_grpc_portfolio_api.py Introduced dynamic gas price fetching via current_chain_gas_price(), added optional usd parameters, and updated string formatting (e.g., applying .lower() on oracle types).
pyinjective/core/broadcaster.py, pyinjective/core/market.py Enhanced gas fee logic by renaming TRANSACTION_GAS_LIMIT to TRANSACTION_ANTE_GAS_LIMIT, adding update_gas_price, and incorporating quantization (using ROUND_UP) in notional to chain conversion.
pyinjective/ofac.json Added a new entry to the sanctions list.
pyinjective/proto/... (various files) Updated protobuf definitions: added new fields (e.g., usd_value, total_balance_usd), adjusted serialized indices, and introduced new RPC service definitions (e.g., for referrals, txfees, genesis state).
tests/... (multiple test files) Revised tests to cover new parameters (e.g., fixed_gas_enabled, usd, total_usd), updated expected data structures, and adjusted assertions to match the dynamic gas price flow.
examples/chain_client/... (auction, authz, bank, distribution, exchange, insurance, oracle, peggy, permissions, staking, tokenfactory, etc.) Replaced static GAS_PRICE with asynchronous dynamic gas price retrieval and adjustment (multiplying by 1.1); improved output formatting (JSON pretty-print); updated broadcaster method parameters.
pyinjective/core/gas_heuristics_gas_limit_estimator.py New file establishing multiple gas limit estimator classes for various order types and transactions.
pyinjective/client/chain/grpc/chain_grpc_txfees_api.py, and related txfees/proto files Introduced new gRPC API for transaction fees, genesis state, and query services with associated message types and RPC methods.

Sequence Diagram(s)

sequenceDiagram
    participant C as Client
    participant AC as AsyncClient
    participant BC as Blockchain
    participant MB as MsgBroadcasterWithPk

    C->>AC: await current_chain_gas_price()
    AC->>BC: Fetch current gas price
    BC-->>AC: Return gas price
    AC-->>C: Return gas price
    C->>C: Adjust gas price (multiply *1.1)
    C->>MB: Call new_using_simulation(gas_price, client, composer)
    MB->>C: update_gas_price(gas_price)
Loading

Possibly related PRs

  • feat/update_gas_estimator_base_values #344: The changes in the main PR regarding updates to the gas limit estimator and the modifications in the retrieved PR that adjust gas limit constants are directly related, as both involve enhancements to the gas estimation logic within the same context of transaction processing.
  • fix/add_notional_quantization #374: The changes in the main PR regarding the updates to the CHANGELOG.md and the introduction of quantization in the functions for converting notional values to chain format are directly related to the modifications in the retrieved PR, which also focuses on adding quantization for notional values. Both PRs enhance the precision of value conversions in the codebase.
  • Feat/add exchange messages from v1.13 #341: The changes in the main PR, which include the addition of the min_notional parameter across various market classes and the introduction of new message types in the exchange module, are directly related to the changes in the retrieved PR, which also adds new message types and incorporates the min_notional field in the exchange context. Both PRs enhance the functionality of the exchange module by ensuring consistent handling of the min_notional parameter.

Suggested reviewers

  • PavelInjective

🪧 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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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.
    • @coderabbitai help me debug CodeRabbit configuration file.

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 using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

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
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: 0

🧹 Nitpick comments (4)
pyinjective/proto/exchange/injective_accounts_rpc_pb2.py (1)

49-116: Introduction of total_balance_usd and available_balance_usd.
These new fields expand the SubaccountDeposit message to support USD values. Ensure all referencing code handles these fields properly, including any backward-compatibility or migrations.

Consider adding test cases to confirm correct population of these fields in any relevant usage scenarios.

pyinjective/proto/exchange/injective_referral_rpc_pb2_grpc.py (1)

35-60: Methods remain unimplemented.
The servicer raises NotImplementedError with UNIMPLEMENTED status. Ensure this is intentional or provide actual implementations/extended error messages if needing partial support.

pyinjective/proto/exchange/injective_chart_rpc_pb2_grpc.py (1)

68-97: Unimplemented servicer methods.
SpotMarketSummary, AllSpotMarketSummary, DerivativeMarketSummary, and AllDerivativeMarketSummary raise NotImplementedError. If this is placeholder code, consider adding partial implementations or removing until ready.

pyinjective/core/gas_limit_estimator.py (1)

15-33: Consider centralizing constants for clarity.
These gas limit constants are well-labeled but could be grouped in an enum or dictionary to reduce clutter and ensure consistency across the file.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f8f5ce8 and fd60afc.

📒 Files selected for processing (41)
  • CHANGELOG.md (1 hunks)
  • Makefile (1 hunks)
  • buf.gen.yaml (1 hunks)
  • examples/exchange_client/oracle_rpc/1_StreamPrices.py (1 hunks)
  • examples/exchange_client/portfolio_rpc/1_AccountPortfolio.py (1 hunks)
  • pyinjective/async_client.py (1 hunks)
  • pyinjective/client/indexer/grpc/indexer_grpc_portfolio_api.py (2 hunks)
  • pyinjective/core/broadcaster.py (2 hunks)
  • pyinjective/core/gas_limit_estimator.py (6 hunks)
  • pyinjective/core/market.py (4 hunks)
  • pyinjective/ofac.json (1 hunks)
  • pyinjective/proto/exchange/injective_accounts_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_archiver_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_auction_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_campaign_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_chart_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_chart_rpc_pb2_grpc.py (4 hunks)
  • pyinjective/proto/exchange/injective_explorer_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_explorer_rpc_pb2_grpc.py (8 hunks)
  • pyinjective/proto/exchange/injective_portfolio_rpc_pb2.py (2 hunks)
  • pyinjective/proto/exchange/injective_referral_rpc_pb2.py (1 hunks)
  • pyinjective/proto/exchange/injective_referral_rpc_pb2_grpc.py (1 hunks)
  • pyinjective/proto/exchange/injective_spot_exchange_rpc_pb2.py (2 hunks)
  • pyinjective/proto/google/api/client_pb2.py (3 hunks)
  • pyinjective/proto/google/api/http_pb2.py (1 hunks)
  • pyinjective/proto/google/api/resource_pb2.py (1 hunks)
  • pyinjective/proto/google/api/visibility_pb2.py (1 hunks)
  • pyinjective/proto/ibc/core/connection/v1/tx_pb2.py (3 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/exchange_pb2.py (2 hunks)
  • pyinjective/proto/injective/permissions/v1beta1/query_pb2_grpc.py (3 hunks)
  • pyproject.toml (1 hunks)
  • tests/client/chain/grpc/test_chain_grpc_exchange_api.py (2 hunks)
  • tests/client/indexer/grpc/test_indexer_grpc_account_api.py (6 hunks)
  • tests/client/indexer/grpc/test_indexer_grpc_auction_api.py (4 hunks)
  • tests/client/indexer/grpc/test_indexer_grpc_explorer_api.py (8 hunks)
  • tests/client/indexer/grpc/test_indexer_grpc_portfolio_api.py (7 hunks)
  • tests/client/indexer/grpc/test_indexer_grpc_spot_api.py (2 hunks)
  • tests/client/indexer/stream_grpc/test_indexer_grpc_account_stream.py (2 hunks)
  • tests/client/indexer/stream_grpc/test_indexer_grpc_explorer_stream.py (2 hunks)
  • tests/core/test_gas_limit_estimator.py (16 hunks)
  • tests/core/test_message_based_transaction_fee_calculator.py (8 hunks)
🧰 Additional context used
🪛 Ruff (0.8.2)
tests/core/test_gas_limit_estimator.py

467-467: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


501-501: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


520-520: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


536-536: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


572-572: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


592-592: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


608-608: Redefinition of unused first_match_bet_market from line 35

(F811)


644-644: Redefinition of unused first_match_bet_market from line 35

(F811)


664-664: Redefinition of unused first_match_bet_market from line 35

(F811)


742-742: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


758-758: Redefinition of unused btc_usdt_perp_market from line 34

(F811)

🔇 Additional comments (123)
pyinjective/ofac.json (1)

22-22: New address added to OFAC blacklist.

A new Ethereum address has been added to the OFAC blacklist. This update expands the list of blacklisted addresses that will be checked against when validating transactions.

pyinjective/proto/injective/permissions/v1beta1/query_pb2_grpc.py (1)

98-99: Improved docstring formatting for better readability.

The docstrings for several methods in the QueryServicer class have been reformatted to break longer lines into shorter ones, improving readability without changing any functional behavior.

Also applies to: 122-123, 130-131, 138-139, 146-147, 154-155, 162-163, 177-178

pyinjective/core/broadcaster.py (1)

283-283:

❓ Verification inconclusive

Updated gas limit constant for transactions.

The constant TRANSACTION_GAS_LIMIT has been renamed to TRANSACTION_ANTE_GAS_LIMIT and its value has been increased from 60,000 to 105,000. This change aligns with the PR objective to update the gas estimator for fixed exchange gas.

The increased gas limit provides more headroom for transaction execution, which helps prevent out-of-gas errors when on-chain gas calculations have changed.

Also applies to: 297-297


🏁 Script executed:

#!/bin/bash
# Description: Check for any other references to the old constant name that might need updating

# Look for any remaining references to TRANSACTION_GAS_LIMIT
rg "TRANSACTION_GAS_LIMIT" --type py

Length of output: 36


Gas limit constant update confirmed – please manually verify residual references.

  • The change renames TRANSACTION_GAS_LIMIT to TRANSACTION_ANTE_GAS_LIMIT with the value increased from 60,000 to 105,000, aligning with the fixed exchange gas estimator update.
  • A search for TRANSACTION_GAS_LIMIT in Python files returned no results, suggesting the old constant appears to have been fully removed.
  • However, due to the low output from the verification script, please perform a manual review (especially in pyinjective/core/broadcaster.py at lines 283 and 297) to ensure there are no overlooked references.
pyinjective/proto/google/api/resource_pb2.py (1)

18-18: Updated protocol buffer generated code.

The serialized options for the resource descriptor have been updated. This is part of the broader update to compiled protocol buffers mentioned in the PR objectives.

These changes are automatically generated by the protocol buffer compiler and should be treated as implementation details that don't affect the API's behavior.

Also applies to: 25-25

pyinjective/proto/google/api/visibility_pb2.py (1)

18-18: No issues with the auto-generated protobuf changes

The modifications to the DESCRIPTOR variable and _serialized_options in this auto-generated file reflect the updated protocol buffer definitions. These changes are the result of recompiling the protocol buffers as specified in the PR objectives.

Also applies to: 25-25

pyinjective/proto/exchange/injective_auction_rpc_pb2.py (1)

17-17: Appropriate protobuf updates with new USD value field

The changes to this auto-generated protobuf file add a new usd_value field to the Coin message type, along with corresponding updates to serialized positions of various message types. This aligns with the PR objective of updating protocol buffers and is likely related to the gas heuristics changes mentioned in the PR description.

Also applies to: 32-48

pyinjective/client/indexer/grpc/indexer_grpc_portfolio_api.py (1)

1-1: Well-implemented USD parameter addition

The method signature has been properly updated to include an optional usd parameter with appropriate type hints. The implementation correctly passes this parameter to the request object, following good Python practices.

Also applies to: 24-27

pyinjective/proto/google/api/http_pb2.py (1)

17-17: No issues with the auto-generated protobuf changes

These changes to the DESCRIPTOR variable and _serialized_options are the expected result of recompiling the protocol buffers as specified in the PR objectives.

Also applies to: 24-24

pyinjective/proto/exchange/injective_spot_exchange_rpc_pb2.py (1)

17-125: Necessary protocol buffer definition updates

These changes reflect adjustments to the serialized positions for _COIN and _INJECTIVESPOTEXCHANGERPC entities to accommodate the new usd_value field added to the Coin structure. This is properly generated by the protocol buffer compiler and aligns with the PR objective of updating compiled protos.

buf.gen.yaml (1)

15-28: Updated dependency versions

The changes appropriately update the tags and branches for several Git dependencies:

  • cosmos-sdk: v0.50.9-inj-2 → v0.50.9-inj-4
  • ibc-go: v8.3.2-inj-0 → v8.6.1-inj
  • wasmd: v0.53.2-inj-1 → v0.53.2-inj.2
  • injective-core branch: testnet → master

These version updates align with the PR objective to update protocol buffers for both Indexer and Core components.

pyinjective/proto/exchange/injective_archiver_rpc_pb2.py (1)

17-77: Necessary protocol buffer definition updates

The adjustments to serialized positions for various entities in this file are consistent with the PR objective of updating all compiled protocol buffers. These changes accommodate updated protocol buffer definitions, ensuring the generated code accurately reflects the updated specifications.

pyinjective/core/market.py (4)

2-2: Added ROUND_UP for improved decimal handling

Appropriate addition of ROUND_UP import from the decimal module to support the new quantization functionality.


42-43: Enhanced notional value conversion with quantization

This change improves the precision of notional value conversion by adding a quantization step, ensuring values are rounded up to whole numbers before applying additional decimal formatting. This aligns with the PR objective of updating gas estimator logic to match on-chain gas heuristics changes.


124-125: Consistent implementation of quantization for DerivativeMarket

The quantization step is consistently implemented here for the DerivativeMarket class, ensuring uniform handling of notional values across different market types.


235-236: Consistent implementation of quantization for BinaryOptionMarket

The quantization approach is properly applied to the BinaryOptionMarket class, completing the consistent implementation across all market types and ensuring uniform behavior.

pyinjective/proto/exchange/injective_portfolio_rpc_pb2.py (2)

17-17: Auto-generated descriptor updates
These changes are generated by the protocol buffer compiler to incorporate updated fields (e.g., USD fields). No functional concerns identified.


38-58: Reflection data revisions
The _serialized_start and _serialized_end attributes for various messages and fields have been updated to align with newly introduced fields like usd_value. No issues detected with the generated output.

pyinjective/proto/ibc/core/connection/v1/tx_pb2.py (4)

22-22: Descriptor definition adjustment
The protocol buffer DESCRIPTOR has been recompiled for IBC connection messages to reflect the latest on-chain or .proto changes. Looks correct.


35-50: Field serialization options updated
The _serialized_options for fields like client_state and related fields have changed to b'\030\001', indicating slight modifications in serialization. No functional concerns.


52-74: Extended serialization and metadata
Additional fields (proof_client, proof_consensus, consensus_height, etc.) have updated _serialized_options to handle new or refined logic in connection messages. Everything appears consistent.


81-92: Refreshed descriptor indices
The _serialized_start and _serialized_end values have been refreshed for OpenTry, OpenAck, and related messages. This is normal for updated .proto compilations.

pyinjective/proto/google/api/client_pb2.py (2)

20-20: Regenerated DESCRIPTOR for client API
New descriptor content reflects changes in client library settings and code generation parameters. No issues found with this auto-generated code.


38-80: Enhanced library settings and serialization changes
Fields like SelectiveGapicGeneration and unversioned_package_disabled are incorporated into _serialized_ attributes. The updates look consistent with the revised .proto definitions.

pyinjective/proto/exchange/injective_chart_rpc_pb2.py (2)

17-17: Auto-generated descriptor update found.
These lines are standard protobuf boilerplate for the updated descriptor. No manual logic is present here, so no action is required.


28-50: Re-indexed serialized starts/ends.
These updates reflect the new or modified proto messages (e.g., added field “s” to SpotMarketHistoryResponse). Ensure downstream consumers are aware of the updated message layout.

pyinjective/proto/exchange/injective_campaign_rpc_pb2.py (2)

17-17: Descriptor assignment for updated proto.
This is a routine updated descriptor assignment. The generated code appears consistent with the changes in the proto schema.


32-66: New fields (e.g., usd_value) in _COIN.
The serialized boundaries were adjusted to accommodate fields like usd_value. Verify any services or integrations that might rely on the old field layout are updated accordingly.

pyinjective/proto/exchange/injective_accounts_rpc_pb2.py (1)

17-17: Updated descriptor for account-based messages.
No direct logic changes—merely an auto-generated shift for the new proto definitions.

pyinjective/proto/exchange/injective_explorer_rpc_pb2.py (2)

17-17: Exploration-service descriptor update.
Auto-generated changes setting up the updated descriptor references. No manual adjustments necessary.


58-190: New and updated message boundaries for Explorer RPC.
These changes (e.g., GetBlocksV2Request, Cursor, extended BlockInfo) should be tested to ensure older clients are not broken and new fields are handled gracefully in integration layers.

pyproject.toml (1)

3-3: Version bumped to 1.10.0-rc1

This version update aligns with the PR objectives of updating protocol buffers and modifying gas estimator logic. The change from 1.9.0-rc3 to 1.10.0-rc1 represents a minor version increment, which is appropriate for introducing these types of changes.

Makefile (1)

34-34: Updated injective-indexer to v1.14.25

This change updates the branch version for the injective-indexer repository clone from v1.13.117_RC1 to v1.14.25. This is consistent with the PR objectives of updating compiled protocol buffers for both Indexer and Core components.

The version update ensures that the SDK will be compatible with the latest Indexer API changes.

examples/exchange_client/oracle_rpc/1_StreamPrices.py (1)

32-32: Standardized oracle_type to lowercase

Adding the .lower() method call to market.oracle_type ensures consistent behavior in the listen_oracle_prices_updates method by standardizing the oracle type to lowercase format, regardless of how it's represented in the source data.

This is a good defensive programming practice to prevent potential case-sensitivity issues when using this value for API calls or comparisons.

tests/client/indexer/stream_grpc/test_indexer_grpc_account_stream.py (2)

26-28: Added USD balance fields to SubaccountDeposit

The test has been updated to include new fields for USD balance representation in the SubaccountDeposit object. This addition supports new functionality for representing balance values in USD.


64-66: Updated expected output to include USD balance fields

The expected balance update structure has been modified to include the new USD balance fields, ensuring the test properly validates the enhanced API response format.

These changes ensure the test accurately validates the USD balance representation feature that's been added to the account balance API.

examples/exchange_client/portfolio_rpc/1_AccountPortfolio.py (1)

12-12: Update demonstrates new USD parameter usage.

The code now explicitly passes usd=False to the fetch_account_portfolio_balances method, showing proper usage of the newly added parameter. This aligns with the PR's objective of updating API logic to accommodate recent changes in gas heuristics.

tests/client/indexer/stream_grpc/test_indexer_grpc_explorer_stream.py (2)

92-92: Added new Unix timestamp field to test data.

The test now includes the block_unix_timestamp field with a Unix timestamp value of 1699744939364, which is part of the protocol buffer updates mentioned in the PR objectives.


123-123: Updated expected response with new Unix timestamp field.

The expected update dictionary correctly includes the blockUnixTimestamp field derived from the block_unix_timestamp field of block_info, maintaining test validity with the updated protocol buffers.

tests/client/indexer/grpc/test_indexer_grpc_spot_api.py (5)

704-708: Added USD value field to source coin in atomic swap test.

The test case now includes the usd_value field for the source coin, which is part of the protocol buffer updates related to notional value conversion mentioned in the PR objectives.


709-713: Added USD value field to destination coin in atomic swap test.

The test case now includes the usd_value field for the destination coin, which aligns with the protocol buffer updates.


755-755: Updated assertion to validate destination coin USD value.

The expected output structure now validates the presence and correct mapping of the USD value field in the API response.


757-757: Updated assertion to validate fee USD value.

The expected output structure now includes validation for the USD value field in the fee coin.


763-767: Updated assertion to validate source coin USD value.

The expected output structure now properly checks the presence and correct structure of the USD value field in the source coin.

tests/client/indexer/grpc/test_indexer_grpc_auction_api.py (4)

24-24: Added USD value field to coin in fetch_auction test.

The test now includes the usd_value field set to "1000000000000000000" for coins, reflecting the protocol buffer updates for enhanced notional value conversion.


58-58: Updated assertion to validate USD value in auction response.

The expected auction structure now correctly verifies the usdValue field, ensuring the API handles and returns the new field properly.


79-79: Added USD value field to coin in fetch_auctions test.

The test now appropriately includes the usd_value field for coins in the auction basket, maintaining consistency with the updated protocol buffers.


103-103: Updated assertion to validate USD value in auctions response.

The expected auctions response now verifies the usdValue field's presence and correct structure in the API response.

pyinjective/async_client.py (1)

2040-2045: API Enhancement: Added USD parameter to fetch_account_portfolio_balances

The method signature has been updated to include an optional usd parameter, allowing clients to fetch portfolio balances with USD values. This enhancement aligns with the protocol buffer updates mentioned in the PR objectives.

CHANGELOG.md (3)

5-8: Appropriate changelog entry for gas estimator updates

The changelog correctly documents the gas estimator update as described in the PR objective, which includes aligning the implementation with on-chain values for fixed gas messages.


9-12: Appropriate changelog entry for notional value conversion fix

The entry correctly documents the addition of quantization in notional value conversion functions, which is part of the updates mentioned in the PR.


13-13: Updated release date for version 1.9.0

The release date has been properly updated.

tests/client/chain/grpc/test_chain_grpc_exchange_api.py (2)

63-63: Added fixed gas parameter to align with on-chain changes.

The addition of the fixed_gas_enabled=True parameter to the Params object reflects the implementation of new gas heuristics mentioned in PR CP-235. This is a necessary change to keep the tests aligned with the updated protocol.


113-113: Updated expected params with fixed gas enabled field.

This change correctly adds the fixed gas enabled field to the expected output, ensuring that the test validates the proper handling of this new parameter in the API response.

tests/client/indexer/grpc/test_indexer_grpc_account_api.py (6)

136-137: Added USD balance fields to SubaccountDeposit.

These new fields properly reflect the changes to the SubaccountDeposit structure to include USD value representations of balances, which is consistent with the overall updates being made to incorporate USD values throughout the system.


163-164: Added USD fields to expected output for validation.

The test has been correctly updated to verify that the API response includes the new USD balance fields, ensuring proper validation of the enhanced API functionality.


180-181: Added USD balance fields to SubaccountDeposit in another test.

Consistent implementation of the USD balance fields across multiple test cases, ensuring comprehensive coverage of the new functionality.


207-208: Updated expected output to verify USD fields.

The test validation has been appropriately updated to ensure that the API correctly processes and returns the new USD balance fields.


341-341: Added USD value field to Coin structure.

This change adds the usd_value field to the Coin structure, which is consistent with the larger effort to incorporate USD values throughout the codebase.


363-363: Updated expected rewards output to validate USD value.

The expected output has been properly updated to verify that the API correctly processes and returns the new USD value field for reward coins.

tests/client/indexer/grpc/test_indexer_grpc_explorer_api.py (2)

63-63: Well-integrated timestamp field additions to protocol buffer responses

The addition of block_unix_timestamp fields to various data structures (TxData, BlockInfo, TxDetailData) and their corresponding assertions in the test provides Unix timestamp representations of block times. This enhances the API by offering a standardized, numeric timestamp format that's easier to process programmatically than string timestamps.

Also applies to: 153-153, 214-214, 297-297, 358-358, 439-439, 464-464, 498-498, 532-532, 592-592, 841-841, 894-894


1619-1619: USD value field addition enhances transaction information

The addition of the usd_value field to the Coin structure and its corresponding assertion in the test provides additional context about the fiat value of cryptocurrency amounts. This is valuable for users who need to understand the USD equivalent of their token holdings or transfers.

Also applies to: 1661-1661

pyinjective/proto/injective/exchange/v1beta1/exchange_pb2.py (2)

303-416: Updated serialization positions accommodate protocol buffer changes

The changes to serialization start and end positions for various message types are necessary to accommodate additions or modifications to the Protocol Buffer definitions. These updates ensure correct serialization and deserialization of messages with the newly added fields such as Unix timestamps and USD values.


21-21: Updated DESCRIPTOR serialization includes new field definitions

The modification to the serialized DESCRIPTOR accommodates changes to the Protocol Buffer definitions, particularly the addition of fields like is_instant_derivative_market_launch_enabled in the Params message and other fields observed in the test file updates.

tests/core/test_message_based_transaction_fee_calculator.py (3)

10-15: Updates to gas limit imports reflect the new structure

The import modifications replace GenericExchangeGasLimitEstimator with the more specific constant SPOT_ORDER_CREATION_GAS_LIMIT, which aligns with the PR objective of updating gas estimator logic to match on-chain changes.


62-62: Gas limit constants updated for consistency

The changes replace TRANSACTION_GAS_LIMIT with TRANSACTION_ANTE_GAS_LIMIT and update inner message gas limits to use specific constants like SPOT_ORDER_CREATION_GAS_LIMIT instead of generic references. This properly implements the PR objective to update gas estimator logic to align with recent on-chain changes to gas heuristics.

Also applies to: 90-90, 112-112, 134-134, 161-161, 193-194, 232-233


151-154: Function parameter formatting is consistent

The updated msg_liquidate_position call maintains proper parameter formatting with the new market_id parameter.

pyinjective/proto/exchange/injective_explorer_rpc_pb2_grpc.py (8)

38-42: New GetBlocksV2 method added to the stub class

This addition introduces a new version of the blocks retrieval method, following the proper gRPC pattern for method registration with appropriate serialization and deserialization.


68-72: New GetTxsV2 method added to the stub class

Similar to the blocks method, this adds a new version of the transactions retrieval method with proper serialization configuration.


177-183: GetBlocksV2 method implementation in servicer class

The method is properly defined with appropriate documentation and follows the established pattern of raising NotImplementedError until actual implementation is provided.


219-225: GetTxsV2 method implementation in servicer class

The method follows the same pattern as other unimplemented methods, raising NotImplementedError as expected.


351-355: Method handler for GetBlocksV2 added to server configuration

The RPC method handler is properly registered with the correct request deserializer and response serializer.


381-385: Method handler for GetTxsV2 added to server configuration

The server configuration is properly updated to include the new method handler with correct serialization functions.


576-601: Experimental API method for GetBlocksV2

The static method implementation follows the established pattern for other experimental gRPC methods, ensuring consistent client-side implementation.


738-764: Experimental API method for GetTxsV2

The implementation maintains consistency with other experimental API methods, ensuring proper serialization and parameter handling.

tests/client/indexer/grpc/test_indexer_grpc_portfolio_api.py (6)

24-24: Added USD value fields to balance objects

USD value fields are added to the coin and subaccount deposit objects. This supports the enhanced functionality for displaying monetary values in USD across the application.

Also applies to: 29-30


79-80: Updated expected response structure with USD fields

The expected response structure properly includes the new USD-related fields, ensuring that tests validate the new functionality correctly.

Also applies to: 89-90


126-127: Added USD value fields to portfolio balance test

Similar USD value fields are added to the portfolio balance test objects, maintaining consistency across all test cases.

Also applies to: 131-132


144-144: Added total USD field to portfolio balances

The new total_usd field provides an aggregate USD value for the entire portfolio, enhancing the functionality for users to understand their total portfolio value.


155-155: Updated API call to include USD parameter

The API call now includes the usd=True parameter, indicating that USD values should be included in the response. This properly tests the new feature.


163-164: Updated expected response includes all USD fields

The expected response structure properly validates all new USD fields, ensuring comprehensive test coverage of the new functionality.

Also applies to: 173-174, 178-178

pyinjective/proto/exchange/injective_referral_rpc_pb2.py (1)

1-41: New referral system protocol buffer definitions

This file introduces a new referral system with comprehensive message definitions for handling referrer and invitee details. The generated protocol buffer code includes:

  1. Request/response pairs for referrer details, invitee details, and referrer lookups by code
  2. A ReferralInvitee message type for representing invitees with their commissions and trading volumes
  3. A new InjectiveReferralRPC service with appropriate methods

This addition enhances the platform's capabilities for implementing referral programs and tracking related metrics.

pyinjective/proto/exchange/injective_referral_rpc_pb2_grpc.py (4)

1-7: Auto-generated stubs look good.
These lines are standard boilerplate generated by the gRPC Python protocol compiler. No issues found here.


8-33: Client stub implementation is consistent.
The InjectiveReferralRPCStub class follows the typical gRPC pattern. All method registrations appear correct.


62-84: Service registration is standard.
The add_InjectiveReferralRPCServicer_to_server function is appropriately set up to handle the service’s RPC methods.


86-171: Experimental static methods are fine.
No concerns about the experimental InjectiveReferralRPC class. The static methods correctly match the service paths.

pyinjective/proto/exchange/injective_chart_rpc_pb2_grpc.py (3)

28-47: New Spot/Derivative Market Summaries look properly defined.
The newly added unary-unary methods for spot/derivative summaries in the InjectiveChartRPCStub appear consistent with existing patterns.


111-130: Handlers mapping looks correct.
The added handlers in add_InjectiveChartRPCServicer_to_server align with the newly defined methods.


196-304: Static call definitions match new RPC endpoints.
These client-side methods in InjectiveChartRPC are consistent with the stub’s definitions and serialization logic.

pyinjective/core/gas_limit_estimator.py (18)

111-132: Check for missing validation on order type.
The post-only vs. non-post-only logic is correct, but consider validating unknown order types to avoid silent fallback.


134-147: Spot market order gas limit logic is straightforward.
No issues spotted. Implementation cleanly returns a fixed limit.


149-162: Cancel spot order estimator is clean.
Everything looks consistent and clear.


164-185: Derivative limit orders logic parallels spot.
Post-only check is consistent with the rest of the code.


187-200: Create derivative market orders returns correct constant.
Implementation is straightforward and matches naming.


202-215: Cancel derivative order estimator is consistent.
Code mirrors spot cancellation. Looks good.


217-238: Binary options limit orders mirror derivative logic.
No concerns about the approach. Consistent with the file’s pattern.


240-253: Binary options market orders use a single constant.
Implementation is aligned with derivative approach.


255-268: Cancel binary options order matches existing code style.
No issues found here.


279-283: Potential double counting for post-only orders.
You add both SPOT_ORDER_CREATION_GAS_LIMIT and also POST_ONLY_SPOT_ORDER_CREATION_GAS_LIMIT for the same post-only order. Confirm whether this is intentional or if the post-only portion should be a replacement, not an additive cost.


318-323: Check for double counting in derivative orders.
Similar to spot orders, ensure adding both base and post-only creation gas costs is the intended logic.


368-392: Verify additive approach in batch update orders.
The code adds standard creation cost plus post-only creation cost for each post-only order. Confirm it’s not double charging.


400-414: Deposit estimator is concise.
The new deposit logic is straightforward. Implementation aligns well with the naming.


416-430: Withdraw estimator is consistent.
Implementation cleanly returns the corresponding constant.


432-446: Subaccount transfer estimator is correct.
No logical issues spotted.


448-462: External transfer estimator is straightforward.
Matches the pattern established in the file.


464-478: Increase position margin estimator looks correct.
No apparent issues; naming is clear.


480-494: Decrease margin estimator is well-aligned.
Implementation is consistent with the rest of the margin logic.

tests/core/test_gas_limit_estimator.py (17)

7-24: Gas limit constants added for comprehensive coverage.

The additions of numerous new gas limit constants significantly expand the SDK's ability to accurately estimate gas costs for various operation types, including binary options, market orders, transfers, and position margin adjustments.


93-93: Simplified gas limit calculation for batch operations.

The assertion has been simplified to only consider the total gas cost as the product of individual operation cost and operation count, removing any additional overhead previously included.


120-120: Consistent simplification of batch operation gas calculations.

All batch operation gas calculations now follow the same simplified approach, ensuring consistency across different order types.

Also applies to: 149-149, 176-176, 209-209, 244-244, 300-300, 333-333, 366-366, 400-400


417-421: Improved formatting for cancel-all gas calculations.

The cancel-all gas estimations now use a cleaner multi-line format while maintaining the correct calculation logic for each market type.

Also applies to: 438-443, 460-465


467-499: New test for spot limit order gas estimation.

Added comprehensive test coverage for regular and post-only spot limit orders, ensuring the appropriate gas constants are used.

🧰 Tools
🪛 Ruff (0.8.2)

467-467: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


501-518: New test for spot market order gas estimation.

Added test coverage for spot market orders with their specific gas requirements.

🧰 Tools
🪛 Ruff (0.8.2)

501-501: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


520-534: New test for spot order cancellation gas estimation.

Added test coverage for spot order cancellation operations.

🧰 Tools
🪛 Ruff (0.8.2)

520-520: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


536-570: New test for derivative limit order gas estimation.

Added comprehensive test coverage for regular and post-only derivative limit orders.

🧰 Tools
🪛 Ruff (0.8.2)

536-536: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


572-590: New test for derivative market order gas estimation.

Added test coverage for derivative market orders.

🧰 Tools
🪛 Ruff (0.8.2)

572-572: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


592-606: New test for derivative order cancellation gas estimation.

Added test coverage for derivative order cancellation operations.

🧰 Tools
🪛 Ruff (0.8.2)

592-592: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


608-642: New test for binary options limit order gas estimation.

Added comprehensive test coverage for regular and post-only binary options limit orders.

🧰 Tools
🪛 Ruff (0.8.2)

608-608: Redefinition of unused first_match_bet_market from line 35

(F811)


644-662: New test for binary options market order gas estimation.

Added test coverage for binary options market orders.

🧰 Tools
🪛 Ruff (0.8.2)

644-644: Redefinition of unused first_match_bet_market from line 35

(F811)


664-678: New test for binary options order cancellation gas estimation.

Added test coverage for binary options order cancellation operations.

🧰 Tools
🪛 Ruff (0.8.2)

664-664: Redefinition of unused first_match_bet_market from line 35

(F811)


680-693: New tests for deposit and withdraw gas estimation.

Added test coverage for deposit and withdraw operations, ensuring appropriate gas limits are applied.

Also applies to: 695-708


710-724: New tests for transfer operations gas estimation.

Added test coverage for subaccount and external transfer operations.

Also applies to: 726-740


742-756: New tests for position margin adjustment gas estimation.

Added test coverage for increasing and decreasing position margin operations.

Also applies to: 758-772

🧰 Tools
🪛 Ruff (0.8.2)

742-742: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


800-800: Updated exec message gas calculation.

Modified the assertion to match the updated gas calculation approach.

Copy link
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: 3

🧹 Nitpick comments (27)
examples/chain_client/ibc/transfer/1_MsgTransfer.py (1)

63-66: Consider if the second gas price update is necessary.

The code fetches and updates the gas price a second time after the transaction is already broadcast. This would only be useful if the message_broadcaster will be used for additional transactions later in the script. If this is a single-transaction example, this update appears to be unnecessary.

If no further transactions are being sent in this script, consider removing this second gas price update:

-    gas_price = await client.current_chain_gas_price()
-    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-    gas_price = int(gas_price * 1.1)
-    message_broadcaster.update_gas_price(gas_price=gas_price)
examples/chain_client/exchange/10_MsgCreateDerivativeLimitOrder.py (1)

77-81: Improved gas price handling with dynamic fetching.

The code now dynamically retrieves the current gas price from the chain instead of using a static value, making the application more responsive to current network conditions. The 10% adjustment provides a buffer against price fluctuations during transaction broadcasting.

Consider extracting this gas price adjustment pattern into a helper function since it appears in multiple files.

tests/client/chain/grpc/configurable_txfees_query_servicer.py (1)

6-16: Add docstrings to improve code documentation

Consider adding docstrings to the class and its methods to document their purpose, parameters, and return values. This will help other developers understand how to use this servicer class in tests.

class ConfigurableTxfeesQueryServicer(txfees_query_grpc.QueryServicer):
+    """
+    A configurable servicer for txfees queries used in testing.
+    Allows pre-configuring responses by adding them to the respective deques.
+    """
    def __init__(self):
        super().__init__()
        self.params_responses = deque()
        self.eip_base_fee_responses = deque()

    async def Params(self, request: txfees_query_pb.QueryParamsRequest, context=None, metadata=None):
+        """
+        Handles params query requests by returning pre-configured responses.
+        
+        Args:
+            request: The QueryParamsRequest
+            context: gRPC context (optional)
+            metadata: Request metadata (optional)
+            
+        Returns:
+            The last response added to params_responses
+        """
        return self.params_responses.pop()

    async def GetEipBaseFee(self, request: txfees_query_pb.QueryEipBaseFeeRequest, context=None, metadata=None):
+        """
+        Handles EIP base fee query requests by returning pre-configured responses.
+        
+        Args:
+            request: The QueryEipBaseFeeRequest
+            context: gRPC context (optional)
+            metadata: Request metadata (optional)
+            
+        Returns:
+            The last response added to eip_base_fee_responses
+        """
        return self.eip_base_fee_responses.pop()
examples/chain_client/distribution/3_WithdrawValidatorCommission.py (1)

49-52: Consider extracting the gas price adjustment logic

The gas price fetching and adjustment logic appears in two places (lines 22-24 and 49-52). Consider extracting this into a helper function to avoid code duplication.

async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

+    async def get_adjusted_gas_price():
+        """Fetch and adjust gas price with 10% buffer."""
+        gas_price = await client.current_chain_gas_price()
+        return int(gas_price * 1.1)  # 10% buffer
+
    # select network: local, testnet, mainnet
    network = Network.testnet()
    client = AsyncClient(network)
    composer = await client.composer()

-    gas_price = await client.current_chain_gas_price()
-    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-    gas_price = int(gas_price * 1.1)
+    gas_price = await get_adjusted_gas_price()

    message_broadcaster = MsgBroadcasterWithPk.new_without_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # ... rest of the function ...

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

-    gas_price = await client.current_chain_gas_price()
-    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-    gas_price = int(gas_price * 1.1)
+    gas_price = await get_adjusted_gas_price()
    message_broadcaster.update_gas_price(gas_price=gas_price)
examples/chain_client/exchange/25_MsgUpdateDerivativeMarket.py (1)

61-64: Consider extracting the gas price adjustment logic

The gas price fetching and adjustment logic appears in two places (lines 26-28 and 61-64). Consider extracting this into a helper function to avoid code duplication.

async def main() -> None:
    dotenv.load_dotenv()
    configured_private_key = os.getenv("INJECTIVE_PRIVATE_KEY")

+    async def get_adjusted_gas_price():
+        """Fetch and adjust gas price with 10% buffer."""
+        gas_price = await client.current_chain_gas_price()
+        return int(gas_price * 1.1)  # 10% buffer
+
    # select network: local, testnet, mainnet
    network = Network.testnet()

    # initialize grpc client
    client = AsyncClient(network)
    await client.initialize_tokens_from_chain_denoms()
    composer = await client.composer()

-    gas_price = await client.current_chain_gas_price()
-    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-    gas_price = int(gas_price * 1.1)
+    gas_price = await get_adjusted_gas_price()

    message_broadcaster = MsgBroadcasterWithPk.new_using_simulation(
        network=network,
        private_key=configured_private_key,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )

    # ... rest of the function ...

    # broadcast the transaction
    result = await message_broadcaster.broadcast([message])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

-    gas_price = await client.current_chain_gas_price()
-    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-    gas_price = int(gas_price * 1.1)
+    gas_price = await get_adjusted_gas_price()
    message_broadcaster.update_gas_price(gas_price=gas_price)
examples/chain_client/exchange/13_MsgInstantBinaryOptionsMarketLaunch.py (2)

24-27: Consider making the 1.1 multiplier configurable.

Multiplying the gas price by 1.1 is a quick fix for on-chain gas fluctuations. However, you might consider extracting this ratio to a configuration or environment variable for easier tuning.

-    gas_price = int(gas_price * 1.1)
+    multiplier = float(os.getenv("GAS_PRICE_MULTIPLIER", "1.1"))
+    gas_price = int(gas_price * multiplier)

67-70: Re-fetching gas price ensures up-to-date fees.

Re-fetching and updating the gas price after broadcasting allows for better adaptation to network conditions. This is a valid approach, though repeated calls might be unnecessary if only a single transaction is broadcast.

examples/chain_client/exchange/23_MsgDecreasePositionMargin.py (2)

24-27: Give consideration to making the multiplier configurable.

Similar to other scripts, extracting the 1.1 multiplier into a parameter aids future fine-tuning of gas costs.

-    gas_price = int(gas_price * 1.1)
+    multiplier = float(os.getenv("GAS_PRICE_MULTIPLIER", "1.1"))
+    gas_price = int(gas_price * multiplier)

61-64: Dynamic update of gas price is beneficial.

Fetching and setting a new gas price post-transaction handles changing network fees. Confirm if multiple broadcasts warrant repeated updates.

examples/chain_client/exchange/26_MsgAuthorizeStakeGrants.py (2)

25-28: Parameterize the gas multiplier for easier maintenance.

A static multiplier of 1.1 is fine short-term, but consider making it configurable to handle different network conditions or user preferences.

-    gas_price = int(gas_price * 1.1)
+    multiplier = float(os.getenv("GAS_PRICE_MULTIPLIER", "1.1"))
+    gas_price = int(gas_price * multiplier)

56-59: Re-fetching gas price supports continuously changing conditions.

Confirm if re-checking the gas price immediately after broadcasting is necessary for your workflow. This approach is valid but might be optional if only a single TX is broadcast in this script.

examples/chain_client/tokenfactory/3_MsgBurn.py (2)

19-25: Consider making gas price multiplier configurable.

While 1.1 is a sensible buffer, externalizing this factor will make adjustments simpler as chain conditions evolve.

-    gas_price = int(gas_price * 1.1)
+    multiplier = float(os.getenv("GAS_PRICE_MULTIPLIER", "1.1"))
+    gas_price = int(gas_price * multiplier)

52-55: Post-transaction gas price update.

Re-fetching the latest gas price can be beneficial if multiple transactions follow. Otherwise, it may be unnecessary overhead.

examples/chain_client/exchange/24_MsgUpdateSpotMarket.py (1)

59-62: Added gas price update after transaction broadcast.

This is an important addition that ensures the message broadcaster uses the most current gas price for any subsequent transactions.

Consider extracting the gas price fetching and adjustment logic into a separate helper function to avoid code duplication, as this pattern appears in multiple files:

-gas_price = await client.current_chain_gas_price()
-# adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-gas_price = int(gas_price * 1.1)
+gas_price = await get_adjusted_gas_price(client)

With a utility function like:

async def get_adjusted_gas_price(client, adjustment_factor=1.1):
    """
    Fetch current gas price and apply adjustment factor to account for fluctuations.
    
    Args:
        client: AsyncClient instance
        adjustment_factor: Multiplier to account for gas price fluctuations (default: 1.1)
        
    Returns:
        int: Adjusted gas price
    """
    gas_price = await client.current_chain_gas_price()
    return int(gas_price * adjustment_factor)
examples/chain_client/tokenfactory/5_MsgSetDenomMetadata.py (1)

66-69: Added gas price update after transaction broadcast.

This ensures the message broadcaster uses the most current gas price for any subsequent transactions.

The gas price fetching and adjustment logic is duplicated in multiple files. Consider creating a shared utility function to reduce duplication, following DRY principles.

examples/chain_client/3_MessageBroadcaster.py (1)

79-82: Added gas price update after transaction broadcast.

This ensures the message broadcaster uses the most current gas price for subsequent transactions.

Consider adding explicit error handling around the gas price fetching and update operations to gracefully handle any API failures. While the current_chain_gas_price() method has internal error handling, adding try-except blocks around the critical gas price operations in the example would be more robust.

-gas_price = await client.current_chain_gas_price()
-# adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-gas_price = int(gas_price * 1.1)
-message_broadcaster.update_gas_price(gas_price=gas_price)
+try:
+    gas_price = await client.current_chain_gas_price()
+    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
+    gas_price = int(gas_price * 1.1)
+    message_broadcaster.update_gas_price(gas_price=gas_price)
+except Exception as e:
+    print(f"Warning: Failed to update gas price: {e}")
examples/chain_client/exchange/27_MsgActivateStakeGrant.py (1)

53-56: Gas price refreshing after transaction.

Good practice to refresh the gas price after transaction completion and update the broadcaster to ensure subsequent transactions use the latest gas price.

Consider extracting the gas price fetching and adjustment logic to a helper function to avoid code duplication with the similar code at lines 25-27.

+async def get_adjusted_gas_price(client):
+    gas_price = await client.current_chain_gas_price()
+    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
+    return int(gas_price * 1.1)
+

Then you could replace both instances with:

-gas_price = await client.current_chain_gas_price()
-# adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-gas_price = int(gas_price * 1.1)
+gas_price = await get_adjusted_gas_price(client)
examples/chain_client/6_MessageBroadcasterWithGranteeAccountWithoutSimulation.py (1)

65-68: Gas price refreshing after transaction.

Good practice to refresh the gas price after transaction completion and update the broadcaster to ensure subsequent transactions use the latest gas price.

Consider extracting the gas price fetching and adjustment logic to a helper function to avoid code duplication with the similar code at lines 32-34.

examples/chain_client/5_MessageBroadcasterWithoutSimulation.py (1)

80-83: Gas price refreshing after transaction.

Good practice to refresh the gas price after transaction completion and update the broadcaster to ensure subsequent transactions use the latest gas price.

Consider extracting the gas price fetching and adjustment logic to a helper function to avoid code duplication with the similar code at lines 26-28.

Additionally, consider adding basic error handling for gas price fetching to gracefully handle connection issues:

+async def get_adjusted_gas_price(client):
+    try:
+        gas_price = await client.current_chain_gas_price()
+        # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
+        return int(gas_price * 1.1)
+    except Exception as e:
+        print(f"Error fetching gas price: {e}. Using default adjustment.")
+        return int(client.network.gas_price() * 1.1)
+
tests/core/test_gas_heuristics_gas_limit_estimator.py (2)

95-120: Test uses hardcoded spot market ID rather than fixture.

The test for batch cancel spot orders uses a hardcoded market ID instead of leveraging the spot market fixture like other tests.

Consider modifying the test to use the fixture-provided spot market ID for consistency:

-def test_estimation_for_batch_cancel_spot_orders(self):
-    spot_market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
-    composer = Composer(network="testnet")
+def test_estimation_for_batch_cancel_spot_orders(self, basic_composer, inj_usdt_spot_market):
+    spot_market_id = inj_usdt_spot_market.id
+    composer = basic_composer

151-176: Test uses hardcoded derivative market ID rather than fixture.

The test for batch cancel derivative orders uses a hardcoded market ID instead of leveraging the derivative market fixture like other tests.

Consider modifying the test to use the fixture-provided derivative market ID for consistency:

-def test_estimation_for_batch_cancel_derivative_orders(self):
-    spot_market_id = "0x0611780ba69656949525013d947713300f56c37b6175e02f26bffa495c3208fe"
-    composer = Composer(network="testnet")
+def test_estimation_for_batch_cancel_derivative_orders(self, basic_composer, btc_usdt_perp_market):
+    market_id = btc_usdt_perp_market.id
+    composer = basic_composer

Also, note that the variable is named spot_market_id but it's used for derivative orders, which may be confusing.

pyinjective/proto/injective/txfees/v1beta1/query_pb2_grpc.py (3)

8-10: Add missing docstring or reference.

The class QueryStub lacks a descriptive docstring. Consider providing a short description for clarity and maintainability.


32-38: Implement or remove placeholder method.

Params is currently unimplemented and raises NotImplementedError. If you're planning a future implementation, consider adding a TODO or partial logic to indicate the next steps.


40-46: Implement or remove placeholder method.

GetEipBaseFee is also currently unimplemented. If it remains a placeholder, clearly document when and how it will be implemented to avoid confusion.

pyinjective/core/gas_heuristics_gas_limit_estimator.py (3)

35-38: Align with the existing GasLimitEstimator.

GasHeuristicsGasLimitEstimator inherits similar responsibilities to the general GasLimitEstimator. Ensure that introducing another hierarchy doesn't create confusion or duplication. Consider referencing or extending GasLimitEstimator directly to keep the code DRY.


332-383: Re-evaluate default assumptions in BatchUpdateOrders.

The AVERAGE_CANCEL_ALL_AFFECTED_ORDERS constant (20) is a heuristic that may lead to under- or over-estimations if real usage significantly differs. Regularly validate these assumptions against actual on-chain data or usage metrics.


480-503: Ensure bounding of dynamic sums in ExecGasLimitEstimator.

MsgExec sums the gas for each sub-message plus a default overhead of 20_000. In large or nested messages, this might exceed practical block or transaction limits. Add checks or logs to prevent the risk of transaction submission failures.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between fd60afc and 45b98d2.

📒 Files selected for processing (82)
  • examples/chain_client/1_LocalOrderHash.py (4 hunks)
  • examples/chain_client/3_MessageBroadcaster.py (3 hunks)
  • examples/chain_client/4_MessageBroadcasterWithGranteeAccount.py (3 hunks)
  • examples/chain_client/5_MessageBroadcasterWithoutSimulation.py (3 hunks)
  • examples/chain_client/6_MessageBroadcasterWithGranteeAccountWithoutSimulation.py (3 hunks)
  • examples/chain_client/auction/1_MsgBid.py (2 hunks)
  • examples/chain_client/authz/1_MsgGrant.py (2 hunks)
  • examples/chain_client/authz/2_MsgExec.py (2 hunks)
  • examples/chain_client/authz/3_MsgRevoke.py (2 hunks)
  • examples/chain_client/bank/1_MsgSend.py (2 hunks)
  • examples/chain_client/distribution/1_SetWithdrawAddress.py (3 hunks)
  • examples/chain_client/distribution/2_WithdrawDelegatorReward.py (3 hunks)
  • examples/chain_client/distribution/3_WithdrawValidatorCommission.py (3 hunks)
  • examples/chain_client/distribution/4_FundCommunityPool.py (3 hunks)
  • examples/chain_client/exchange/10_MsgCreateDerivativeLimitOrder.py (2 hunks)
  • examples/chain_client/exchange/11_MsgCreateDerivativeMarketOrder.py (2 hunks)
  • examples/chain_client/exchange/12_MsgCancelDerivativeOrder.py (2 hunks)
  • examples/chain_client/exchange/13_MsgInstantBinaryOptionsMarketLaunch.py (3 hunks)
  • examples/chain_client/exchange/14_MsgCreateBinaryOptionsLimitOrder.py (2 hunks)
  • examples/chain_client/exchange/15_MsgCreateBinaryOptionsMarketOrder.py (2 hunks)
  • examples/chain_client/exchange/16_MsgCancelBinaryOptionsOrder.py (2 hunks)
  • examples/chain_client/exchange/17_MsgSubaccountTransfer.py (2 hunks)
  • examples/chain_client/exchange/18_MsgExternalTransfer.py (2 hunks)
  • examples/chain_client/exchange/19_MsgLiquidatePosition.py (2 hunks)
  • examples/chain_client/exchange/1_MsgDeposit.py (2 hunks)
  • examples/chain_client/exchange/20_MsgIncreasePositionMargin.py (2 hunks)
  • examples/chain_client/exchange/21_MsgRewardsOptOut.py (2 hunks)
  • examples/chain_client/exchange/22_MsgAdminUpdateBinaryOptionsMarket.py (2 hunks)
  • examples/chain_client/exchange/23_MsgDecreasePositionMargin.py (3 hunks)
  • examples/chain_client/exchange/24_MsgUpdateSpotMarket.py (3 hunks)
  • examples/chain_client/exchange/25_MsgUpdateDerivativeMarket.py (3 hunks)
  • examples/chain_client/exchange/26_MsgAuthorizeStakeGrants.py (3 hunks)
  • examples/chain_client/exchange/27_MsgActivateStakeGrant.py (3 hunks)
  • examples/chain_client/exchange/2_MsgWithdraw.py (2 hunks)
  • examples/chain_client/exchange/3_MsgInstantSpotMarketLaunch.py (3 hunks)
  • examples/chain_client/exchange/4_MsgInstantPerpetualMarketLaunch.py (3 hunks)
  • examples/chain_client/exchange/5_MsgInstantExpiryFuturesMarketLaunch.py (3 hunks)
  • examples/chain_client/exchange/6_MsgCreateSpotLimitOrder.py (2 hunks)
  • examples/chain_client/exchange/7_MsgCreateSpotMarketOrder.py (2 hunks)
  • examples/chain_client/exchange/8_MsgCancelSpotOrder.py (2 hunks)
  • examples/chain_client/exchange/9_MsgBatchUpdateOrders.py (2 hunks)
  • examples/chain_client/ibc/transfer/1_MsgTransfer.py (3 hunks)
  • examples/chain_client/insurance/1_MsgCreateInsuranceFund.py (2 hunks)
  • examples/chain_client/insurance/2_MsgUnderwrite.py (2 hunks)
  • examples/chain_client/insurance/3_MsgRequestRedemption.py (2 hunks)
  • examples/chain_client/oracle/1_MsgRelayPriceFeedPrice.py (2 hunks)
  • examples/chain_client/oracle/2_MsgRelayProviderPrices.py (2 hunks)
  • examples/chain_client/peggy/1_MsgSendToEth.py (2 hunks)
  • examples/chain_client/permissions/1_MsgCreateNamespace.py (3 hunks)
  • examples/chain_client/permissions/2_MsgUpdateNamespace.py (3 hunks)
  • examples/chain_client/permissions/3_MsgUpdateActorRoles.py (3 hunks)
  • examples/chain_client/permissions/4_MsgClaimVoucher.py (3 hunks)
  • examples/chain_client/staking/1_MsgDelegate.py (2 hunks)
  • examples/chain_client/tokenfactory/1_CreateDenom.py (3 hunks)
  • examples/chain_client/tokenfactory/2_MsgMint.py (3 hunks)
  • examples/chain_client/tokenfactory/3_MsgBurn.py (3 hunks)
  • examples/chain_client/tokenfactory/4_MsgChangeAdmin.py (3 hunks)
  • examples/chain_client/tokenfactory/5_MsgSetDenomMetadata.py (3 hunks)
  • examples/chain_client/txfees/query/1_GetEipBaseFee.py (1 hunks)
  • examples/chain_client/wasm/1_MsgExecuteContract.py (2 hunks)
  • examples/chain_client/wasmx/1_MsgExecuteContractCompat.py (2 hunks)
  • pyinjective/async_client.py (6 hunks)
  • pyinjective/client/chain/grpc/chain_grpc_token_factory_api.py (0 hunks)
  • pyinjective/client/chain/grpc/chain_grpc_txfees_api.py (1 hunks)
  • pyinjective/core/broadcaster.py (11 hunks)
  • pyinjective/core/gas_heuristics_gas_limit_estimator.py (1 hunks)
  • pyinjective/proto/injective/exchange/v1beta1/query_pb2.py (3 hunks)
  • pyinjective/proto/injective/txfees/v1beta1/genesis_pb2.py (1 hunks)
  • pyinjective/proto/injective/txfees/v1beta1/genesis_pb2_grpc.py (1 hunks)
  • pyinjective/proto/injective/txfees/v1beta1/query_pb2.py (1 hunks)
  • pyinjective/proto/injective/txfees/v1beta1/query_pb2_grpc.py (1 hunks)
  • pyinjective/proto/injective/txfees/v1beta1/tx_pb2.py (1 hunks)
  • pyinjective/proto/injective/txfees/v1beta1/tx_pb2_grpc.py (1 hunks)
  • pyinjective/proto/injective/txfees/v1beta1/txfees_pb2.py (1 hunks)
  • pyinjective/proto/injective/txfees/v1beta1/txfees_pb2_grpc.py (1 hunks)
  • pyinjective/proto/osmosis/txfees/v1beta1/query_pb2.py (1 hunks)
  • pyinjective/proto/osmosis/txfees/v1beta1/query_pb2_grpc.py (1 hunks)
  • tests/client/chain/grpc/configurable_txfees_query_servicer.py (1 hunks)
  • tests/client/chain/grpc/test_chain_grpc_exchange_api.py (4 hunks)
  • tests/client/chain/grpc/test_chain_grpc_txfees_api.py (1 hunks)
  • tests/core/test_gas_heuristics_gas_limit_estimator.py (1 hunks)
  • tests/core/test_message_based_transaction_fee_calculator.py (7 hunks)
💤 Files with no reviewable changes (1)
  • pyinjective/client/chain/grpc/chain_grpc_token_factory_api.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/core/test_message_based_transaction_fee_calculator.py
  • tests/client/chain/grpc/test_chain_grpc_exchange_api.py
🧰 Additional context used
🧬 Code Definitions (49)
examples/chain_client/exchange/11_MsgCreateDerivativeMarketOrder.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/16_MsgCancelBinaryOptionsOrder.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/authz/3_MsgRevoke.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/1_MsgDeposit.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/2_MsgWithdraw.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/7_MsgCreateSpotMarketOrder.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/ibc/transfer/1_MsgTransfer.py (2)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
pyinjective/core/broadcaster.py (4)
  • update_gas_price (53-59)
  • update_gas_price (337-343)
  • update_gas_price (438-444)
  • update_gas_price (503-509)
examples/chain_client/authz/2_MsgExec.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/bank/1_MsgSend.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/oracle/2_MsgRelayProviderPrices.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/peggy/1_MsgSendToEth.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/10_MsgCreateDerivativeLimitOrder.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/auction/1_MsgBid.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/12_MsgCancelDerivativeOrder.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/1_LocalOrderHash.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/20_MsgIncreasePositionMargin.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/18_MsgExternalTransfer.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/9_MsgBatchUpdateOrders.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/wasm/1_MsgExecuteContract.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/21_MsgRewardsOptOut.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/wasmx/1_MsgExecuteContractCompat.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/8_MsgCancelSpotOrder.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/22_MsgAdminUpdateBinaryOptionsMarket.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/14_MsgCreateBinaryOptionsLimitOrder.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/authz/1_MsgGrant.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/19_MsgLiquidatePosition.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/15_MsgCreateBinaryOptionsMarketOrder.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/oracle/1_MsgRelayPriceFeedPrice.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/staking/1_MsgDelegate.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/exchange/17_MsgSubaccountTransfer.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/tokenfactory/1_CreateDenom.py (2)
pyinjective/async_client.py (3)
  • AsyncClient (83-2572)
  • composer (2330-2337)
  • current_chain_gas_price (2339-2351)
pyinjective/core/broadcaster.py (6)
  • MsgBroadcasterWithPk (62-343)
  • new_using_simulation (82-114)
  • update_gas_price (53-59)
  • update_gas_price (337-343)
  • update_gas_price (438-444)
  • update_gas_price (503-509)
examples/chain_client/tokenfactory/3_MsgBurn.py (2)
pyinjective/async_client.py (3)
  • AsyncClient (83-2572)
  • composer (2330-2337)
  • current_chain_gas_price (2339-2351)
pyinjective/core/broadcaster.py (6)
  • MsgBroadcasterWithPk (62-343)
  • new_using_simulation (82-114)
  • update_gas_price (53-59)
  • update_gas_price (337-343)
  • update_gas_price (438-444)
  • update_gas_price (503-509)
pyinjective/async_client.py (3)
pyinjective/client/chain/grpc/chain_grpc_txfees_api.py (2)
  • ChainGrpcTxfeesApi (10-28)
  • fetch_eip_base_fee (21-25)
pyinjective/client/indexer/grpc/indexer_grpc_portfolio_api.py (1)
  • fetch_account_portfolio_balances (24-30)
pyinjective/core/token.py (2)
  • Token (8-26)
  • convert_value_from_extended_decimal_format (22-23)
tests/core/test_gas_heuristics_gas_limit_estimator.py (3)
pyinjective/async_client.py (1)
  • composer (2330-2337)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (7)
  • BatchUpdateOrdersGasLimitEstimator (332-381)
  • GasHeuristicsGasLimitEstimator (35-92)
  • ExecGasLimitEstimator (480-502)
  • for_message (45-59)
  • gas_limit (62-63)
  • gas_limit (103-112)
  • gas_limit (126-127)
tests/core/test_message_based_transaction_fee_calculator.py (1)
  • basic_composer (30-43)
examples/chain_client/insurance/1_MsgCreateInsuranceFund.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
tests/client/chain/grpc/test_chain_grpc_txfees_api.py (3)
pyinjective/client/chain/grpc/chain_grpc_txfees_api.py (3)
  • ChainGrpcTxfeesApi (10-28)
  • fetch_module_params (15-19)
  • fetch_eip_base_fee (21-25)
tests/client/chain/grpc/configurable_txfees_query_servicer.py (2)
  • ConfigurableTxfeesQueryServicer (6-16)
  • Params (12-13)
pyinjective/proto/injective/txfees/v1beta1/query_pb2_grpc.py (2)
  • Params (32-38)
  • Params (72-96)
examples/chain_client/insurance/3_MsgRequestRedemption.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
examples/chain_client/tokenfactory/5_MsgSetDenomMetadata.py (2)
pyinjective/async_client.py (3)
  • AsyncClient (83-2572)
  • composer (2330-2337)
  • current_chain_gas_price (2339-2351)
pyinjective/core/broadcaster.py (6)
  • MsgBroadcasterWithPk (62-343)
  • new_without_simulation (117-149)
  • update_gas_price (53-59)
  • update_gas_price (337-343)
  • update_gas_price (438-444)
  • update_gas_price (503-509)
examples/chain_client/5_MessageBroadcasterWithoutSimulation.py (2)
pyinjective/async_client.py (4)
  • AsyncClient (83-2572)
  • composer (2330-2337)
  • sync_timeout_height (320-328)
  • current_chain_gas_price (2339-2351)
pyinjective/core/broadcaster.py (6)
  • MsgBroadcasterWithPk (62-343)
  • new_using_simulation (82-114)
  • update_gas_price (53-59)
  • update_gas_price (337-343)
  • update_gas_price (438-444)
  • update_gas_price (503-509)
examples/chain_client/exchange/6_MsgCreateSpotLimitOrder.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
pyinjective/proto/injective/txfees/v1beta1/query_pb2_grpc.py (2)
pyinjective/proto/osmosis/txfees/v1beta1/query_pb2_grpc.py (5)
  • QueryStub (8-21)
  • GetEipBaseFee (27-32)
  • GetEipBaseFee (54-78)
  • QueryServicer (24-32)
  • Query (50-78)
tests/client/chain/grpc/configurable_txfees_query_servicer.py (2)
  • Params (12-13)
  • GetEipBaseFee (15-16)
pyinjective/proto/osmosis/txfees/v1beta1/query_pb2_grpc.py (2)
pyinjective/proto/injective/txfees/v1beta1/query_pb2_grpc.py (6)
  • QueryStub (8-26)
  • GetEipBaseFee (40-45)
  • GetEipBaseFee (99-123)
  • QueryServicer (29-45)
  • add_QueryServicer_to_server (48-64)
  • Query (68-123)
tests/client/chain/grpc/configurable_txfees_query_servicer.py (1)
  • GetEipBaseFee (15-16)
examples/chain_client/txfees/query/1_GetEipBaseFee.py (2)
pyinjective/async_client.py (1)
  • fetch_eip_base_fee (2325-2326)
pyinjective/client/chain/grpc/chain_grpc_txfees_api.py (1)
  • fetch_eip_base_fee (21-25)
examples/chain_client/insurance/2_MsgUnderwrite.py (1)
pyinjective/async_client.py (1)
  • current_chain_gas_price (2339-2351)
pyinjective/core/broadcaster.py (5)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (5)
  • GasHeuristicsGasLimitEstimator (35-92)
  • for_message (45-59)
  • gas_limit (62-63)
  • gas_limit (103-112)
  • gas_limit (126-127)
pyinjective/async_client.py (1)
  • composer (2330-2337)
pyinjective/composer.py (1)
  • Composer (104-1765)
pyinjective/core/network.py (2)
  • string (369-370)
  • Network (106-389)
pyinjective/core/gas_limit_estimator.py (15)
  • GasLimitEstimator (24-81)
  • for_message (34-48)
  • gas_limit (51-52)
  • gas_limit (91-92)
  • gas_limit (107-115)
  • gas_limit (129-134)
  • gas_limit (148-158)
  • gas_limit (172-177)
  • gas_limit (197-242)
  • gas_limit (258-264)
  • gas_limit (278-279)
  • gas_limit (293-294)
  • gas_limit (308-309)
  • gas_limit (326-327)
  • gas_limit (348-349)
pyinjective/client/chain/grpc/chain_grpc_txfees_api.py (3)
pyinjective/proto/injective/txfees/v1beta1/query_pb2_grpc.py (5)
  • QueryStub (8-26)
  • Params (32-38)
  • Params (72-96)
  • GetEipBaseFee (40-45)
  • GetEipBaseFee (99-123)
tests/client/chain/grpc/configurable_txfees_query_servicer.py (2)
  • Params (12-13)
  • GetEipBaseFee (15-16)
pyinjective/async_client.py (1)
  • fetch_eip_base_fee (2325-2326)
examples/chain_client/exchange/23_MsgDecreasePositionMargin.py (2)
pyinjective/async_client.py (2)
  • current_chain_gas_price (2339-2351)
  • composer (2330-2337)
pyinjective/core/broadcaster.py (6)
  • MsgBroadcasterWithPk (62-343)
  • new_using_simulation (82-114)
  • update_gas_price (53-59)
  • update_gas_price (337-343)
  • update_gas_price (438-444)
  • update_gas_price (503-509)
examples/chain_client/permissions/4_MsgClaimVoucher.py (2)
pyinjective/async_client.py (3)
  • AsyncClient (83-2572)
  • composer (2330-2337)
  • current_chain_gas_price (2339-2351)
pyinjective/core/broadcaster.py (6)
  • MsgBroadcasterWithPk (62-343)
  • new_using_simulation (82-114)
  • update_gas_price (53-59)
  • update_gas_price (337-343)
  • update_gas_price (438-444)
  • update_gas_price (503-509)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (1)
pyinjective/core/gas_limit_estimator.py (44)
  • GasLimitEstimator (24-81)
  • applies_to (30-31)
  • applies_to (88-89)
  • applies_to (104-105)
  • applies_to (126-127)
  • applies_to (145-146)
  • applies_to (169-170)
  • applies_to (194-195)
  • applies_to (255-256)
  • applies_to (275-276)
  • applies_to (290-291)
  • applies_to (305-306)
  • applies_to (320-324)
  • applies_to (344-346)
  • for_message (34-48)
  • gas_limit (51-52)
  • gas_limit (91-92)
  • gas_limit (107-115)
  • gas_limit (129-134)
  • gas_limit (148-158)
  • gas_limit (172-177)
  • gas_limit (197-242)
  • gas_limit (258-264)
  • gas_limit (278-279)
  • gas_limit (293-294)
  • gas_limit (308-309)
  • gas_limit (326-327)
  • gas_limit (348-349)
  • message_type (55-60)
  • _message_class (63-64)
  • _message_class (94-96)
  • _message_class (117-118)
  • _message_class (136-137)
  • _message_class (160-161)
  • _message_class (179-180)
  • _message_class (244-245)
  • _message_class (266-267)
  • _message_class (281-282)
  • _message_class (296-297)
  • _message_class (311-312)
  • _message_class (329-334)
  • _message_class (351-353)
  • _parsed_message (66-71)
  • _select_post_only_orders (73-81)
🪛 Ruff (0.8.2)
tests/core/test_gas_heuristics_gas_limit_estimator.py

44-44: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


44-44: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


44-44: Redefinition of unused first_match_bet_market from line 35

(F811)


246-246: Redefinition of unused usdt_token from line 39

(F811)


467-467: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


501-501: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


520-520: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


536-536: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


572-572: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


592-592: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


608-608: Redefinition of unused first_match_bet_market from line 35

(F811)


644-644: Redefinition of unused first_match_bet_market from line 35

(F811)


664-664: Redefinition of unused first_match_bet_market from line 35

(F811)


742-742: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


758-758: Redefinition of unused btc_usdt_perp_market from line 34

(F811)

pyinjective/proto/injective/txfees/v1beta1/query_pb2.py

15-15: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)


16-16: pyinjective.proto.google.api.annotations_pb2 imported but unused

Remove unused import: pyinjective.proto.google.api.annotations_pb2

(F401)


17-17: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2 imported but unused

Remove unused import: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2

(F401)

pyinjective/proto/injective/txfees/v1beta1/txfees_pb2.py

15-15: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)


16-16: pyinjective.proto.google.api.annotations_pb2 imported but unused

Remove unused import: pyinjective.proto.google.api.annotations_pb2

(F401)


17-17: pyinjective.proto.amino.amino_pb2 imported but unused

Remove unused import: pyinjective.proto.amino.amino_pb2

(F401)

pyinjective/proto/injective/txfees/v1beta1/genesis_pb2.py

15-15: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2 imported but unused

Remove unused import: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2

(F401)


16-16: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)

pyinjective/proto/injective/txfees/v1beta1/genesis_pb2_grpc.py

3-3: grpc imported but unused

Remove unused import: grpc

(F401)

pyinjective/proto/injective/txfees/v1beta1/tx_pb2.py

15-15: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)


16-16: pyinjective.proto.cosmos.msg.v1.msg_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos.msg.v1.msg_pb2

(F401)


17-17: pyinjective.proto.cosmos_proto.cosmos_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos_proto.cosmos_pb2

(F401)


18-18: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2 imported but unused

Remove unused import: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2

(F401)


19-19: pyinjective.proto.amino.amino_pb2 imported but unused

Remove unused import: pyinjective.proto.amino.amino_pb2

(F401)

pyinjective/proto/injective/txfees/v1beta1/txfees_pb2_grpc.py

3-3: grpc imported but unused

Remove unused import: grpc

(F401)

pyinjective/proto/osmosis/txfees/v1beta1/query_pb2.py

15-15: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)


16-16: pyinjective.proto.google.api.annotations_pb2 imported but unused

Remove unused import: pyinjective.proto.google.api.annotations_pb2

(F401)


17-17: google.protobuf.duration_pb2 imported but unused

Remove unused import: google.protobuf.duration_pb2

(F401)

🔇 Additional comments (227)
pyinjective/proto/injective/exchange/v1beta1/query_pb2.py (1)

22-595: Protocol buffer update aligns with the PR's gas estimator logic changes.

This update to the generated protobuf file correctly reflects the changes in field serialization positions and options that support the updated gas estimator logic mentioned in the PR description. The modifications are automatically generated and should not be manually edited.

pyinjective/proto/injective/txfees/v1beta1/txfees_pb2_grpc.py (1)

1-4: Auto-generated file looks correct.

This is an auto-generated file by the gRPC Python protocol compiler. The presence of the standard imports is expected even though the file currently has minimal content. Future gRPC service implementations will utilize this module structure.

🧰 Tools
🪛 Ruff (0.8.2)

3-3: grpc imported but unused

Remove unused import: grpc

(F401)

pyinjective/proto/injective/txfees/v1beta1/genesis_pb2.py (1)

1-31: Auto-generated protobuf definition looks correct.

This file properly defines the GenesisState message with its params field, which is essential for the proper initialization of the txfees module. The imports and message descriptors follow standard Protocol Buffers patterns for auto-generated files.

🧰 Tools
🪛 Ruff (0.8.2)

15-15: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2 imported but unused

Remove unused import: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2

(F401)


16-16: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)

pyinjective/async_client.py (5)

16-16: Properly includes necessary txfees API import.

The import of ChainGrpcTxfeesApi is required for the new transaction fee-related functionality.


188-191: Clean initialization of the txfees API client.

The txfees API client is initialized following the same pattern as the other API clients, maintaining code consistency.


2046-2051: Backwards-compatible parameter addition.

The addition of the optional usd parameter to the fetch_account_portfolio_balances method maintains backward compatibility while allowing additional functionality.


2325-2327: Well-structured API method for EIP base fee.

The fetch_eip_base_fee method provides a clean interface to access the EIP base fee data, which is essential for the updated gas estimator.


2339-2352: Robust implementation of dynamic gas price fetching.

This method implements dynamic gas price fetching with proper error handling and fallback to a default value. The decimal conversion is correctly implemented using the Token utility methods.

The method gracefully handles potential failures when querying the chain for gas prices, which is a good defensive programming practice.

pyinjective/proto/injective/txfees/v1beta1/query_pb2.py (1)

1-48: Auto-generated protobuf definitions provide necessary transaction fee APIs.

This file defines the Protocol Buffer messages and gRPC service needed for querying transaction fee parameters and EIP base fees. These definitions properly implement the API interfaces required for the updated gas estimator functionality mentioned in the PR.

🧰 Tools
🪛 Ruff (0.8.2)

15-15: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)


16-16: pyinjective.proto.google.api.annotations_pb2 imported but unused

Remove unused import: pyinjective.proto.google.api.annotations_pb2

(F401)


17-17: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2 imported but unused

Remove unused import: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2

(F401)

pyinjective/core/broadcaster.py (8)

52-59: Well-designed abstract method with clear documentation.

The addition of the update_gas_price abstract method to the TransactionFeeCalculator class is appropriate and follows good design principles. The method signature and docstring clearly indicate the purpose and expected parameters.


151-188: Nice addition of a factory method for gas heuristics.

The new factory method new_using_gas_heuristics provides a convenient way to create a broadcaster that uses the new gas heuristics estimator. This enhances the API's flexibility while maintaining backward compatibility.


263-302: Good pattern consistency for grantee accounts.

The new_for_grantee_account_using_gas_heuristics method maintains consistency with other factory methods while extending the gas heuristics functionality to grantee accounts. The implementation follows the established pattern.


337-344: Appropriate delegator method for updating gas price.

This method provides a public interface for updating the gas price in the broadcaster, properly delegating to the fee calculator implementation. This enhances API usability while maintaining separation of concerns.


448-448: Renamed constant with updated value.

The rename from TRANSACTION_GAS_LIMIT to TRANSACTION_ANTE_GAS_LIMIT with an increased value (from 60,000 to 105,000) better reflects its purpose and aligns with updated gas requirements.


450-461: Enhanced constructor with configurable estimator class.

Adding the estimator_class parameter allows for more flexibility in gas estimation strategies. This change supports the integration of the new gas heuristics estimator while maintaining backward compatibility.


462-466: Convenient factory method for gas heuristics.

The new_using_gas_heuristics class method provides a clean way to create instances configured with the new GasHeuristicsGasLimitEstimator, improving code readability and usability.


503-509: Implementation of abstract method for MessageBasedCalculator.

The implementation of update_gas_price follows the contract defined in the abstract class and properly updates the internal gas price value.

pyinjective/proto/injective/txfees/v1beta1/genesis_pb2_grpc.py (1)

1-4: Auto-generated gRPC file with unused import.

This file is auto-generated by the gRPC Python protocol compiler plugin. The grpc import is flagged as unused by static analysis, but this is common in auto-generated stubs when the file doesn't implement specific service methods. Since this is an auto-generated file, no changes are needed.

🧰 Tools
🪛 Ruff (0.8.2)

3-3: grpc imported but unused

Remove unused import: grpc

(F401)

examples/chain_client/txfees/query/1_GetEipBaseFee.py (2)

8-13: Well-structured example for fetching EIP base fee.

This example demonstrates how to fetch the EIP base fee from the chain, which is necessary for understanding the current gas price. The implementation is clean and follows the established pattern for example scripts.


15-16: Standard entry point for async execution.

Using the event loop's run_until_complete method is the correct approach for running the async function in a synchronous context.

examples/chain_client/exchange/11_MsgCreateDerivativeMarketOrder.py (2)

10-10: Removed static GAS_PRICE import in favor of dynamic retrieval.

The removal of the GAS_PRICE constant import is appropriate since gas price is now retrieved dynamically from the chain.


78-81: Improved gas price handling with dynamic fetching and safety margin.

This change enhances transaction reliability by:

  1. Dynamically fetching the current gas price from the chain
  2. Adding a 10% safety margin to account for price fluctuations between request and broadcast

This approach is more resilient than using a static constant and aligns with the PR objective to update gas estimator logic.

examples/chain_client/oracle/2_MsgRelayProviderPrices.py (2)

8-8: Updated import statement to reflect new dynamic gas pricing.

You've removed GAS_PRICE and kept only GAS_FEE_BUFFER_AMOUNT from the constants import, which aligns with the changes in gas price handling logic.


65-68: Good enhancement to dynamic gas price handling.

The changes properly implement dynamic gas price retrieval with a safety buffer. By fetching the gas price at runtime and applying a 10% increase, you ensure that the transaction remains valid even if gas prices fluctuate between request and broadcast time.

The code now uses client.current_chain_gas_price() which will attempt to query the current on-chain gas price and fall back to a default if needed (as seen in the referenced snippet from async_client.py).

examples/chain_client/exchange/14_MsgCreateBinaryOptionsLimitOrder.py (2)

10-10: Updated import statement to reflect new dynamic gas pricing.

You've removed the GAS_PRICE import and kept only GAS_FEE_BUFFER_AMOUNT from the constants, which aligns with the changes in gas price handling logic.


88-91: Good enhancement to dynamic gas price handling.

The changes properly implement dynamic gas price retrieval with a safety buffer. By fetching the gas price at runtime and applying a 10% increase, you ensure that the transaction remains valid even if gas prices fluctuate between request and broadcast time.

The comment clearly explains the rationale behind the adjustment, which is helpful for maintainability.

examples/chain_client/tokenfactory/4_MsgChangeAdmin.py (6)

2-2: Updated imports to support new functionality.

Added the json module for improved response formatting and switched to the AsyncClient import, which is necessary for the new asynchronous gas price retrieval logic.

Also applies to: 7-7


20-22: Switched to AsyncClient with asynchronous composer initialization.

You've refactored the client initialization to use AsyncClient and retrieve the composer asynchronously, which is better aligned with the SDK's overall design for handling blockchain interactions.


23-25: Good implementation of dynamic gas price retrieval.

The code now fetches the gas price at runtime and adds a 10% buffer to handle potential fluctuations between price retrieval and transaction broadcast time.


27-33: Updated message broadcaster initialization with new parameters.

The message broadcaster now receives the gas price, client, and composer instances, allowing it to use the dynamic gas price and interact with the blockchain through the provided client.


48-48: Improved response formatting with JSON indentation.

Using json.dumps() with indentation makes the transaction response more readable, which is a nice usability improvement.


50-53: Added post-transaction gas price update.

This is a good addition that updates the gas price after broadcasting the transaction, ensuring that the message broadcaster has the latest gas price for any subsequent transactions. This helps maintain transaction validity in a network with fluctuating gas prices.

examples/chain_client/exchange/21_MsgRewardsOptOut.py (2)

8-8: Updated import statement to reflect new dynamic gas pricing.

You've removed GAS_PRICE and kept only GAS_FEE_BUFFER_AMOUNT from the constants import, which aligns with the changes in gas price handling logic.


55-58: Good enhancement to dynamic gas price handling.

The changes properly implement dynamic gas price retrieval with a safety buffer. By fetching the gas price at runtime and applying a 10% increase, you ensure that the transaction remains valid even if gas prices fluctuate between request and broadcast time.

The comment clearly explains the rationale behind the adjustment, which is helpful for maintainability.

examples/chain_client/insurance/2_MsgUnderwrite.py (2)

8-8: Import updates align with new gas price strategy.

The removal of the GAS_PRICE import reflects the shift from using a static constant to dynamically fetching gas prices.


60-63: Dynamic gas price retrieval improves transaction reliability.

The implementation of dynamic gas price fetching via await client.current_chain_gas_price() with a 1.1x multiplier is a good approach that:

  1. Makes the gas price responsive to current network conditions
  2. Adds a safety margin to account for potential fluctuations between request and broadcast time

This change aligns with the PR objective to update gas heuristics.

examples/chain_client/tokenfactory/2_MsgMint.py (7)

2-2: Adding JSON import improves response formatting.

The addition of the json import enables better response formatting later in the code.


7-7: Updated import for AsyncClient.

The import of AsyncClient directly from pyinjective.async_client aligns with the updated client creation approach in this file.


20-22: Client initialization with AsyncClient and composer fetching.

The code now properly initializes the AsyncClient and asynchronously fetches the composer.


23-26: Dynamic gas price retrieval with safety margin.

Similar to other files, implementing dynamic gas price fetching with a 1.1x multiplier improves transaction reliability by adapting to current network conditions.


30-33: Updated message_broadcaster parameters.

The message broadcaster now correctly includes the dynamically calculated gas price, client, and composer.


49-51: Improved transaction response formatting.

Using json.dumps with indentation provides a more readable output format for transaction responses.


52-55: Gas price update after transaction.

Updating the gas price after broadcasting the transaction ensures that subsequent transactions (if any) will use the most recent gas price. This is a good practice that aligns with the dynamic gas price strategy.

examples/chain_client/exchange/1_MsgDeposit.py (2)

8-8: Import updates align with new gas price strategy.

The removal of the GAS_PRICE import reflects the shift from using a static constant to dynamically fetching gas prices.


58-61: Dynamic gas price retrieval improves transaction reliability.

The implementation of dynamic gas price fetching with a 1.1x multiplier ensures:

  1. Gas prices adapt to current network conditions
  2. A safety buffer accounts for price fluctuations between request and broadcast
  3. Transactions remain valid even with minor gas price changes

This change aligns with the PR objective of updating gas estimator logic for fixed exchange gas.

examples/chain_client/bank/1_MsgSend.py (2)

8-8: Import updates align with new gas price strategy.

The removal of the GAS_PRICE import reflects the shift from using a static constant to dynamically fetching gas prices.


60-63: Dynamic gas price retrieval improves transaction reliability.

The implementation of dynamic gas price fetching via await client.current_chain_gas_price() with a 1.1x multiplier is consistent with the changes made in other files. This approach:

  1. Adapts to current network conditions instead of using a static value
  2. Provides a safety margin for gas price fluctuations
  3. Integrates well with the existing gas limit and fee calculation logic

This consistency across files ensures a uniform approach to gas price handling throughout the codebase.

examples/chain_client/auction/1_MsgBid.py (1)

55-58: Good improvement to dynamic gas price handling!

This change improves transaction reliability by fetching the current gas price dynamically from the chain rather than using a fixed constant. The 10% adjustment buffer is a smart addition that helps ensure the transaction remains valid even if gas prices fluctuate slightly between request and broadcast time.

examples/chain_client/authz/3_MsgRevoke.py (1)

60-63: Well-implemented dynamic gas price handling!

This change enhances the transaction process by fetching the current gas price from the chain instead of using a hardcoded value. The 10% safety margin ensures that transactions remain valid despite potential gas price fluctuations between request and broadcast time. This approach will make the application more resilient to network changes.

examples/chain_client/exchange/15_MsgCreateBinaryOptionsMarketOrder.py (1)

76-79: Good implementation of dynamic gas pricing!

This change improves the market order creation process by using real-time gas prices from the chain rather than static constants. The 10% adjustment provides a safety buffer against gas price fluctuations during transaction processing. This approach aligns with best practices for blockchain transaction handling.

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

26-28: Good implementation of dynamic gas pricing!

This change enhances the transaction process by fetching real-time gas prices from the chain instead of using hardcoded values. The 10% adjustment provides a safety buffer for gas price fluctuations during transaction processing.


61-61: Nice improvement to output formatting!

Using json.dumps() with indentation makes the transaction result much more readable and easier to debug.


24-25:

❓ Verification inconclusive

Verify the removal of timeout height synchronization.

The call to await client.sync_timeout_height() has been removed. This method typically ensures transactions have appropriate timeout heights. Please verify this removal is intentional and won't cause transactions to use inappropriate timeout values.


🏁 Script executed:

#!/bin/bash
# Search for other occurrences of sync_timeout_height to see if it's consistently removed
rg "sync_timeout_height" --type py

Length of output: 3751


Confirm the intentional removal of timeout height synchronization in the IBC transfer module.

In examples/chain_client/ibc/transfer/1_MsgTransfer.py, the call to await client.sync_timeout_height() has been removed—even though many other example files continue to invoke it. This change could affect transaction timeout handling if it isn’t compensated by alternative logic. Additionally, please verify that the second gas price update (used after the transaction) is necessary and not redundant. If these differences are deliberate, a brief code comment clarifying the rationale would help prevent confusion in the future.

examples/chain_client/exchange/10_MsgCreateDerivativeLimitOrder.py (1)

10-10: Updated import statements to match the new gas price approach.

The import statement has been updated to remove the static GAS_PRICE constant, supporting the shift to dynamic gas price fetching.

examples/chain_client/exchange/9_MsgBatchUpdateOrders.py (2)

10-10: Updated import statements to match the new gas price approach.

The import statement has been updated to remove the static GAS_PRICE constant, supporting the shift to dynamic gas price fetching.


153-156: Improved gas price handling with dynamic fetching.

The code now dynamically retrieves the current gas price from the chain instead of using a static value, making the application more responsive to current network conditions. The 10% adjustment provides a buffer against price fluctuations during transaction broadcasting.

examples/chain_client/authz/2_MsgExec.py (2)

10-10: Updated import statements to match the new gas price approach.

The import statement has been updated to remove the static GAS_PRICE constant, supporting the shift to dynamic gas price fetching.


82-85: Improved gas price handling with dynamic fetching.

The code now dynamically retrieves the current gas price from the chain instead of using a static value, making the application more responsive to current network conditions. The 10% adjustment provides a buffer against price fluctuations during transaction broadcasting.

examples/chain_client/peggy/1_MsgSendToEth.py (2)

9-9: Updated import statements to match the new gas price approach.

The import statement has been updated to remove the static GAS_PRICE constant, supporting the shift to dynamic gas price fetching.


69-72: Improved gas price handling with dynamic fetching.

The code now dynamically retrieves the current gas price from the chain instead of using a static value, making the application more responsive to current network conditions. The 10% adjustment provides a buffer against price fluctuations during transaction broadcasting.

examples/chain_client/exchange/2_MsgWithdraw.py (2)

8-8: GAS_PRICE import removed in favor of dynamic gas price fetching

The code now dynamically fetches gas prices instead of using a static constant, improving adaptability to network conditions.


56-59: Good improvement: Dynamic gas price calculation with safety buffer

The implementation now fetches the current gas price from the chain and applies a 10% buffer to account for price fluctuations between request time and transaction broadcast. This approach is more resilient to changing network conditions.

examples/chain_client/oracle/1_MsgRelayPriceFeedPrice.py (2)

8-8: GAS_PRICE import removed in favor of dynamic gas price fetching

The code now dynamically fetches gas prices instead of using a static constant, improving adaptability to network conditions.


60-63: Good improvement: Dynamic gas price calculation with safety buffer

The implementation now fetches the current gas price from the chain and applies a 10% buffer to account for price fluctuations between request time and transaction broadcast. This approach is more resilient to changing network conditions.

examples/chain_client/exchange/17_MsgSubaccountTransfer.py (2)

9-9: GAS_PRICE import removed in favor of dynamic gas price fetching

The code now dynamically fetches gas prices instead of using a static constant, improving adaptability to network conditions.


64-67: Good improvement: Dynamic gas price calculation with safety buffer

The implementation now fetches the current gas price from the chain and applies a 10% buffer to account for price fluctuations between request time and transaction broadcast. This approach is more resilient to changing network conditions.

examples/chain_client/exchange/19_MsgLiquidatePosition.py (2)

10-10: GAS_PRICE import removed in favor of dynamic gas price fetching

The code now dynamically fetches gas prices instead of using a static constant, improving adaptability to network conditions.


85-88: Good improvement: Dynamic gas price calculation with safety buffer

The implementation now fetches the current gas price from the chain and applies a 10% buffer to account for price fluctuations between request time and transaction broadcast. This approach is more resilient to changing network conditions.

examples/chain_client/wasm/1_MsgExecuteContract.py (2)

8-8: Import statement updated to remove deprecated constant.

The import statement has been updated to only include GAS_FEE_BUFFER_AMOUNT while removing the GAS_PRICE constant, which aligns with the move to dynamic gas pricing.


70-73: Dynamic gas pricing implementation looks good.

The code now retrieves gas prices dynamically from the chain and applies a 10% buffer to account for price fluctuations between request and broadcast time. This approach is more resilient to changing network conditions than using a static constant.

The implementation correctly:

  1. Fetches current gas price asynchronously
  2. Adds a safety margin (1.1x multiplier)
  3. Ensures the result is an integer for subsequent calculations
pyinjective/proto/injective/txfees/v1beta1/txfees_pb2.py (1)

1-58: Auto-generated protobuf file looks correct.

This is an auto-generated Protocol Buffers file that defines the transaction fees parameters structure. It contains all the necessary fields for handling EIP-based transaction fees and various parameters that control gas price calculations.

The static analysis flagged some unused imports at lines 15-17, but since this is an auto-generated file, we should not modify these imports manually as they might be necessary for the protobuf structure.

🧰 Tools
🪛 Ruff (0.8.2)

15-15: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)


16-16: pyinjective.proto.google.api.annotations_pb2 imported but unused

Remove unused import: pyinjective.proto.google.api.annotations_pb2

(F401)


17-17: pyinjective.proto.amino.amino_pb2 imported but unused

Remove unused import: pyinjective.proto.amino.amino_pb2

(F401)

examples/chain_client/exchange/7_MsgCreateSpotMarketOrder.py (2)

10-10: Import statement updated to remove deprecated constant.

The import statement has been updated to only include GAS_FEE_BUFFER_AMOUNT while removing the GAS_PRICE constant, aligning with the move to dynamic gas pricing.


75-78: Dynamic gas pricing implementation looks good.

The code now retrieves gas prices dynamically from the chain and applies a 10% buffer to account for price fluctuations between request and broadcast time, making transactions more resilient to network changes.

The implementation correctly:

  1. Fetches current gas price asynchronously
  2. Adds a safety margin (1.1x multiplier)
  3. Ensures the result is an integer for subsequent calculations
examples/chain_client/1_LocalOrderHash.py (2)

9-9: Import statement updated to remove deprecated constant.

The import statement has been updated to only include GAS_FEE_BUFFER_AMOUNT while removing the GAS_PRICE constant, aligning with the move to dynamic gas pricing.


115-118: Dynamic gas pricing implemented consistently across all transactions.

The code now consistently retrieves gas prices dynamically from the chain at each transaction point and applies a 10% buffer to account for price fluctuations.

The implementation correctly:

  1. Fetches current gas price asynchronously for each transaction
  2. Adds a safety margin (1.1x multiplier)
  3. Ensures the result is an integer for subsequent calculations

This consistent implementation across multiple transaction blocks in the same file aligns with the PR objective to update gas estimator logic to match on-chain changes to gas heuristics.

Also applies to: 156-159, 252-255

examples/chain_client/insurance/3_MsgRequestRedemption.py (2)

8-8: Import updated to remove GAS_PRICE constant

The code now uses dynamic gas price retrieval instead of the static GAS_PRICE constant, which aligns with the PR objective of updating the gas estimator logic.


60-63:

✅ Verification successful

Dynamic gas price retrieval implementation looks good

The code now dynamically fetches the current chain gas price and applies a 10% buffer to account for gas price fluctuations between request time and transaction broadcast.


🏁 Script executed:

#!/bin/bash
# Check how the current_chain_gas_price method is implemented
grep -A 20 "def current_chain_gas_price" pyinjective/async_client.py

Length of output: 964


Dynamic Gas Price Adjustment Verified

The code in examples/chain_client/insurance/3_MsgRequestRedemption.py correctly retrieves the current chain gas price via await client.current_chain_gas_price() and applies a 10% buffer by multiplying the result by 1.1. Our investigation confirmed that the current_chain_gas_price method (in pyinjective/async_client.py) fetches the chain base fee and gracefully falls back to a default value on error. No further changes are required.

examples/chain_client/exchange/22_MsgAdminUpdateBinaryOptionsMarket.py (2)

9-9: Import updated to remove GAS_PRICE constant

The code now uses dynamic gas price retrieval instead of the static GAS_PRICE constant, which aligns with the PR objective of updating the gas estimator logic.


74-77: Dynamic gas price retrieval implementation looks good

The code now dynamically fetches the current chain gas price and applies a 10% buffer to account for gas price fluctuations between request time and transaction broadcast. This approach is consistent with changes in other example files.

examples/chain_client/distribution/1_SetWithdrawAddress.py (5)

2-2: Added json module for improved output formatting

The json module is now used to format the transaction response output, which improves readability.


21-24: Dynamic gas price retrieval implementation looks good

The code now dynamically fetches the current chain gas price and applies a 10% buffer to account for gas price fluctuations between request time and transaction broadcast.


28-28: Updated MsgBroadcasterWithPk initialization to use dynamic gas price

The message broadcaster now receives the dynamic gas price as a parameter, which aligns with the updated gas estimator logic.


48-48: Improved output formatting with JSON indentation

Transaction response output is now formatted as a JSON string with proper indentation, which improves readability for debugging and logging purposes.


50-53:

✅ Verification successful

Added gas price update after transaction broadcast

The code now updates the gas price in the message broadcaster after the transaction has been broadcast, ensuring that any subsequent transactions use the latest gas price. This is a comprehensive approach to gas price management.


🏁 Script executed:

#!/bin/bash
# Check how the update_gas_price method is implemented in the broadcaster
grep -A 10 "def update_gas_price" pyinjective/core/broadcaster.py

Length of output: 1483


Gas Price Update Implementation Verified

The update to propagate the chain’s current gas price has been verified. The change in examples/chain_client/distribution/1_SetWithdrawAddress.py—which fetches, scales, and then applies the gas price via message_broadcaster.update_gas_price(gas_price=gas_price)—correctly propagates the updated value to the fee calculator. As confirmed by the implementations in pyinjective/core/broadcaster.py, this update ensures that subsequent transactions use the latest gas price.

  • The multiplier (1.1) adjustment is applied before updating, catering for delays between fetching and broadcast.
  • The call to update_gas_price correctly routes to implementations (e.g., in MsgBroadcasterWithPk and MessageBasedTransactionFeeCalculator) that update the gas price in their respective contexts.
examples/chain_client/exchange/12_MsgCancelDerivativeOrder.py (2)

8-8: Import updated to remove GAS_PRICE constant

The code now uses dynamic gas price retrieval instead of the static GAS_PRICE constant, which aligns with the PR objective of updating the gas estimator logic.


62-65: Dynamic gas price retrieval implementation looks good

The code now dynamically fetches the current chain gas price and applies a 10% buffer to account for gas price fluctuations between request time and transaction broadcast. This approach is consistent with changes in other example files.

examples/chain_client/exchange/18_MsgExternalTransfer.py (2)

9-9: Import updated to remove GAS_PRICE constant.

The code now uses the dynamic current_chain_gas_price() method instead of the static GAS_PRICE constant, which is a good improvement for adaptability to network conditions.


64-67: Good implementation of dynamic gas price with safety buffer.

The new code dynamically fetches the current gas price from the chain and applies a 10% buffer to account for price fluctuations between request and broadcast time. This approach is more resilient than using a fixed constant.

examples/chain_client/distribution/2_WithdrawDelegatorReward.py (5)

2-2: Added JSON module for better response formatting.

Good addition to improve response readability by enabling pretty-printing of JSON data.


22-25: Implemented dynamic gas price fetching with buffer.

Good implementation of fetching current gas price from the chain with a 10% safety margin to handle potential price fluctuations.


29-29: Added gas_price parameter to MsgBroadcasterWithPk.

The code now correctly passes the dynamically fetched gas price to the message broadcaster, ensuring it uses current network conditions when calculating fees.


49-49: Improved response formatting with JSON pretty-printing.

Using json.dumps with indentation makes the response more readable for developers, which is a good usability improvement.


51-54: Added gas price update after transaction.

Good practice to update the gas price after transaction completion, especially if the broadcaster will be reused for subsequent transactions. This ensures each transaction uses the most current gas price.

examples/chain_client/wasmx/1_MsgExecuteContractCompat.py (2)

9-9: Import updated to remove GAS_PRICE constant.

The code now uses the dynamic current_chain_gas_price() method instead of the static GAS_PRICE constant, which is a good improvement for adaptability to network conditions.


67-70: Good implementation of dynamic gas price with safety buffer.

The new code dynamically fetches the current gas price from the chain and applies a 10% buffer to account for price fluctuations between request and broadcast time. This approach is more resilient than using a fixed constant.

examples/chain_client/exchange/6_MsgCreateSpotLimitOrder.py (2)

10-10: Import updated to remove GAS_PRICE constant.

The code now uses the dynamic current_chain_gas_price() method instead of the static GAS_PRICE constant, which is a good improvement for adaptability to network conditions.


76-79: Good implementation of dynamic gas price with safety buffer.

The new code dynamically fetches the current gas price from the chain and applies a 10% buffer to account for price fluctuations between request and broadcast time. This approach is more resilient than using a fixed constant.

examples/chain_client/exchange/8_MsgCancelSpotOrder.py (2)

8-8: Updated import statements to align with new gas price approach

The code no longer imports the static GAS_PRICE constant since it's being replaced by a dynamic approach.


62-65: Good implementation of dynamic gas price fetching

This change improves the gas price calculation by:

  1. Dynamically fetching the current gas price from the chain
  2. Adding a 10% buffer to account for price fluctuations between request and broadcast time

This approach is more resilient to chain conditions than using a static constant.

examples/chain_client/distribution/4_FundCommunityPool.py (5)

2-2: Added JSON formatting for improved output readability

The addition of the JSON module allows for better formatting of transaction response data.


22-25: Implemented dynamic gas price fetching with safety buffer

This addition properly fetches the current gas price from the chain and adds a 10% buffer to account for price fluctuations.


29-29: Updated to use dynamic gas price in broadcaster construction

The code now correctly passes the dynamically calculated gas price to the message broadcaster.


49-49: Improved response output formatting

Using JSON formatting with indentation makes the transaction response more readable for developers.


51-54: Added gas price update after transaction broadcast

While this update doesn't affect this specific example (as there are no subsequent transactions), it establishes a good pattern for more complex scenarios where multiple transactions might be broadcast in sequence.

pyinjective/proto/osmosis/txfees/v1beta1/query_pb2.py (1)

1-38: Protocol Buffer generated file aligns with update objectives

This machine-generated Protocol Buffer file adds support for querying EIP base fees, which is essential for the gas price estimation improvements in this PR.

Note: The static analysis warnings about unused imports (lines 15-17) should be ignored as they're required by the Protocol Buffer system even if they appear unused in the generated Python code.

🧰 Tools
🪛 Ruff (0.8.2)

15-15: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)


16-16: pyinjective.proto.google.api.annotations_pb2 imported but unused

Remove unused import: pyinjective.proto.google.api.annotations_pb2

(F401)


17-17: google.protobuf.duration_pb2 imported but unused

Remove unused import: google.protobuf.duration_pb2

(F401)

examples/chain_client/insurance/1_MsgCreateInsuranceFund.py (2)

8-8: Updated import statements to align with new gas price approach

The code no longer imports the static GAS_PRICE constant as it's being replaced by a dynamic approach.


64-67: Good implementation of dynamic gas price fetching

This change improves the gas price calculation by:

  1. Dynamically fetching the current gas price from the chain
  2. Adding a 10% buffer to account for price fluctuations between request and broadcast time

The implementation correctly uses the asynchronous client method and maintains proper error handling through the current_chain_gas_price() method, which falls back to a default value if the chain query fails.

examples/chain_client/exchange/20_MsgIncreasePositionMargin.py (2)

9-9: Import statement updated to reflect gas price changes.

The import statement has been modified to remove the GAS_PRICE constant and keep only GAS_FEE_BUFFER_AMOUNT, since gas price is now fetched dynamically from the chain.


66-69:

✅ Verification successful

Dynamic gas price retrieval implementation looks good.

The code now dynamically fetches the current gas price from the chain instead of using a static constant, which is more responsive to current network conditions. Adding a 10% buffer is a good practice to prevent transaction failures due to gas price fluctuations.

To verify this implementation works across different network conditions, you can run:


🏁 Script executed:

#!/bin/bash
# Check how the dynamic gas price retrieval works under different network loads

# Search for other places where similar dynamic gas price logic is implemented
rg -A 3 "current_chain_gas_price\(\)" --type py

Length of output: 41403


Dynamic Gas Price Retrieval Confirmed

The implementation in examples/chain_client/exchange/20_MsgIncreasePositionMargin.py is consistent with how dynamic gas pricing is handled elsewhere in the codebase. The use of await client.current_chain_gas_price() followed by applying a 10% buffer via int(gas_price * 1.1) is applied uniformly across multiple modules, ensuring responsiveness to network conditions. No further changes are needed.

examples/chain_client/staking/1_MsgDelegate.py (2)

8-8: Import statement updated to reflect gas price changes.

The import statement has been properly modified to remove the GAS_PRICE constant, keeping only GAS_FEE_BUFFER_AMOUNT since gas price is now fetched dynamically.


60-63: Dynamic gas price implementation is appropriate.

The code now dynamically fetches the current gas price from the chain, making it more responsive to network conditions. The 10% adjustment helps account for price fluctuations between retrieval and broadcast time, ensuring transaction validity.

examples/chain_client/authz/1_MsgGrant.py (2)

8-8: Import statement updated to reflect gas price changes.

The import has been correctly updated to remove the static GAS_PRICE constant, keeping only GAS_FEE_BUFFER_AMOUNT.


75-78: Dynamic gas price retrieval implemented correctly.

The implementation correctly fetches the current gas price from the chain and adds a 10% buffer to account for price fluctuations. This approach aligns with the PR objective to update gas estimator logic for fixed exchange gas.

examples/chain_client/exchange/16_MsgCancelBinaryOptionsOrder.py (2)

8-8: Import statement updated appropriately.

The import has been correctly updated to remove the static GAS_PRICE constant, keeping only the necessary GAS_FEE_BUFFER_AMOUNT.


65-68:

❓ Verification inconclusive

Dynamic gas price implementation with appropriate buffer.

The code now dynamically fetches the current gas price and adds a 10% safety buffer, which ensures the transaction remains valid even if gas prices fluctuate shortly after retrieval. This implementation aligns with the updates to the gas estimator logic mentioned in the PR objectives.

To ensure consistent error handling across all implementations:


🏁 Script executed:

#!/bin/bash
# Check for consistent error handling in gas price retrieval

# Look for instances where current_chain_gas_price is called but errors might not be properly handled
rg -A 5 -B 2 "current_chain_gas_price\(\)" --type py | grep -A 3 -i "try|except|error"

Length of output: 88


Dynamic gas price with 10% safety buffer – please verify error handling

The updated code correctly fetches the current gas price and applies a 10% buffer to account for fluctuations. However, our automated search for try/except blocks around the call to client.current_chain_gas_price() did not return any results. This absence might mean that error handling is performed internally within the client method or that it’s missing in this context. Please manually verify that error handling is applied consistently across all usages of current_chain_gas_price() or add the necessary error management where needed.

  • Location: examples/chain_client/exchange/16_MsgCancelBinaryOptionsOrder.py, Lines 65-68
  • Next Step: Confirm that either the current_chain_gas_price() implementation or the calling context robustly handles potential errors.
examples/chain_client/distribution/3_WithdrawValidatorCommission.py (1)

22-25: Gas price adjustment looks good

The addition of dynamic gas price fetching and adjustment is a good improvement. The 10% buffer helps ensure the transaction remains valid even if gas prices fluctuate between request and broadcast.

pyinjective/proto/injective/txfees/v1beta1/tx_pb2.py (1)

1-44: Auto-generated Protobuf file

This file is auto-generated by the Protocol Buffer compiler and should not be manually edited, as indicated by the comment on line 3. The static analysis warnings about unused imports can be safely ignored since they might be needed by the protobuf machinery.

🧰 Tools
🪛 Ruff (0.8.2)

15-15: pyinjective.proto.gogoproto.gogo_pb2 imported but unused

Remove unused import: pyinjective.proto.gogoproto.gogo_pb2

(F401)


16-16: pyinjective.proto.cosmos.msg.v1.msg_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos.msg.v1.msg_pb2

(F401)


17-17: pyinjective.proto.cosmos_proto.cosmos_pb2 imported but unused

Remove unused import: pyinjective.proto.cosmos_proto.cosmos_pb2

(F401)


18-18: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2 imported but unused

Remove unused import: pyinjective.proto.injective.txfees.v1beta1.txfees_pb2

(F401)


19-19: pyinjective.proto.amino.amino_pb2 imported but unused

Remove unused import: pyinjective.proto.amino.amino_pb2

(F401)

examples/chain_client/exchange/25_MsgUpdateDerivativeMarket.py (2)

26-29: Gas price adjustment looks good

The addition of dynamic gas price fetching and adjustment is a good improvement. The 10% buffer helps ensure the transaction remains valid even if gas prices fluctuate between request and broadcast.


30-36: Good updates to the broadcaster initialization

The addition of gas_price, client, and composer parameters to the new_using_simulation method aligns with the PR's objective to update the gas estimator for fixed exchange gas.

examples/chain_client/exchange/13_MsgInstantBinaryOptionsMarketLaunch.py (3)

2-2: Good addition for JSON serialization.

Importing json helps produce more readable output logs.


32-34: Proper inclusion of dynamic parameters.

Passing gas_price, client, and composer into MsgBroadcasterWithPk.new_using_simulation aligns well with the dynamic fee calculation approach.


65-66: Enhanced readability with JSON output.

Printing the transaction response in an indented JSON format improves debugging and clarity for developers.

examples/chain_client/exchange/23_MsgDecreasePositionMargin.py (3)

2-2: JSON import improves logging flexibility.

Integrating json facilitates structured output for transaction responses or debugging data.


32-34: Explicit parameter passing to new_using_simulation.

Specifying gas_price, client, and composer makes the broadcaster more adaptable for dynamic gas fee calculations.


59-60: Neater response output.

Using json.dumps(result, indent=2) is user-friendly for debugging and log inspection.

examples/chain_client/exchange/26_MsgAuthorizeStakeGrants.py (3)

2-2: JSON import for structured logs.

Importing json is helpful for producing cleaner and more parseable output.


33-35: Correct usage of dynamic broadcaster instantiation.

Passing gas_price, client, and composer ensures the broadcaster is fully aware of the latest network configurations.


54-55: Improves debugging clarity.

Printing the transaction result as indented JSON provides more clarity to developers.

examples/chain_client/tokenfactory/3_MsgBurn.py (4)

2-2: Helpful addition for structured output.

Importing json enables printing results with consistent formatting.


7-7: Switching to AsyncClient for chain interactions.

Using AsyncClient is consistent with the asynchronous approach in this codebase, ensuring non-blocking network calls.


30-32: Explicitly passing dynamic parameters.

Including gas_price, client, and composer in the broadcaster instantiation accommodates evolving network conditions.


50-51: Clearer transaction output.

Using JSON formatting for the response log is optimal for debugging and machine parsing.

examples/chain_client/exchange/24_MsgUpdateSpotMarket.py (4)

2-2: Added JSON module for better result formatting.

The addition of the json module enables more readable transaction response output with proper indentation.


26-28: Improved gas price handling with dynamic fetching.

Fetching the current gas price dynamically and applying a 10% buffer improves transaction reliability by accounting for potential gas price fluctuations between request and broadcast time.


33-35: Enhanced MsgBroadcasterWithPk initialization with required parameters.

The updated initialization now correctly passes the dynamically calculated gas price, client, and composer to the broadcaster, which aligns with changes in the broadcaster implementation.


57-57: Improved response formatting with JSON indentation.

Using json.dumps with indentation makes the transaction response more readable for debugging and analysis.

examples/chain_client/tokenfactory/5_MsgSetDenomMetadata.py (6)

2-2: Added JSON module for better result formatting.

The addition of the json module enables more readable transaction response output with proper indentation.


7-7: Switched to AsyncClient for improved asynchronous handling.

Using AsyncClient instead of direct Composer import enables better asynchronous operations and access to dynamic gas pricing.


20-21: Properly initialized AsyncClient and composer.

The initialization creates the client and asynchronously obtains the composer with all required market data.


23-25: Implemented dynamic gas price fetching.

Fetching the current gas price dynamically and applying a 10% buffer improves transaction reliability.


30-33: Updated MsgBroadcasterWithPk initialization with required parameters.

The updated initialization now correctly passes the dynamically calculated gas price, client, and composer to the broadcaster.


64-64: Improved response formatting with JSON indentation.

Using json.dumps with indentation makes the transaction response more readable.

examples/chain_client/exchange/5_MsgInstantExpiryFuturesMarketLaunch.py (5)

2-2: Added JSON module for better result formatting.

The addition of the json module enables more readable transaction response output with proper indentation.


26-28: Implemented dynamic gas price fetching.

Fetching the current gas price dynamically and applying a 10% buffer improves transaction reliability by accounting for potential gas price fluctuations.


33-35: Updated MsgBroadcasterWithPk parameters.

The broadcaster now receives the dynamically calculated gas price, client, and composer parameters, aligning with the updated method signature.


66-67: Improved response formatting with JSON indentation.

Using json.dumps with indentation makes the transaction response more readable for debugging and analysis.


68-71: Added gas price update after transaction broadcast.

This ensures the message broadcaster uses the most current gas price for subsequent transactions, maintaining gas price accuracy over time.

examples/chain_client/3_MessageBroadcaster.py (6)

2-2: Added JSON module for better result formatting.

The addition of the json module enables more readable transaction response output with proper indentation.


9-9: Switched to AsyncClient for improved asynchronous handling.

Using AsyncClient instead of ProtoMsgComposer enables better asynchronous operations and access to dynamic gas pricing functionality.


22-23: Properly initialized AsyncClient and composer.

The initialization creates the client and asynchronously obtains the composer with all required market data.


25-27: Implemented dynamic gas price fetching.

Fetching the current gas price dynamically and applying a 10% buffer improves transaction reliability by accounting for potential gas price fluctuations.


32-34: Updated MsgBroadcasterWithPk initialization with required parameters.

The updated initialization now correctly passes the dynamically calculated gas price, client, and composer to the broadcaster.


77-77: Improved response formatting with JSON indentation.

Using json.dumps with indentation makes the transaction response more readable for debugging and analysis.

examples/chain_client/permissions/2_MsgUpdateNamespace.py (4)

2-2: Import changes align with new functionality.

The addition of the json module import and replacement of Composer with AsyncClient import supports the new asynchronous gas price handling and improved JSON response formatting.

Also applies to: 7-7


19-25: Gas price retrieval and adjustment implementation looks good.

The code now fetches the gas price dynamically from the chain and applies a 10% buffer to account for potential price fluctuations between request and transaction broadcast time. This approach is more robust than using static gas prices.


30-32: Parameters correctly passed to message broadcaster.

The updated MsgBroadcasterWithPk.new_using_simulation method now properly receives the dynamically calculated gas price, client, and composer instances.


88-93: Good practice: Updating gas price after transaction.

The code fetches a fresh gas price after the transaction completes and updates the message broadcaster. This ensures subsequent transactions use current gas prices, which is particularly important in volatile market conditions.

examples/chain_client/permissions/4_MsgClaimVoucher.py (4)

2-2: Import changes align with new functionality.

The addition of the json module import and replacement of the previous composer import with AsyncClient import supports the new asynchronous gas price handling and improved JSON response formatting.

Also applies to: 7-7


19-25: Gas price retrieval and adjustment implementation looks good.

The code now fetches the gas price dynamically from the chain and applies a 10% buffer to account for potential price fluctuations between request and transaction broadcast time. This matches the implementation in other example files and is more robust than using static gas prices.


30-32: Parameters correctly passed to message broadcaster.

The updated MsgBroadcasterWithPk.new_using_simulation method now properly receives the dynamically calculated gas price, client, and composer instances.


49-54: Good practice: Response formatting and gas price update.

The improved JSON formatting makes the transaction response more readable. Additionally, fetching a fresh gas price after the transaction and updating the message broadcaster ensures subsequent transactions use current gas prices.

examples/chain_client/exchange/4_MsgInstantPerpetualMarketLaunch.py (4)

2-2: Import addition aligns with new functionality.

The addition of the json module import supports the improved JSON response formatting.


25-28: Gas price retrieval and adjustment implementation looks good.

The code now fetches the gas price dynamically from the chain and applies a 10% buffer to account for potential price fluctuations between request and transaction broadcast time. This approach is more robust than using static gas prices.


33-35: Parameters correctly passed to message broadcaster.

The updated MsgBroadcasterWithPk.new_using_simulation method now properly receives the dynamically calculated gas price, client, and composer instances.


65-70: Good practice: Response formatting and gas price update.

The improved JSON formatting makes the transaction response more readable. Additionally, fetching a fresh gas price after the transaction and updating the message broadcaster ensures subsequent transactions use current gas prices.

pyinjective/proto/injective/txfees/v1beta1/tx_pb2_grpc.py (1)

1-80: Auto-generated gRPC code looks correct.

This file contains auto-generated gRPC code for the auction message service, particularly for the UpdateParams method. The implementation follows standard gRPC patterns with clearly defined stubs, servicers, and method handlers.

The file includes:

  • MsgStub class for client-side service interaction
  • MsgServicer class with placeholder implementation
  • Helper function to register the service with a gRPC server
  • Experimental API class with static method for making calls

Since this is auto-generated code, no specific improvements are needed.

examples/chain_client/exchange/27_MsgActivateStakeGrant.py (4)

2-2: Added JSON import for improved response formatting.

Added import of the json module to format transaction responses with better readability.


25-27: Dynamic gas price fetching and adjustment.

Good approach to fetch gas prices dynamically and adjust them by a 10% margin to account for potential fluctuations between request and broadcast time.


29-35: Updated broadcasting parameters to include dynamic gas price.

The broadcaster initialization now properly includes the dynamically fetched gas price along with client and composer instances.


51-51: Improved response formatting with JSON.

Enhanced readability of transaction responses by using formatted JSON output.

examples/chain_client/6_MessageBroadcasterWithGranteeAccountWithoutSimulation.py (5)

2-2: Added JSON import for improved response formatting.

Added import of the json module to format transaction responses with better readability.


25-25: Switched to asynchronous composer creation.

Properly using the await keyword to get the composer instance asynchronously from the client.


32-34: Dynamic gas price fetching and adjustment.

Good approach to fetch gas prices dynamically and adjust them by a 10% margin to account for potential fluctuations.


63-63: Improved response formatting with JSON.

Enhanced readability of transaction responses by using formatted JSON output.


36-42:

✅ Verification successful

Method signature change to use simulation-based broadcasting.

The code now uses new_using_simulation instead of new_for_grantee_account_without_simulation, which aligns with the PR objectives to update gas estimator logic.

Since the method has changed from new_for_grantee_account_without_simulation to new_using_simulation, please verify that this change is intentional and that all parameters are correctly mapped.


🏁 Script executed:

#!/bin/bash
# Check the implementation of new_using_simulation in broadcaster.py to confirm it supports grantee accounts
rg -A 15 'def new_using_simulation' pyinjective/core/broadcaster.py

Length of output: 826


Simulation-based Broadcasting Confirmed

The new call to new_using_simulation in
examples/chain_client/6_MessageBroadcasterWithGranteeAccountWithoutSimulation.py
is correct. The method signature in pyinjective/core/broadcaster.py has been verified to accept the parameters network, private_key, gas_price, client, and composer, which are correctly mapped. The switch from new_for_grantee_account_without_simulation to new_using_simulation is intentional and aligns with the PR objectives for updating the gas estimator logic.

  • Verified method definition supports the required parameters.
  • Confirmed alignment with the PR objectives.
pyinjective/proto/osmosis/txfees/v1beta1/query_pb2_grpc.py (1)

1-78: New gRPC service implementation for Osmosis txfees.

This is an auto-generated file by the gRPC Python protocol compiler that adds support for querying EIP base fees from the Osmosis blockchain. The implementation follows the standard gRPC pattern with stub classes, servicers, and method registrations.

The implementation aligns well with the existing Injective txfees implementation as seen in the relevant code snippets from pyinjective/proto/injective/txfees/v1beta1/query_pb2_grpc.py.

examples/chain_client/5_MessageBroadcasterWithoutSimulation.py (4)

2-2: Updated imports for JSON and AsyncClient.

Added JSON import for response formatting and switched to AsyncClient for asynchronous operations.

Also applies to: 9-9


22-24: Implemented asynchronous client and composer initialization.

Properly initializes the AsyncClient and fetches the composer asynchronously, including timeout height synchronization.


26-28: Dynamic gas price fetching and adjustment.

Good approach to fetch gas prices dynamically and adjust them by a 10% margin to account for potential fluctuations.


78-78: Improved response formatting with JSON.

Enhanced readability of transaction responses by using formatted JSON output.

examples/chain_client/exchange/3_MsgInstantSpotMarketLaunch.py (5)

2-2: Good addition of json module for improved output formatting.

Adding the json module allows for better structured and readable transaction response output.


26-28: Good implementation of dynamic gas price fetching.

Fetching the current chain gas price and applying a 1.1 multiplier is a good practice to account for potential price fluctuations between request and broadcast time.


30-36: Well-structured update to message broadcaster initialization.

The parameters have been appropriately updated to include the gas_price, client, and composer as required by the updated method signature.


60-60: Improved transaction response formatting.

Using json.dumps with indentation enhances readability of the transaction response.


62-65: Good practice: Refreshing gas price after transaction.

Updating the gas price after broadcasting ensures subsequent transactions will use current prices, making the code more robust against chain conditions changing during execution.

examples/chain_client/permissions/1_MsgCreateNamespace.py (7)

2-2: Good addition of json module for improved output formatting.

Adding the json module allows for better structured and readable transaction response output.


7-7: Appropriate transition to AsyncClient.

The import has been updated to use AsyncClient, which is more suitable for the asynchronous operations performed in this file.


19-20: Good implementation of asynchronous client initialization.

Replacing the synchronous composer with an async client and awaiting the composer getter is a good practice for asynchronous code.


22-24: Well-implemented dynamic gas price fetching.

Fetching the current chain gas price and applying a 1.1 multiplier is a good practice to account for potential price fluctuations between request and broadcast time.


26-32: Well-structured update to message broadcaster initialization.

The parameters have been appropriately updated to include the gas_price, client, and composer as required by the updated method signature.


105-105: Improved transaction response formatting.

Using json.dumps with indentation enhances readability of the transaction response.


107-110: Good practice: Refreshing gas price after transaction.

Updating the gas price after broadcasting ensures subsequent transactions will use current prices, making the code more robust against chain conditions changing during execution.

pyinjective/client/chain/grpc/chain_grpc_txfees_api.py (5)

1-8: Well-structured imports and module organization.

The imports are properly organized with standard library imports first, followed by external dependencies and internal modules.


10-14: Clean API class implementation with proper dependency injection.

The ChainGrpcTxfeesApi class follows good practices by accepting a channel and cookie assistant through constructor dependency injection, promoting testability and flexibility.


15-19: Well-implemented async method for fetching module parameters.

The fetch_module_params method properly constructs the gRPC request and delegates execution to the helper method, maintaining a clean separation of concerns.


21-25: Well-implemented async method for fetching EIP base fee.

The fetch_eip_base_fee method properly constructs the gRPC request and delegates execution to the helper method, maintaining a clean separation of concerns.


27-28: Effective helper method implementation for gRPC execution.

The private _execute_call method provides good abstraction for the common pattern of executing gRPC calls through the assistant.

tests/core/test_gas_heuristics_gas_limit_estimator.py (7)

1-40: Well-structured test file setup with appropriate imports.

The necessary imports are organized properly, and the test file correctly imports all the required constants and classes for testing the gas limit estimator.


42-58: Well-designed fixture for testing environment setup.

The basic_composer fixture provides a consistent testing environment by initializing a Composer with test market data, which promotes test reliability and consistency.

🧰 Tools
🪛 Ruff (0.8.2)

44-44: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


44-44: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


44-44: Redefinition of unused first_match_bet_market from line 35

(F811)


59-66: Good baseline test for default behavior.

This test validates the gas limit estimation for messages without specific rules, establishing a baseline for the estimator's functionality.


246-299: Well-implemented test for binary options orders.

The test for batch update binary options orders properly creates a test market and validates the gas estimation logic, which is essential for ensuring correct gas estimation for different market types.

🧰 Tools
🪛 Ruff (0.8.2)

246-246: Redefinition of unused usdt_token from line 39

(F811)


302-401: Comprehensive tests for cancel operations.

The tests for cancel operations cover all market types (spot, derivative, binary options) and both individual cancellations and batch cancellations, providing good coverage for these critical operations.


467-809: Thorough test coverage for all transaction types.

The tests cover a wide range of transaction types including limit orders, market orders, cancellations, deposits, withdrawals, transfers, and contract executions, ensuring comprehensive validation of the gas estimation logic.

🧰 Tools
🪛 Ruff (0.8.2)

467-467: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


501-501: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


520-520: Redefinition of unused inj_usdt_spot_market from line 37

(F811)


536-536: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


572-572: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


592-592: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


608-608: Redefinition of unused first_match_bet_market from line 35

(F811)


644-644: Redefinition of unused first_match_bet_market from line 35

(F811)


664-664: Redefinition of unused first_match_bet_market from line 35

(F811)


742-742: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


758-758: Redefinition of unused btc_usdt_perp_market from line 34

(F811)


831-850: Good test coverage for governance and exchange messages.

The tests for governance messages and generic exchange messages ensure that all message types used in the system have appropriate gas limit estimations.

examples/chain_client/permissions/3_MsgUpdateActorRoles.py (5)

2-2: Good transition to AsyncClient and improved output formatting.

The switch from direct Composer import to AsyncClient, along with adding json for response formatting, provides better asynchronous handling and readability of outputs.

Also applies to: 7-7


20-25: Strong improvement with dynamic gas price fetching.

This implementation properly fetches the current gas price from the chain and applies a 1.1x multiplier to account for potential fluctuations between request and broadcast times. This is a more resilient approach than using static gas prices.


30-32: Appropriate parameter updates for message broadcaster.

The message broadcaster now receives the dynamically calculated gas price, client instance, and asynchronously fetched composer, ensuring proper transaction simulation and fee calculation.


68-68: Enhanced response readability with JSON formatting.

Using json.dumps with indentation significantly improves the readability of transaction responses, making it easier to debug and understand the structure of the response.


70-73: Good practice to update gas price after transaction.

Fetching and updating the gas price after broadcasting ensures subsequent transactions will use the most current gas price, which is particularly valuable for scripts that broadcast multiple transactions.

tests/client/chain/grpc/test_chain_grpc_txfees_api.py (4)

1-13: Well-structured test setup with appropriate fixtures.

The test file properly imports necessary components and sets up a fixture for the TxFees query servicer, following good testing practices with pytest.


15-59: Comprehensive test for module parameters.

The test thoroughly verifies the fetch_module_params functionality by:

  1. Creating a parameters object with all relevant fields
  2. Setting up the mock response
  3. Making the API call
  4. Verifying all fields are correctly returned and formatted

This ensures the API correctly handles and maps all fields from the protobuf response.


61-75: Good coverage of EIP base fee fetching.

This test properly verifies that the API correctly retrieves and formats the EIP base fee data, which is essential for the dynamic gas price calculations implemented in the client code.


77-85: Well-implemented API instance helper method.

The _api_instance method creates a properly configured ChainGrpcTxfeesApi for testing, injecting the mock servicer to enable controlled testing of API responses.

examples/chain_client/4_MessageBroadcasterWithGranteeAccount.py (6)

2-2: Good addition of JSON module for response formatting.

Adding the json module allows for better structured and readable transaction responses.


25-25: Proper async composer initialization.

Fetching the composer asynchronously from the client ensures all market and token data is properly loaded before composing messages.


33-35: Well-implemented dynamic gas price calculation.

This change fetches the current gas price from the chain and applies a safety buffer (1.1x) to account for potential price fluctuations during transaction preparation, which makes the transaction more resilient against gas price changes.


40-42: Properly updated broadcaster parameters.

Passing the dynamic gas price, client instance, and composer to the message broadcaster ensures it has all required context for transaction simulation and fee calculation.


65-65: Improved transaction response readability.

Using json.dumps with indentation provides a much more readable output format for complex transaction responses.


67-70: Good practice to refresh gas price after transaction.

Updating the gas price after broadcasting ensures the broadcaster has the most current pricing information for any subsequent transactions, maintaining accuracy over time.

examples/chain_client/tokenfactory/1_CreateDenom.py (5)

2-2: Good transition to AsyncClient with improved output formatting.

The change from Composer to AsyncClient import and addition of json module enables better asynchronous operation and improved response formatting.

Also applies to: 7-7


20-25: Strong improvement with dynamic gas price fetching.

Initializing the client and fetching both composer and gas price asynchronously provides a more accurate representation of current network conditions. The 1.1x multiplier for gas price adds a safety margin to ensure transactions remain valid despite network fluctuations.


30-32: Proper parameter updates for message broadcaster.

Passing the dynamically fetched gas price, client instance, and composer to the message broadcaster ensures it has all the context needed for accurate transaction simulation and fee calculation.


51-51: Enhanced response readability with JSON formatting.

Using json.dumps with indentation significantly improves the readability of transaction responses, making debugging and analysis easier.


53-56: Good practice to refresh gas price after transaction.

Fetching and updating the gas price after broadcasting ensures that the message broadcaster has the most current pricing information for any subsequent operations, maintaining accuracy in a dynamic network environment.

pyinjective/proto/injective/txfees/v1beta1/query_pb2_grpc.py (1)

66-71:

❓ Verification inconclusive

Validate the experimental endpoints.

The static methods in the Query class are marked as part of an experimental API, but they appear production-ready. Confirm that downstream callers (e.g., client code) correctly handle incomplete or experimental features.

Do you want to scan references to these methods in the codebase to ensure they’re either properly guarded by feature flags or used only in experimental contexts?

Also applies to: 98-124


🏁 Script executed:

#!/bin/bash
# Validate references to Query.Params and Query.GetEipBaseFee within the repository
rg "Query\.(Params|GetEipBaseFee)" -A 5

Length of output: 41


Action Required: Verify Downstream Usage of Experimental Query Endpoints

The experimental static endpoints in the Query class (lines 66–71 and 98–124 in pyinjective/proto/injective/txfees/v1beta1/query_pb2_grpc.py) appear production-ready even though they are marked as experimental. In our initial automated search for references to Query.Params and Query.GetEipBaseFee, no matches were found. This lack of output, however, is not conclusive.

  • Manually verify: Please review the codebase (including client calls and integration tests) to confirm that any use of these endpoints is either completely gated behind feature flags or isolated to experimental contexts.
  • Double-check references: Ensure that no downstream callers rely on these endpoints without proper handling for incomplete or experimental functionality.
pyinjective/core/gas_heuristics_gas_limit_estimator.py (2)

14-25: Re-check numeric constants for correctness.

The gas limit constants (e.g., 61_000, 67_000) seem carefully chosen. However, ensure these values accurately mirror on-chain or recommended values, and confirm they're updated to reflect network-level changes over time.

Please confirm with the chain’s official reference documentation or any live config data that these constants match the chain’s expected values.


294-312: Confirm performance impact for large derivative batches.

Batch-level derivative orders use a similar approach to spot orders. For large volumes, computing gas by iterating each item plus post-only logic is direct but might become expensive. Ensure that the final gas limit doesn’t risk overestimation or hamper user experience.

Would you like a shell script to search your test suite for large-order scenario coverage to verify performance constraints?

Comment on lines +5 to +16

class ConfigurableTxfeesQueryServicer(txfees_query_grpc.QueryServicer):
def __init__(self):
super().__init__()
self.params_responses = deque()
self.eip_base_fee_responses = deque()

async def Params(self, request: txfees_query_pb.QueryParamsRequest, context=None, metadata=None):
return self.params_responses.pop()

async def GetEipBaseFee(self, request: txfees_query_pb.QueryEipBaseFeeRequest, context=None, metadata=None):
return self.eip_base_fee_responses.pop()
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for empty deques

The pop() method on deque will raise an IndexError if the deque is empty. Since this servicer is likely used for testing, consider adding error handling to gracefully handle empty deques or ensure they're populated before calling these methods.

async def Params(self, request: txfees_query_pb.QueryParamsRequest, context=None, metadata=None):
-    return self.params_responses.pop()
+    if not self.params_responses:
+        raise ValueError("No params responses configured")
+    return self.params_responses.pop()

async def GetEipBaseFee(self, request: txfees_query_pb.QueryEipBaseFeeRequest, context=None, metadata=None):
-    return self.eip_base_fee_responses.pop()
+    if not self.eip_base_fee_responses:
+        raise ValueError("No EIP base fee responses configured")
+    return self.eip_base_fee_responses.pop()
📝 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. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
class ConfigurableTxfeesQueryServicer(txfees_query_grpc.QueryServicer):
def __init__(self):
super().__init__()
self.params_responses = deque()
self.eip_base_fee_responses = deque()
async def Params(self, request: txfees_query_pb.QueryParamsRequest, context=None, metadata=None):
return self.params_responses.pop()
async def GetEipBaseFee(self, request: txfees_query_pb.QueryEipBaseFeeRequest, context=None, metadata=None):
return self.eip_base_fee_responses.pop()
class ConfigurableTxfeesQueryServicer(txfees_query_grpc.QueryServicer):
def __init__(self):
super().__init__()
self.params_responses = deque()
self.eip_base_fee_responses = deque()
async def Params(self, request: txfees_query_pb.QueryParamsRequest, context=None, metadata=None):
if not self.params_responses:
raise ValueError("No params responses configured")
return self.params_responses.pop()
async def GetEipBaseFee(self, request: txfees_query_pb.QueryEipBaseFeeRequest, context=None, metadata=None):
if not self.eip_base_fee_responses:
raise ValueError("No EIP base fee responses configured")
return self.eip_base_fee_responses.pop()

Comment on lines 254 to 273
class BatchCreateSpotLimitOrdersGasLimitEstimator(GasHeuristicsGasLimitEstimator):
def __init__(self, message: any_pb2.Any):
self._message = self._parsed_message(message=message)

@classmethod
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 += len(self._message.orders) * SPOT_ORDER_CREATION_GAS_LIMIT
total += math.ceil(len(post_only_orders) * POST_ONLY_SPOT_ORDER_CREATION_GAS_LIMIT)

return total

def _message_class(self, message: any_pb2.Any):
return injective_exchange_tx_pb.MsgBatchCreateSpotLimitOrders

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Check batch creation overhead.

When creating a large batch of spot limit orders, the logic increments the gas limit by both the normal creation gas limit and the post-only creation gas limit for post-only orders. Ensure this approach correctly depicts real usage, especially if the cost for partial or multiple post-only orders is more complex than a simple bulk calculation.

Copy link
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: 0

🧹 Nitpick comments (2)
examples/chain_client/5_MessageBroadcasterWithoutSimulation.py (2)

26-28: Consider refactoring duplicated gas price calculation logic.

The same gas price fetching and adjustment logic appears in two places. Consider extracting this into a helper function to improve maintainability.

async def main() -> None:
    # ... existing code ...
+    async def get_adjusted_gas_price():
+        gas_price = await client.current_chain_gas_price()
+        # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
+        return int(gas_price * 1.1)

    # ... existing code ...
-    gas_price = await client.current_chain_gas_price()
-    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-    gas_price = int(gas_price * 1.1)
+    gas_price = await get_adjusted_gas_price()

    # ... existing code ...

    # broadcast the transaction
    result = await message_broadcaster.broadcast([msg])
    print("---Transaction Response---")
    print(json.dumps(result, indent=2))

-    gas_price = await client.current_chain_gas_price()
-    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-    gas_price = int(gas_price * 1.1)
+    gas_price = await get_adjusted_gas_price()
    message_broadcaster.update_gas_price(gas_price=gas_price)

Also applies to: 80-83


22-36: Add error handling for asynchronous operations.

The code lacks error handling for the async calls. Consider adding try/except blocks to gracefully handle potential failures in fetching gas prices or syncing timeout height.

    # select network: local, testnet, mainnet
    network = Network.testnet()

    client = AsyncClient(network)
-    composer = await client.composer()
-    await client.sync_timeout_height()
-
-    gas_price = await client.current_chain_gas_price()
-    # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
-    gas_price = int(gas_price * 1.1)
+    try:
+        composer = await client.composer()
+        await client.sync_timeout_height()
+        
+        gas_price = await client.current_chain_gas_price()
+        # adjust gas price to make it valid even if it changes between the time it is requested and the TX is broadcasted
+        gas_price = int(gas_price * 1.1)
+    except Exception as e:
+        print(f"Error during initialization: {e}")
+        return

    message_broadcaster = MsgBroadcasterWithPk.new_without_simulation(
        network=network,
        private_key=private_key_in_hexa,
        gas_price=gas_price,
        client=client,
        composer=composer,
    )
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 45b98d2 and f675e2a.

📒 Files selected for processing (2)
  • examples/chain_client/5_MessageBroadcasterWithoutSimulation.py (3 hunks)
  • examples/chain_client/6_MessageBroadcasterWithGranteeAccountWithoutSimulation.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/chain_client/6_MessageBroadcasterWithGranteeAccountWithoutSimulation.py
🧰 Additional context used
🧬 Code Definitions (1)
examples/chain_client/5_MessageBroadcasterWithoutSimulation.py (2)
pyinjective/async_client.py (4)
  • AsyncClient (83-2572)
  • composer (2330-2337)
  • sync_timeout_height (320-328)
  • current_chain_gas_price (2339-2351)
pyinjective/core/broadcaster.py (6)
  • MsgBroadcasterWithPk (62-343)
  • new_without_simulation (117-149)
  • update_gas_price (53-59)
  • update_gas_price (337-343)
  • update_gas_price (438-444)
  • update_gas_price (503-509)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: run-tests (3.11, windows-latest)
🔇 Additional comments (4)
examples/chain_client/5_MessageBroadcasterWithoutSimulation.py (4)

9-9: Good implementation of dynamic gas price fetching with AsyncClient.

The code now properly fetches the current gas price from the chain and applies a buffer to handle price fluctuations between request and broadcast time. This is a significant improvement over using static gas prices.

Also applies to: 22-28


30-36: This code now properly matches the filename.

The issue mentioned in the previous review has been resolved. The file is named "WithoutSimulation" and it correctly uses new_without_simulation.


78-78: Good improvement in result formatting.

Using JSON formatting with indentation makes the transaction response much more readable.


80-83: Good practice updating gas price after broadcasting.

Updating the gas price after broadcasting ensures that subsequent transactions will use the most current price. This is particularly important in volatile market conditions.

Copy link
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: 0

🧹 Nitpick comments (2)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (2)

14-34: Remove unused constant.

BASIC_REFERENCE_GAS_LIMIT (line 37) is declared but never used throughout the file. If there is no future plan to utilize it, consider removing it to keep the codebase free of dead code.

-    BASIC_REFERENCE_GAS_LIMIT = 150_000

332-379: Allow dynamic or configurable “cancel all” assumptions.

In BatchUpdateOrdersGasLimitEstimator (lines 332–379), you define a constant AVERAGE_CANCEL_ALL_AFFECTED_ORDERS = 20 (line 333). Consider making this value configurable or determined at runtime if the average is subject to change and can cause over/underestimation of actual gas usage.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 02165b5 and 1418b58.

📒 Files selected for processing (1)
  • pyinjective/core/gas_heuristics_gas_limit_estimator.py (1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (1)
pyinjective/core/gas_limit_estimator.py (50)
  • GasLimitEstimator (24-81)
  • applies_to (30-31)
  • applies_to (88-89)
  • applies_to (104-105)
  • applies_to (126-127)
  • applies_to (145-146)
  • applies_to (169-170)
  • applies_to (194-195)
  • applies_to (255-256)
  • applies_to (275-276)
  • applies_to (290-291)
  • applies_to (305-306)
  • applies_to (320-324)
  • applies_to (344-346)
  • for_message (34-48)
  • gas_limit (51-52)
  • gas_limit (91-92)
  • gas_limit (107-115)
  • gas_limit (129-134)
  • gas_limit (148-158)
  • gas_limit (172-177)
  • gas_limit (197-242)
  • gas_limit (258-264)
  • gas_limit (278-279)
  • gas_limit (293-294)
  • gas_limit (308-309)
  • gas_limit (326-327)
  • gas_limit (348-349)
  • message_type (55-60)
  • _message_class (63-64)
  • _message_class (94-96)
  • _message_class (117-118)
  • _message_class (136-137)
  • _message_class (160-161)
  • _message_class (179-180)
  • _message_class (244-245)
  • _message_class (266-267)
  • _message_class (281-282)
  • _message_class (296-297)
  • _message_class (311-312)
  • _message_class (329-334)
  • _message_class (351-353)
  • _parsed_message (66-71)
  • _select_post_only_orders (73-81)
  • BatchCreateSpotLimitOrdersGasLimitEstimator (99-118)
  • BatchCancelSpotOrdersGasLimitEstimator (121-137)
  • BatchCreateDerivativeLimitOrdersGasLimitEstimator (140-161)
  • BatchCancelDerivativeOrdersGasLimitEstimator (164-180)
  • BatchUpdateOrdersGasLimitEstimator (183-245)
  • ExecGasLimitEstimator (248-267)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: run-tests (3.10, windows-latest)
  • GitHub Check: run-tests (3.9, windows-latest)
🔇 Additional comments (4)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (4)

35-60: Verify the fallback logic to GasLimitEstimator.

When no matching subclass is found, the code falls back to GasLimitEstimator.for_message(message=message) (line 55). Please confirm that this fallback is the intended behavior, as it may bypass heuristics defined in GasHeuristicsGasLimitEstimator subclasses.


95-116: Consider applying a general message overhead.

In CreateSpotLimitOrdersGasLimitEstimator (lines 95–116), only a single constant is used for gas_limit. If you wish to maintain consistency with other estimators that factor an additional overhead (e.g., GENERAL_MESSAGE_GAS_LIMIT), consider adding it here or clarifying why it is excluded.


265-267: Revisit batch spot limit order calculation

As previously noted in another review, adding SPOT_ORDER_CREATION_GAS_LIMIT for each order (line 266) plus an additional POST_ONLY_SPOT_ORDER_CREATION_GAS_LIMIT for post-only orders (line 267) could result in double-counting gas for post-only orders. If this behavior is unintentional, consider using an either/or approach instead of summing both.

 total = 0
-for order in self._message.orders:
-    total += SPOT_ORDER_CREATION_GAS_LIMIT
-    if order.order_type in [injective_exchange_pb.OrderType.BUY_PO, injective_exchange_pb.OrderType.SELL_PO]:
-        total += (POST_ONLY_SPOT_ORDER_CREATION_GAS_LIMIT - SPOT_ORDER_CREATION_GAS_LIMIT)
+for order in self._message.orders:
+    if order.order_type in [injective_exchange_pb.OrderType.BUY_PO, injective_exchange_pb.OrderType.SELL_PO]:
+        total += POST_ONLY_SPOT_ORDER_CREATION_GAS_LIMIT
+    else:
+        total += SPOT_ORDER_CREATION_GAS_LIMIT

481-499: Looks good—minimal overhead for nested messages.

ExecGasLimitEstimator (lines 481–499) correctly sums the gas limits of the nested messages and adds a small overhead (DEFAULT_GAS_LIMIT). This straightforward design appears valid and maintainable.

Copy link
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: 2

🧹 Nitpick comments (2)
pyinjective/async_client.py (2)

273-275: Avoid using __del__ for async cleanup.
Relying on __del__ in Python for releasing async resources may lead to unpredictable behaviors, because object finalization is not guaranteed at a deterministic time. Implement an explicit teardown method or a context manager for better reliability when closing/cleaning up asynchronous tasks.


2346-2359: Dynamic fallback for chain gas price looks good.
The broad try/except is appropriate here, given you want to default back to GAS_PRICE on any error. For more precise debugging, you could consider narrower exception handling (e.g., KeyError) if you suspect specific dictionary access issues.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 1418b58 and 14909ae.

📒 Files selected for processing (1)
  • pyinjective/async_client.py (8 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
pyinjective/async_client.py (3)
pyinjective/client/chain/grpc/chain_grpc_txfees_api.py (2)
  • ChainGrpcTxfeesApi (10-28)
  • fetch_eip_base_fee (21-25)
pyinjective/client/indexer/grpc/indexer_grpc_portfolio_api.py (1)
  • fetch_account_portfolio_balances (24-30)
pyinjective/core/token.py (2)
  • Token (8-26)
  • convert_value_from_extended_decimal_format (22-23)
🔇 Additional comments (7)
pyinjective/async_client.py (7)

16-16: Dependency import looks fine.
This import of ChainGrpcTxfeesApi appears correct and sets the stage for the new fee querying functionality.


38-38: Use of GAS_PRICE for fallback is appropriate.
The import aligns well with your fallback logic in current_chain_gas_price.


188-191: Setting up txfees_api.
No issues found—integration of the ChainGrpcTxfeesApi instance here cleanly ties into the new gas fee querying.


276-279: Channel closure method looks good.
This explicit close_exchange_channel method is a solid approach to release resources safely.


280-283: Consistent channel teardown approach.
This mirrors the same safe closure used elsewhere.


284-287: Safe closure of chain stream channel.
No concerns found; consistent with the other channel closes.


2052-2059: Optional usd parameter integration.
The newly added usd parameter is passed through correctly. Just ensure that upstream usage (if any) aligns with this API change.

Comment on lines +2332 to +2334
async def fetch_eip_base_fee(self) -> Dict[str, Any]:
return await self.txfees_api.fetch_eip_base_fee()

Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Fetching EIP base fee without robust fallback check.
Currently, you assume the response always includes "baseFee". If the chain’s response format changes or is temporarily unavailable, this could cause issues.


🏁 Script executed:

#!/bin/bash
# Description: Verify presence of "baseFee" key in EIP base fee responses across the codebase and protos.

# Searching references to "baseFee" within the proto files or code:
rg -A 5 "baseFee" 

# Inspect if there's any condition where "baseFee" might be missing or omitted
# from the returned dictionary or proto definition.

Length of output: 1175


EIP Base Fee: Enhance Fallback Robustness

The current implementation in pyinjective/async_client.py (lines 2332–2334) directly delegates to self.txfees_api.fetch_eip_base_fee() and later relies on accessing eip_base_fee_response["baseFee"]["baseFee"] without first confirming that these keys exist. Tests in tests/client/chain/grpc/test_chain_grpc_txfees_api.py assume the nested structure ({"baseFee": {"baseFee": ...}}), but if the chain's response shifts—even temporarily—the lack of a pre-validation check could trigger unexpected exceptions.

Actionable Suggestions:

  • Pre-Validation Check: Before attempting to convert the value, verify that both "baseFee" and its nested "baseFee" exist in the response.
  • Fallback Mechanism: If the expected keys are missing, either fetch an alternative default value or return a clearly-defined error response.
  • Enhanced Logging: Update the error logging to provide sufficient context about the missing keys for easier debugging.

Copy link
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: 0

🧹 Nitpick comments (1)
pyinjective/core/broadcaster.py (1)

405-412: Consider logging gas price updates.

Updating the fee calculator’s gas price dynamically is fine, but it might be helpful to log changes for better observability.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 9f2062c and 25b01df.

📒 Files selected for processing (1)
  • pyinjective/core/broadcaster.py (11 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: run-tests (3.10, windows-latest)
🔇 Additional comments (16)
pyinjective/core/broadcaster.py (16)

4-4: No issues with the new import.

Importing Type is appropriate for annotating custom class-based parameters.


13-13: Correct usage of new import.

All references to GasHeuristicsGasLimitEstimator appear consistent.


52-60: Abstract method addition looks good.

The newly introduced update_gas_price method and docstring are clear and consistent with the rest of the interface.


86-102: Docstring additions are consistent.

The docstring explaining optional custom gas price parameters is clear and ensures users understand the chain-formatted integer input.


121-145: Comprehensive docstring for non-simulation setup.

These lines properly document the new optional gas_price parameter and maintain consistency with the rest of the code.


146-183: New class method aligns well with gas heuristics.

The logic neatly instantiates a MessageBasedTransactionFeeCalculator with heuristics. No issues found.


185-207: New method for estimated gas configuration.

This block mirrors the non-simulation approach while allowing an optional gas price override. Implementation is consistent.


229-246: Expanded docstring for grantee account simulation.

The approach properly reuses the simulated fee calculator with an optional gas price. Good clarity.


265-290: Grantee account setup without simulation.

All parameters and docstrings are consistent with the high-level design. No concerns.


291-329: Heuristics-based gas for grantee accounts.

This mirrors the standard logic for a different account configuration. Code remains consistent.


331-370: Estimated gas mode for grantee accounts.

Implementation follows the established pattern, introducing an optional gas price parameter and docstring clarity.


506-513: Gas price updater in simulated fee calculator.

This aligns with the abstract method requirement and supports real-time adjustments.


516-539: Check higher ante gas limit's impact on fees.

Raising TRANSACTION_ANTE_GAS_LIMIT from 60,000 to 105,000 may cause higher fees overall. Confirm that this remains acceptable for users.

You can verify via unit/integration tests or by simulating various transactions to ensure fees stay within expected bounds.


546-548: Ante gas limit addition is structurally sound.

No issues with summing the heuristic-based message gas limit and the ante gas limit.


570-574: Estimator instantiation.

The approach to retrieve a suitable estimator instance per message is flexible and maintainable.


575-582: Method completes the abstract interface.

Implementation of update_gas_price matches the new abstract contract.

@aarmoa aarmoa merged commit c8a30f5 into dev Apr 8, 2025
12 of 13 checks passed
Copy link
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: 0

♻️ Duplicate comments (1)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (1)

254-273: Revisit the batch creation overhead
This calculation for batch creation of spot limit orders splits post-only vs. normal orders, but it revisits a prior concern about potentially overestimating gas when mixing partial or multiple post-only orders. Please verify that the line 267 usage of math.ceil for each post-only order is the intended behavior.

🧹 Nitpick comments (3)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (3)

14-32: Consider consolidating constants into a single reference
These constants spread across lines 14–32 can become cumbersome to maintain if more order types are added in the future. Centralizing them in a dictionary or config file would simplify updates and keep the codebase more organized.


35-93: Add docstrings to improve clarity
The abstract class GasHeuristicsGasLimitEstimator and its methods lack explanatory docstrings. Adding short docstrings would help other developers quickly understand each method’s purpose and usage.


484-507: Consider unifying with existing ExecGasLimitEstimator
This implementation mirrors the aggregator logic in gas_limit_estimator.py for MsgExec. Consider refactoring to avoid code duplication and to ensure consistent logic for new message types.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between 25b01df and 104d176.

📒 Files selected for processing (1)
  • pyinjective/core/gas_heuristics_gas_limit_estimator.py (1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (1)
pyinjective/core/gas_limit_estimator.py (45)
  • GasLimitEstimator (24-81)
  • applies_to (30-31)
  • applies_to (88-89)
  • applies_to (104-105)
  • applies_to (126-127)
  • applies_to (145-146)
  • applies_to (169-170)
  • applies_to (194-195)
  • applies_to (255-256)
  • applies_to (275-276)
  • applies_to (290-291)
  • applies_to (305-306)
  • applies_to (320-324)
  • applies_to (344-346)
  • for_message (34-48)
  • gas_limit (51-52)
  • gas_limit (91-92)
  • gas_limit (107-115)
  • gas_limit (129-134)
  • gas_limit (148-158)
  • gas_limit (172-177)
  • gas_limit (197-242)
  • gas_limit (258-264)
  • gas_limit (278-279)
  • gas_limit (293-294)
  • gas_limit (308-309)
  • gas_limit (326-327)
  • gas_limit (348-349)
  • message_type (55-60)
  • _message_class (63-64)
  • _message_class (94-96)
  • _message_class (117-118)
  • _message_class (136-137)
  • _message_class (160-161)
  • _message_class (179-180)
  • _message_class (244-245)
  • _message_class (266-267)
  • _message_class (281-282)
  • _message_class (296-297)
  • _message_class (311-312)
  • _message_class (329-334)
  • _message_class (351-353)
  • _parsed_message (66-71)
  • _select_post_only_orders (73-81)
  • ExecGasLimitEstimator (248-267)
🔇 Additional comments (2)
pyinjective/core/gas_heuristics_gas_limit_estimator.py (2)

95-116: Spot limit estimator logic is correct
The approach for distinguishing between post-only and standard spot limit orders aligns with the rest of the file. Nice job.


332-386: Confirm correctness of average cancel-all multiplier
The AVERAGE_CANCEL_ALL_AFFECTED_ORDERS = 20 constant may not accurately reflect real-world usage if user behavior differs significantly. Consider verifying via production data or adjusting if necessary.

@aarmoa aarmoa deleted the CP-235/update_gas_estimator_for_fixed_exchange_gas branch April 8, 2025 12:03
aarmoa added a commit that referenced this pull request Apr 16, 2025
* fix: renamed fetch_subaccount_orders_list to fetch_derivative_subaccount_orders_list

* Cp 235/update gas estimator for fixed exchange gas (#375)

* feat: updated changelog and version number for v1.9.0 release

* fix: updated the oracle stream prices script to send the oracle type always in lowercase

* fix: added quantization in the functions that convert notional values to chain format

* cp-235: updated the gas limit estimator logic to reflect the new logic for gas heuristics in exchange module (chain v1.15)

* cp-235: updated all proto definitions with the candidate indexer and chain core versions for v1.15 chain upgrade

* feat: added a new message based fee calculator supporting the Exchange module gas heuristics

* fix: fix broadcaster creation example scripts

* fix: pointed to the correct injective-core branch for the proto generation

* fix: updated gas heuristics per message gas cost to sync with latest changes on chain

* fix: added cleanup code in AsyncClient for the object destruction phase

* feat: updated proto definitions for chain v1.15 upgrade and Indexer v1.14.48

* feat: made the gas calculator using gas heuristics the default one for the MsgBroadcasterWithPk when broadcasting without simulation

* fix: fixed gas calculation using heuristics to not duplicate the required gas for post only orders

* fix: updated chain version to v1.15 and indexer version to v1.15.6
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.

1 participant