Skip to content
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

Feat/injective spot with delegation #6493

Merged

Conversation

aarmoa
Copy link
Contributor

@aarmoa aarmoa commented Jul 19, 2023

Before submitting this PR, please make sure:

  • Your code builds clean without any errors or warnings
  • You are using approved title ("feat/", "fix/", "docs/", "refactor/")

A description of the changes proposed in the pull request:
Implementation of a new Injective spot connector.
The new connector does not require Gateway (pure Python connector) and has been implemented to trade with delegated accounts (ie: the trading account trades in representation of a granter account, that is the one having the funds).
The current connector implementation does not support market orders (only limit and limit maker). Market orders support will be added in a future version.

In order to use delegated accounts to trade it is necessary to perform a gran onchain. To send the grant transaction please use the script file hummingbot/connector/exchange/injective_v2/account_delegation_script.py.

NOTE:
There is a problem with the dYdX library. It has very hard restrictions on the possible versions to use for web3, forcing the whole Hummingbot project to use an old version of that library and all other crypto related libraries required by web3 in place. Taking into account that it is critical for any crypto project to use the most updated library versions for security reasons, the restrictions imposed by dydx-v3-python are not acceptable. I think the only solutions the Hummingbot project has are:

  • Take the code the dYdX connector needs from the library into the connector itself, to not depend on the library
  • Remove the dYdX connector until the dYdX team starts maintaining their library properly

In this PR, to solve the library issue and allow the use of newer web3 versions, I changed environment.yml file to point to the branch of a PR sent already to the dYdX library project that solves the issue (dydxprotocol/dydx-v3-python#202). The PR was created in march in all this time the team has not merged it (and they don't show any intentions to merge it in the near future).

Tests performed by the developer:
Created unit tests for all new components.
Tested the connector by running pure market making strategies.

Tips for QA testing:
Configure a delegate trading account and teste the connector using spot strategies.

PRP: https://snapshot.org/#/hbot-prp.eth/proposal/0xaf8fa07fbd40c0e92fed0b220c922b1f08416e2e8443e3dfd625ed30c89b6416

abel added 19 commits July 11, 2023 15:47
…e use of a very old web3 library version, incompatible with Injective SDK library
…e use of a very old web3 library version, incompatible with Injective SDK library
@aarmoa aarmoa force-pushed the feat/injective_spot_with_delegation branch from d64ece6 to cdb5e36 Compare July 19, 2023 04:36
@rapcmia rapcmia requested review from rapcmia and nikspz July 31, 2023 13:38
@rapcmia
Copy link
Contributor

rapcmia commented Aug 1, 2023

PR update:

  • Ran connect now displays injective_v2
    image
  • Tried to connect injective_v2 however we are still looking how we can get the trading subaccount index and granter account with dev and Injective support on discord (waiting for response)
    image

We also observe this behavior when it is on idle or switched to other window, it would return a error parsing on the background resulting on a distorted display

image

Screen.Recording.2023-08-01.at.10.14.59.AM.mov

Steps to reproduce:

  1. Start the client and switch terminal or to another window for couple of minuts
  2. Go back to the client again and see error parsing
  3. Error not available on logs

@keithbaum
Copy link
Contributor

@rapcmia This is induced by errors coming from stderr when grpc library throws exceptions (host unavailable or rate limit) and it breaks the UI. Solution I found to this is to redirect stderr to /dev/null

Try running the command you run to start hummingbot like so:
./bin/hummingbot.py 2>/dev/null

This is not related to malfunction of the connector itself but the grpc lib which is the same used by the original injective connector (and which produced the same glitches in previous QA unfortunately)

@rapcmia
Copy link
Contributor

rapcmia commented Aug 2, 2023

Thanks for the info @keithbaum, ill check this with the team 🙇🏼


PR update:

  • Able to connect injective_v2 wallet ✅
  • However for account_delegation_script after filling the required values of the script and using mainnet im getting the error below
    image
    (hummingbot) rapcmia@mishka injective_v2 % python account_delegation_script.py
    E0802 14:20:08.254235000 6183514112 hpack_parser.cc:991]               Error parsing 'content-type' metadata: invalid value
    Traceback (most recent call last):
      File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/account_delegation_script.py", line 84, in <module>
        asyncio.get_event_loop().run_until_complete(main())
      File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
        return future.result()
      File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/account_delegation_script.py", line 58, in main
        (sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
      File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/site-packages/pyinjective/async_client.py", line 341, in simulate_tx
        metadata = await self.load_cookie(type="chain")
      File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/site-packages/pyinjective/async_client.py", line 256, in load_cookie
        metadata = await self.renew_cookie(self.chain_cookie, type)
      File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/site-packages/pyinjective/async_client.py", line 231, in renew_cookie
        expires_at = cookie.get(f"{self.cookie_type}").get("expires")
    AttributeError: 'NoneType' object has no attribute 'get'
    (hummingbot) rapcmia@mishka injective_v2 %
    
  • For testnet getting the error below:
    (hummingbot) rapcmia@mishka injective_v2 % python account_delegation_script.py
    <AioRpcError of RPC that terminated with:
       status = StatusCode.UNKNOWN
       details = "grantee and granter should be different With gas wanted: '0' and gas used: '10296' "
       debug_error_string = "UNKNOWN:Error received from peer ipv4:34.138.231.254:443 {grpc_message:"grantee and granter should be different With gas wanted: \'0\' and gas used: \'10296\' ", grpc_status:2, created_time:"2023-08-02T14:29:55.642778+08:00"}"
    >
    (hummingbot) rapcmia@mishka injective_v2 %
    

Steps to reproduce:

  1. Add the required values for the script
  2. Run python account_delegation_script.py

@aarmoa
Copy link
Contributor Author

aarmoa commented Aug 2, 2023

Regarding the first issue @rapcmia (AttributeError: 'NoneType' object has no attribute 'get'), check if in the directory that was the working directory when you executed the command there is a file named .chain_cookie. If there is please remove it. The file is generated when you connect to one network, but if you connected first to testnet, you can't then connect to mainnet without removing the file (of if you connected first to mainnet you can't connect to testnet then without removing it)

@aarmoa
Copy link
Contributor Author

aarmoa commented Aug 2, 2023

For the second error, the error message is already describing the problem grantee and granter should be different.
Please double check that you are using different accounts for granter and grantee.

@rapcmia
Copy link
Contributor

rapcmia commented Aug 3, 2023

Hi @aarmoa thanks for the help.
I am able to delegate on testnet and seems to be successful 635EA19B1DA15. Also ok to connect wallet on the client using a portofolio and trading account.
image

However when we start the PMM strategy we are getting failed to submit order with the error below:

2023-08-03 14:25:22,243 - 21826 - hummingbot.connector.exchange.injective_v2.injective_v2_exchange.InjectiveV2Exchange - NETWORK - Error submitting buy LIMIT_MAKER order to Injective_v2_testnet for 2.00000000 ATOM-USDT 8.604.
Traceback (most recent call last):
  File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_data_source.py", line 334, in create_orders
    result = await self._send_in_transaction(message=delegated_message)
  File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_data_source.py", line 633, in _send_in_transaction
    simulation_result = await self.query_executor.simulate_tx(tx_byte=signed_transaction_data)
  File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_query_executor.py", line 143, in simulate_tx
    response, success = await self._sdk_client.simulate_tx(tx_byte=tx_byte)
  File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/site-packages/pyinjective/async_client.py", line 341, in simulate_tx
    metadata = await self.load_cookie(type="chain")
  File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/site-packages/pyinjective/async_client.py", line 256, in load_cookie
    metadata = await self.renew_cookie(self.chain_cookie, type)
  File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/site-packages/pyinjective/async_client.py", line 231, in renew_cookie
    expires_at = cookie.get(f"{self.cookie_type}").get("expires")
AttributeError: 'NoneType' object has no attribute 'get'
  • It seems to return the same error as on the previous comment so we tried to delete the .chain_cookie as well still no avail
  • Tried different market IDs available getting the same result {ATOM-USDT,WETH-USDT}

Steps to reproduce:

  1. Run account_delegation_script and check the txn to confirm granter and grantee
  2. Setup PMM using injective_v2 testnet then start. Observe behavior

logs_pmm-injective_v2-02.log


When running the script for mainnet, getting stream removed error
image

Steps to reproduce:

  • Add required values for the config for granter and grantee
  • Run python account_delegation_script then issue occurred

Copy link
Contributor

@cardosofede cardosofede left a comment

Choose a reason for hiding this comment

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

Good job King Kode!

@cardosofede
Copy link
Contributor

@aarmoa I forgot to mention that you need to add the connector to connector_status

@cardosofede
Copy link
Contributor

Regarding the first issue @rapcmia (AttributeError: 'NoneType' object has no attribute 'get'), check if in the directory that was the working directory when you executed the command there is a file named .chain_cookie. If there is please remove it. The file is generated when you connect to one network, but if you connected first to testnet, you can't then connect to mainnet without removing the file (of if you connected first to mainnet you can't connect to testnet then without removing it)

Is possible to add a check in the connect command to remove if it exists?

@aarmoa
Copy link
Contributor Author

aarmoa commented Aug 3, 2023

Regarding the first issue @rapcmia (AttributeError: 'NoneType' object has no attribute 'get'), check if in the directory that was the working directory when you executed the command there is a file named .chain_cookie. If there is please remove it. The file is generated when you connect to one network, but if you connected first to testnet, you can't then connect to mainnet without removing the file (of if you connected first to mainnet you can't connect to testnet then without removing it)

Is possible to add a check in the connect command to remove if it exists?

Hi @cardosofede. I will add this as part of the logic in the PR we will be submitting as soon as this is merged. It will be easier that way because in the other branch we have made several changes to the logic that initializes the Injective AsyncClient and the path of the cookie file

@aarmoa
Copy link
Contributor Author

aarmoa commented Aug 3, 2023

Hi @aarmoa thanks for the help. I am able to delegate on testnet and seems to be successful 635EA19B1DA15. Also ok to connect wallet on the client using a portofolio and trading account. image

However when we start the PMM strategy we are getting failed to submit order with the error below:

2023-08-03 14:25:22,243 - 21826 - hummingbot.connector.exchange.injective_v2.injective_v2_exchange.InjectiveV2Exchange - NETWORK - Error submitting buy LIMIT_MAKER order to Injective_v2_testnet for 2.00000000 ATOM-USDT 8.604.
Traceback (most recent call last):
  File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_data_source.py", line 334, in create_orders
    result = await self._send_in_transaction(message=delegated_message)
  File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_data_source.py", line 633, in _send_in_transaction
    simulation_result = await self.query_executor.simulate_tx(tx_byte=signed_transaction_data)
  File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_query_executor.py", line 143, in simulate_tx
    response, success = await self._sdk_client.simulate_tx(tx_byte=tx_byte)
  File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/site-packages/pyinjective/async_client.py", line 341, in simulate_tx
    metadata = await self.load_cookie(type="chain")
  File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/site-packages/pyinjective/async_client.py", line 256, in load_cookie
    metadata = await self.renew_cookie(self.chain_cookie, type)
  File "/Users/rapcomia/anaconda3/envs/hummingbot/lib/python3.10/site-packages/pyinjective/async_client.py", line 231, in renew_cookie
    expires_at = cookie.get(f"{self.cookie_type}").get("expires")
AttributeError: 'NoneType' object has no attribute 'get'
  • It seems to return the same error as on the previous comment so we tried to delete the .chain_cookie as well still no avail
  • Tried different market IDs available getting the same result {ATOM-USDT,WETH-USDT}

Steps to reproduce:

  1. Run account_delegation_script and check the txn to confirm granter and grantee
  2. Setup PMM using injective_v2 testnet then start. Observe behavior

logs_pmm-injective_v2-02.log

When running the script for mainnet, getting stream removed error image

Steps to reproduce:

  • Add required values for the config for granter and grantee
  • Run python account_delegation_script then issue occurred

The only way to solve the issue you mention is to remove the .chain_cookie file.

Regarding the issue with the delegation script in mainnet, try changing the following lines:
NETWORK = Network.mainnet("sentry3")
and
client = AsyncClient(NETWORK, insecure=True)

@rapcmia
Copy link
Contributor

rapcmia commented Aug 4, 2023

PR update:

  • Test latest commit dddf40e15808f3fa0bfd8c6b8
  • Setup account_delegation for testnet/mainnet ✅

Ran test on injective_v2 testnet

However there are instances of errors on fetching status of order and normally fix itself on the next order cycle
image

  • There are instances that when this happens and stopped the client, there were orders left on the exchange:
    • Tried to start the strategy again see if it can recognized but it created a new set of orders again. Then stopped the strategy and was able to the orders created but not the stuck orders on exchange
    • Tried to relaunch the client but still it did not able to recognize the previous orders

Steps to reproduce:

  1. Setup injective_v2 testnet on PMM
  2. When the error happen while creating orders, stop the strategy then start again
  3. Observe that orders are left on the exchange
    • Another good sample to reproduce this issue is by enabling hanging orders

6493.zip


Ran test on injective_v2 mainnet

  • Run account_delegation_script and add {INJ/USDT, ATOM/USDT}
  • Advised by dev to use and change lines 10 and 29 then run the script
    image
    image
  • Setup PMM using INJ-USDT
    image
    • While trying to create order it now return an error of Stream removed
    • Tried to clear the .chain_cookie if this helps but no go
    • Tried to check if changing from sentry3 to {sentry1, sentry 0} but no go:
      • accidentally found this error when setting up account_delegation script so we tried to use it too but same results
        image
    2023-08-04 12:23:38,096 - 5028 - hummingbot.strategy.pure_market_making.pure_market_making - INFO - (INJ-USDT) Creating 1 bid orders at (Size, Price): ['1.5 INJ, 8.024 USDT']
    2023-08-04 12:23:38,097 - 5028 - hummingbot.strategy.pure_market_making.pure_market_making - INFO - (INJ-USDT) Creating 1 ask orders at (Size, Price): ['1.5 INJ, 8.187 USDT']
    2023-08-04 12:23:39,053 - 5028 - pyinjective.composer.Composer - INFO - Loaded market metadata for: 'Mainnet Spot INJ/USDT'
    2023-08-04 12:23:39,054 - 5028 - pyinjective.composer.Composer - INFO - Loaded market metadata for: 'Mainnet Spot INJ/USDT'
    2023-08-04 12:23:40,738 - 5028 - hummingbot.connector.exchange.injective_v2.injective_v2_exchange.InjectiveV2Exchange - NETWORK - Error submitting buy LIMIT_MAKER order to Injective_v2 for 1.500000000000000000 INJ-USDT 8.024.
    Traceback (most recent call last):
      File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_data_source.py", line 334, in create_orders
        result = await self._send_in_transaction(message=delegated_message)
      File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_data_source.py", line 633, in _send_in_transaction
        simulation_result = await self.query_executor.simulate_tx(tx_byte=signed_transaction_data)
      File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_query_executor.py", line 145, in simulate_tx
        raise RuntimeError(f"Transaction simulation failure ({response})")
    RuntimeError: Transaction simulation failure (<AioRpcError of RPC that terminated with:
        status = StatusCode.UNKNOWN
        details = "Stream removed"
        debug_error_string = "UNKNOWN:Error received from peer  {grpc_message:"Stream removed", grpc_status:2, created_time:"2023-08-04T12:23:40.737475+08:00"}"
    >)
    2023-08-04 12:23:40,739 - 5028 - hummingbot.connector.exchange.injective_v2.injective_v2_exchange.InjectiveV2Exchange - WARNING - Failed to submit buy order to Injective_v2. Check API key and network connection.
    2023-08-04 12:23:40,740 - 5028 - hummingbot.connector.exchange.injective_v2.injective_v2_exchange.InjectiveV2Exchange - NETWORK - Error submitting sell LIMIT_MAKER order to Injective_v2 for 1.500000000000000000 INJ-USDT 8.187.
    Traceback (most recent call last):
      File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_data_source.py", line 334, in create_orders
        result = await self._send_in_transaction(message=delegated_message)
      File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_data_source.py", line 633, in _send_in_transaction
        simulation_result = await self.query_executor.simulate_tx(tx_byte=signed_transaction_data)
      File "/Users/rapcomia/github/hummingbot/6493/hummingbot/connector/exchange/injective_v2/injective_query_executor.py", line 145, in simulate_tx
        raise RuntimeError(f"Transaction simulation failure ({response})")
    RuntimeError: Transaction simulation failure (<AioRpcError of RPC that terminated with:
        status = StatusCode.UNKNOWN
        details = "Stream removed"
        debug_error_string = "UNKNOWN:Error received from peer  {grpc_message:"Stream removed", grpc_status:2, created_time:"2023-08-04T12:23:40.737475+08:00"}"
    >)
    2023-08-04 12:23:40,740 - 5028 - hummingbot.connector.exchange.injective_v2.injective_v2_exchange.InjectiveV2Exchange - WARNING - Failed to submit buy order to Injective_v2. Check API key and network connection.
    

Steps to reproduce:

  1. Run delegation script and confirm if successful
  2. Setup simple PMM with injective_v2 mainnet
  3. Start the strategy and observe the behavior

logs_pmm-injective_v2-mainnet.log

@aarmoa
Copy link
Contributor Author

aarmoa commented Aug 4, 2023

  • In Injective the orders are identified buy the "order hash". The order hash is generated based on the order's data and a particular element of the subaccount called the nonce. The nonce is a number that changes as the subaccount operates. The Injective connector has to estimate locally what is going to be the orders' hash, by estimating the changes to the nonce counter. But if at any point the nonce in the bot is not correctly synchronized with the nonce in the chain, the estimated hashes will be incorrect. At this point the connector will re-synchronize the nonce number, but the orders already created in the exchange will have to be manually cancelled by the user, because the connector does not know the orders' hashes.
    This is not an issue in the connector, it is a known limitation.

  • Regarding the "stream removed" error, this happens when the node used to operate is overloaded. That can happen when using the public nodes. To avoid this situation the user should be running its own node. The connector handles these disconnections correctly and recovers. It should not be considered an error.

  • I could not understand the error you mentioned happened when you tried to make the bot use "sentry0", "sentry1" and "sentry3". This is not configurable in the bot. Could you describe the steps you took to do this configuration?

@cardosofede cardosofede merged commit 914c71c into hummingbot:development Aug 4, 2023
2 checks passed
@aarmoa aarmoa deleted the feat/injective_spot_with_delegation branch August 4, 2023 16:19
@aarmoa aarmoa mentioned this pull request Aug 4, 2023
2 tasks
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.

None yet

5 participants