terra.py icon indicating copy to clipboard operation
terra.py copied to clipboard

tx_infos_by_height() messages giving multiple amounts under a single transaction

Open benfriedman opened this issue 2 years ago • 6 comments

  • terra_sdk version: 2.0.5
  • Python version: 3.10
  • Operating System: Windows 11

Description

Want to check the latest block for msgSend transactions and filter for large amounts:

What I Did

while(True):
     sleep(10)
     for tx in self.terra.tx.tx_infos_by_height():
            	if type(tx.body.messages[0]) == terra_proto.cosmos.bank.v1beta1.MsgSend: 
            		print(tx.body)
            		print('')
            		print(tx.body.messages[0].amount)
            		print('')

Sometimes my responses have multiple amounts! Example: TxBody(messages=[MsgSend(from_address='terra1gvwvrjrpyxur5ck36qt8ue27dyq0fxmjy7kjfq', to_address='terra19cgtslwzdqyhgdqzu03kwl6pf0jj383ffmjmv4', amount=[Coin(denom='uusd', amount='300000'), Coin(denom='uusd', amount='1'), Coin(denom='uusd', amount='5000000'), Coin(denom='uusd', amount='1000000'), Coin(denom='uusd', amount='300000')])], memo='', timeout_height=0)

Why is it feeding me a list of amounts? I check a transaction on the Terra Station UI and it shows one amount. Is this expected behavior?

benfriedman avatar Apr 29 '22 07:04 benfriedman

could you try v2.0.6?

Vritra4 avatar Apr 30 '22 11:04 Vritra4

Tried, it did work better, although now this tx_infos_by_height() intermittently fails with the following error:

terra_sdk.exceptions.LCDResponseError: Status 400 - {'code': 3, 'message': 'tx (79B5B68B218A5E61F0369D69C5019AABC27494D0D0F6C590AED13816087C100C) not found: invalid request', 'details': []}

I can close and make a new issue if it's better, or elaborate on the frequency of these errors.

benfriedman avatar May 04 '22 22:05 benfriedman

is this error still occurring? i've tested this sdk with a block containing the tx and works fine.

Vritra4 avatar May 06 '22 00:05 Vritra4

If you put it in a loop to run every 5 seconds you'll get this error. Here's the code:

` from time import sleep from terra_sdk.client.lcd.params import APIParams, PaginationOptions from terra_sdk.client.lcd import LCDClient

terra = LCDClient(chain_id="columbus-5", url="https://lcd.terra.dev")

while(True): print('starting loop') sleep(5) for tx in terra.tx.tx_infos_by_height(): print(tx) print('') `

and after running this for a minute or so:

Traceback (most recent call last): File ".\get_tx_info_by_height.py", line 14, in <module> for tx in terra.tx.tx_infos_by_height(): File "C:\ProgramData\Anaconda3\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 29, in decorator return instance._run_sync(async_call(instance, *args, **kwargs)) File "C:\ProgramData\Anaconda3\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 13, in _run_sync return self._c.loop.run_until_complete(coroutine) File "C:\Users\bensf\AppData\Roaming\Python\Python37\site-packages\nest_asyncio.py", line 81, in run_until_complete return f.result() File "C:\ProgramData\Anaconda3\lib\asyncio\futures.py", line 181, in result raise self._exception File "C:\ProgramData\Anaconda3\lib\asyncio\tasks.py", line 249, in __step result = coro.send(None) File "C:\ProgramData\Anaconda3\lib\site-packages\terra_sdk\client\lcd\api\tx.py", line 379, in tx_infos_by_height return [await BaseAsyncAPI._try_await(self.tx_info(tx_hash)) for tx_hash in hashes] File "C:\ProgramData\Anaconda3\lib\site-packages\terra_sdk\client\lcd\api\tx.py", line 379, in <listcomp> return [await BaseAsyncAPI._try_await(self.tx_info(tx_hash)) for tx_hash in hashes] File "C:\ProgramData\Anaconda3\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 29, in decorator return instance._run_sync(async_call(instance, *args, **kwargs)) File "C:\ProgramData\Anaconda3\lib\site-packages\terra_sdk\client\lcd\api\_base.py", line 13, in _run_sync return self._c.loop.run_until_complete(coroutine) File "C:\Users\bensf\AppData\Roaming\Python\Python37\site-packages\nest_asyncio.py", line 81, in run_until_complete return f.result() File "C:\ProgramData\Anaconda3\lib\asyncio\futures.py", line 181, in result raise self._exception File "C:\ProgramData\Anaconda3\lib\asyncio\tasks.py", line 249, in __step result = coro.send(None) File "C:\ProgramData\Anaconda3\lib\site-packages\terra_sdk\client\lcd\api\tx.py", line 140, in tx_info res = await self._c._get(f"/cosmos/tx/v1beta1/txs/{tx_hash}") File "C:\ProgramData\Anaconda3\lib\site-packages\terra_sdk\client\lcd\lcdclient.py", line 316, in _get result = await super()._get(*args, **kwargs) File "C:\ProgramData\Anaconda3\lib\site-packages\terra_sdk\client\lcd\lcdclient.py", line 124, in _get raise LCDResponseError(message=str(result), response=response) terra_sdk.exceptions.LCDResponseError: Status 400 - {'code': 3, 'message': 'tx (0754520E60EEE7A94C813E1567358A0513A31B80A69F64AAFABB3E315A78B391) not found: invalid request', 'details': []}

benfriedman avatar May 08 '22 04:05 benfriedman

oh it comes from asynced nodes behind load balancer for public lcd i guess. :( let me find out what i can do.

Vritra4 avatar May 08 '22 05:05 Vritra4

this should be handled in your implementation, it's a basic retry on fail scenario

some example untested code:

height = 1

while True:
    try:
        txs = terra.tx.tx_infos_by_height(height)
        for tx in txs:
            # do something
        height += 1
    except Exception:
        print(f"retrying height {height}")
    sleep(1)

etienne-napoleone avatar Jul 24 '22 17:07 etienne-napoleone

closing with etienne's solution. please feel free to reopen it if you want.

Vritra4 avatar Sep 23 '22 09:09 Vritra4