cadence icon indicating copy to clipboard operation
cadence copied to clipboard

Inconsistent storage paths

Open LanfordCai opened this issue 2 years ago • 3 comments

Issue to be solved

The storage iteration API will now skip any broken values in the storage(https://github.com/onflow/cadence/pull/2202), but the storagePaths will still return the paths with broken values. For example, run the script below:

  pub fun main(address: Address): [Int] {
    let account = getAuthAccount(address)
    let pathsA: [StoragePath] = []
    account.forEachStored(fun (path: StoragePath, type: Type): Bool {
        pathsA.append(path)
        return true
    })

    let pathsB = account.storagePaths
    return [pathsA.length, pathsB.length]
  }

Command: flow scripts execute ./scripts/get_paths.cdc 0x7cf208094b12fdb8 --network=testnet

The result is: [47, 54]

Suggested Solution

Also skip broken values in account.storagePaths to make the behaviour of APIs consistent

LanfordCai avatar Jan 16 '23 04:01 LanfordCai

Thank you for pointing out this inconsistency. I'm not sure if the paths should actually be skipped like for the iterator function, as there, items are only skipped, because their type is unavailable.

If we were to change the behaviour, it would be a breaking change, so should target Stable Cadence.

turbolent avatar Jan 16 '23 16:01 turbolent

Workaround is to use the iterator - fix this inconsistency in Cadence 1.0, maybe by removing storagePaths fields?

j1010001 avatar Jan 26 '23 22:01 j1010001

Workaround is to use the iterator - fix this inconsistency in Cadence 1.0, maybe by removing storagePaths fields?

The iterator may hit the storage interaction limit, an example:

script 1:

  pub fun main(address: Address): [StoragePath] {
    let account = getAuthAccount(address)
    let paths: [StoragePath] = []
    account.forEachStored(fun (path: StoragePath, type: Type): Bool {
        paths.append(path)
        return true
    })

    return paths
  }

script 2:

  pub fun main(address: Address): [StoragePath] {
    let account = getAuthAccount(address)
    return account.storagePaths
  }

command:

flow scripts execute ./scripts/get_paths.cdc 0x34b57a6391ed7130 --network=mainnet

Script 1 will raise an error:

❌ Invalid argument: failed to execute script: failed to execute script at block (98f9b7cd3fd0f1440248592abe2a74666dd89157b5b731cb005ee3b71e27049b): [Error Code: 1106] error caused by: fatal error: storage error: get value failed: [Error Code: 1106] max interaction with storage has exceeded the limit (used: 20042875 bytes, limit 20000000 bytes) 

and script 2 can return normally.

So I don't think it is good to remove storagePaths

And there is also similar problem in publicPaths

LanfordCai avatar Jan 27 '23 02:01 LanfordCai