Web3.py: waitForTransactionReceipt Data Type String Error

Created on 26 Jul 2020  路  4Comments  路  Source: ethereum/web3.py

  • Version: 5.6.0
  • Python: 3.7.4
  • OS: win
  • pip freeze output

What was wrong?

The issue is when doing w3.eth.waitForTransactionReceipt('0x1234....',10) what happens is that it gives back the following error:
TypeError: Unsupported type: The primitive argument must be one of: bytes,bytearray, int or bool and not str
In case the transaction is not yet mined, because the hash datatype is a string...
However, in case the transaction is not pending and is included in the block, the receipt is returned correctly with no error, despite the hash being of datatype string...

How can it be fixed?

I'm not sure, but just giving the timeout error I suppose is fine and simplifies the coding.. As I'm using bytes.fromhex....

Just one question thought, I am currently using the below

            try:
                #Await confirmation for x seconds
                txHash = bytes.fromhex(pendingTX.targetHash[2:])
                sendTX.awaitTxConfirmation(txHash,30)
            except Exception as e:
                #an exception is thrown in case more than x
                #seconds passed and still the tx is not on chain
                if 'is not in the chain' in str(e):
                    #Need to check if the same transaction is still waiting processing


                else:
                    #exit while loop since transaction is confirmed
                    break

Is there a better way to catch the timeout error, instead of using the if 'is not the chain'....?

Most helpful comment

Ah, got it. Thanks for clearing that up.

the first two waitForTransactionReceipt functions give back different errors from the same hash depending whether the transaction hash fed is hexstr of bytes.

You're getting two different error messages because we do param normalization before we send the request, so if the params you're passing aren't valid, the code will error out with a TypeError before we send the JSON-RPC request.

Is there a better way to do this, using the same waitForTransactionReceipt?

I would catch the TimeExhausted error, rather than the very broad Exception, then you don't have to filter for 'is not in the chain' in the error message. The only place we raise TimeExhausted in the code base is in the waitForTransactionReceipt. Also worth noting that the default timeout is 120 seconds, but I imagine you changed it to 5 just for this example.

I'll close this issue since I don't see any web3 bugs, but feel free to reopen if this response doesn't answer your questions!

All 4 comments

@kaleb-keny I'm not sure what the question is here, can you clarify?

w3.eth.sendTransaction and w3.eth.sendRawTransaction both should return Hexbytes. How are you getting the transaction hash? I am also not sure what 'is not in the chain' supposed to be in the second part of your question. If you can provide a minimum reproducible code snippet, that will probably the fastest way to help you debug.

@kclowes Hey thank you for your reply...so please find below a reproducible code which just need an infura key.

import web3
infuraKey  = 'XXXXXXXXXXXXXXXXXXXXXXXXX'
infuraLink = 'https://kovan.infura.io/v3/'+infuraKey
kovanProvider = web3.HTTPProvider(infuraLink )
w3 = web3.Web3(kovanProvider)
txHash = '0x9acd709abe83d6a0c8343c5e06e22602308e01e5c85cf24508a5688abf85656a'
txHashBytes = bytes.fromhex(txHash[2:])

w3.eth.waitForTransactionReceipt(transaction_hash=txHash,
                                 timeout=5)

#TypeError: Unsupported type: The primitive argument must be one of: bytes,bytearray, int or bool and not str

w3.eth.waitForTransactionReceipt(transaction_hash=txHashBytes,
                                 timeout=5)

#TimeExhausted: Transaction 0x9acd709abe83d6a0c8343c5e06e22602308e01e5c85cf24508a5688abf85656a is not in the chain, after 5 seconds

try:
    w3.eth.waitForTransactionReceipt(transaction_hash=txHashBytes,
                                     timeout=5)
except  Exception as e:
    if "is not in the chain" in str(e):
        print("caught")

So the first thing I noticed, as you can see if the transaction is not on chain, the first two waitForTransactionReceipt functions give back different errors from the same hash depending whether the transaction hash fed is hexstr of bytes. I would favor having only one error, the timeout error, for both, as both functions work perfectly whether the input is hexstr, or hex. But it's ok, maybe just wanted your opinion on why the throwback error was designed this way.

So my second question is that I am using a try-catch as you can see above, to catch an error where a transaction "is not in the chain" . Is there a better way to do this, using the same waitForTransactionReceipt?

Ah, got it. Thanks for clearing that up.

the first two waitForTransactionReceipt functions give back different errors from the same hash depending whether the transaction hash fed is hexstr of bytes.

You're getting two different error messages because we do param normalization before we send the request, so if the params you're passing aren't valid, the code will error out with a TypeError before we send the JSON-RPC request.

Is there a better way to do this, using the same waitForTransactionReceipt?

I would catch the TimeExhausted error, rather than the very broad Exception, then you don't have to filter for 'is not in the chain' in the error message. The only place we raise TimeExhausted in the code base is in the waitForTransactionReceipt. Also worth noting that the default timeout is 120 seconds, but I imagine you changed it to 5 just for this example.

I'll close this issue since I don't see any web3 bugs, but feel free to reopen if this response doesn't answer your questions!

When I run this example using a hex string, I get a TypeError thrown after handling the TimeExhausted error. This TypeError does not occur when I use a bytes array instead of a hex string. It only ocurrs when the transaction is not mined before for the timeout.

This seems like a bug, since the documentation shows you can use a hexstring, not just a txHashBytes

Was this page helpful?
0 / 5 - 0 ratings