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

[BUG] estimate_fee_sync always fails with TRANSACTION_FAILED #181

Closed
Pet3ris opened this issue Jun 2, 2022 · 11 comments
Closed

[BUG] estimate_fee_sync always fails with TRANSACTION_FAILED #181

Pet3ris opened this issue Jun 2, 2022 · 11 comments
Labels
question Further information is requested

Comments

@Pet3ris
Copy link

Pet3ris commented Jun 2, 2022

Python version

3.9.12

Expected Behavior

estimate_fee_sync should successfully complete

Current Behavior

It returns the following error:

{"code": "StarknetErrorCode.TRANSACTION_FAILED", "message": "Error at pc=0:392:\nUnknown value for memory cell at address 12:0.\nCairo traceback (most recent call last):\nUnknown location (pc=0:534)\nUnknown location (pc=0:468)"}

Possible Solution

Steps to Reproduce

(nonce,) = keeper_contract.functions["get_nonce"].call_sync()
task_address_felt = int(task["address"], 16)
args, signature = get_account_message_args_sig(keeper_address, registry, "executeTask", [task_address_felt], nonce, key)
unsigned_invocation = keeper_contract.functions["execute"].prepare(*args)

# This is where the error occurs
estimation = unsigned_invocation.estimate_fee_sync()

# This normally runs perfectly fine if I don't do gas estimation for all these transactions that are failing with `estimate_fee`
invocation = unsigned_invocation.invoke_sync(signature=signature, max_fee=0)

FYI - I'm using an older version of an account contract to issue transactions but I'm assuming that this should not impact estimate fee as the other starknet.py apis are working fine?

Context (Environment)

I've been using the excellent starknet.py library to power Yagi Keepers (http://www.yagi.fi/automation).
I'm trying to upgrade keepers now to use fees on testnet before they are officially mandated.

Detailed Description

Possible Implementation

@cptartur
Copy link
Member

cptartur commented Jun 2, 2022

I've tried to replicate using both testnet and devnet using a simple balance contract I've deployed through cairo-lang CLI (I don't have the access to a contract you're using but I don't think that matters), but unfortunately/fortunately it works on my side. Intentionally changing parts of the prepared invoke function caused multiple errors but no like the one you provided.

Parhaps older account contract actually is an issue? In starknet.py 0.8.0 we've changed the way we're signing transactions to reflect changes made in the cairo-lang library itself. The way estimate_fee works it first has to construct the same InvokeFunction as invoke creates, but with signature=None and then passes it to estimate fee feeder gateway endpoint.

Or this may be an issue with contract/calldata/something but it's hard for me to speculate.

@cptartur cptartur added the question Further information is requested label Jun 2, 2022
@Pet3ris
Copy link
Author

Pet3ris commented Jun 2, 2022

Thanks so much @cptartur for the attempts to repro, I think I see what you mean - let me redeploy the latest account contract and I'll report back the findings!

@Pet3ris
Copy link
Author

Pet3ris commented Jun 3, 2022

Unfortunately this didn't fix it, can I add you to my repo to have a look? Promise it's not super complex/nested at all :)

@cptartur
Copy link
Member

cptartur commented Jun 6, 2022

Hey, I'd prefer if we kept this discussion here. Have you tried making the same calls are you trying to do in code through starknet CLI? Are they successful?

The error you've posted is from starknet, just forwared through starknet.py. There's of course a chance we have some bug in starknet.py code that's causing this but we'd need more details to verify it though.

Perhaps the ABI you're using to create a Contract instance isn't correct and that's why you don't get any errors in code but do on starknet?

@Solpatium
Copy link
Contributor

@Pet3ris can you create a full repro showing your issue detached from your codebase? Ideally it would include deploying a simple contract before interacting with it.

@Pet3ris
Copy link
Author

Pet3ris commented Jun 23, 2022

Hey @cptartur @Solpatium - thanks a lot for your guidance, I've done the above and created a separate repository to show how I'm using starknet.py.

The code and readme is available below:
https://github.com/Pet3ris/gas-estimation-example

FYI - I'm running gas estimation on a transaction that succeeds as an invoke with the same arguments, so I think the issue is not in the ABI but rather there is some behavioral difference between estimation and invocation.

@Solpatium
Copy link
Contributor

@Pet3ris thank you for preparing a repro, it allowed us to find the issue - PreparedFunctionCall had no way of passing the signature. Usually AccountClient is used with Contract and it signs the tx automatically, but when using a bare Client that doesn't happen. This is why we couldn't reproduce it. We added a signature parameter to estimate_fee.
Fix: #217
It was already included in the latest release: https://github.com/software-mansion/starknet.py/releases/tag/0.3.4-alpha. Make sure you add your signature when calling estimate_fee.

Apart from that, I suggest using AccountClient instead of bare Client when sending txs. It hides signing and offers a higher-level api :)

@Pet3ris
Copy link
Author

Pet3ris commented Jun 24, 2022

Legends @Solpatium !

@Pet3ris
Copy link
Author

Pet3ris commented Jun 24, 2022

@Solpatium - I updated starknet.py to latest version but it's unfortunately still failing with the same error. Is there any other change I need to make in terms of how I'm using Client for this to work? I also tried to upgrade the openzeppelin account contract to latest and compiling it with 0.9.0 with no luck.

@cptartur
Copy link
Member

Are you providing the same signature to Contract.estimate_fee() as you'd be using in Contract.invoke()?
It's

# create my_signature signature somehow
estimate = my_invoke.estimate_fee_sync(signature=my_signature)

@Pet3ris
Copy link
Author

Pet3ris commented Jun 24, 2022

That fixed it thanks (and makes sense)!

@Pet3ris Pet3ris closed this as completed Jun 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants