flow-emulator
flow-emulator copied to clipboard
Regression: getting "storage used is not initialized or not initialized correctly" error when trying to borrow or check capability on non existent account
Instructions
Please fill out the template below to the best of your ability and include a label indicating which tool/service you were working with when you encountered the problem.
Problem
<what is the problem you've encountered?>
Getting an error when executing a script that tries to borrow or check capability on an account that hasn't be created yet:
failed to update storage used by key #7075626c6963 on account 0000000000000000: account 0000000000000000 storage used is not initialized or not initialized correctly
This wasn't erroring before (on emulator v0.26.0) but errors on v0.29.0.
Steps to Reproduce
<share any logs/screenshots or steps to replicate>
Repro using this script with arg 0x0 (or any non existing account):
import LockedTokens from 0xf8d6e0586b0a20c7
pub fun main(address : Address) {
let account = getAccount(address)
let cap = account.getCapability<&LockedTokens.TokenHolder{LockedTokens.LockedAccountInfo}>(LockedTokens.LockedAccountInfoPublicPath)
cap.check()
}
The same error also happens with similar calls like FlowStakingCollection.doesAccountHaveStakingCollection which also tries to borrow a capability
Acceptance Criteria
This should not error to keep the behavior of the previous version. Alternatively, there should be some API to check if an account exists (returning a bool) or someway to catch this specific error in case we want to ignore it.
Context
<what are you currently working on that this is blocking?> I want to check balances of various addresses, and if they don't exist just return 0. Is there a workaround? Is checking that the account's storageCapacity is greater than 0 a good idea or any other recommendation?
Thank you for the report, this is interesting, will take a look and report back.
additionally, accessing account.storageUsed also causes an error:
failed to submit executable script: client: rpc error: code = Unknown desc = [Error Code: 1101] cadence runtime error Execution failed:
error: getting storage used failed: account 0000000000000000 storage used is not initialized or not initialized correctly
--> 79802cd6e2945636fd595e3b4d53ac3721c8b907976856cb79cbef484f8b8ff1:5:3
|
5 | if account.storageUsed > 0 {
| ^
@assaf-anchor can you also reproduce the same bug on testnet?
looks like it's also happening on testnet for storageUsed
$ cat script.cdc
pub fun main(): UInt64 {
let account = getAccount(0x0)
let i = account.storageUsed
return i
}
$ curl -H 'Content-type: application/json' -d '{"script":"'$(cat script.cdc | base64 -w 0)'", "arguments":[]}' https://rest-testnet.onflow.org/v1/scripts
{
"code": 400,
"message": "Invalid Flow argument: failed to execute the script on the execution node execution-5f6c73a22445d7d958c6a37c1f3be99c72cacd39894a3e46d6647a9adb007b4d@execution-001.devnet33.nodes.onflow.org:3569=100: rpc error: code = InvalidArgument desc = failed to execute script: failed to execute script at block (dfc373f193364a7f69943139daef274522cd27a60774f3daf73b924a1db4e725): [Error Code: 1101] cadence runtime error Execution failed:\nerror: getting storage used failed: account 0000000000000000 storage used is not initialized or not initialized correctly\n --\u003e 989f55d70b5a6e27f78b39055078c9895a2a29f3c66ede7cae8b642092d98756:3:3\n |\n3 | let i = account.storageUsed\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"
}
However, for capability check it doesn't error on testnet
import LockedTokens from 0x95e019a17d0e23d7
pub fun main() {
let account = getAccount(0x0)
let cap = account.getCapability<&LockedTokens.TokenHolder{LockedTokens.LockedAccountInfo}>(LockedTokens.LockedAccountInfoPublicPath)
cap.check()
}
$ curl -H 'Content-type: application/json' -d '{"script":"'$(cat script.cdc| base64 -w 0)'", "arguments":[]}' https://rest-testnet.onflow.org/v1/scripts
"eyJ0eXBlIjoiVm9pZCJ9Cg=="
I see. Well, the fact this fails is OK but I think the confusing part is the error description (I believe the address returned is just an empty address). It might be how Cadence handles a failure when fetching a capability. Just to double-check I will ping @turbolent from Cadence.
Tracked here: https://github.com/onflow/flow-go/issues/3387