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

Error auto updating storage for an agent using the default storage config #1763

Closed
DJHunn39 opened this issue Feb 14, 2024 · 10 comments
Closed

Comments

@DJHunn39
Copy link

DJHunn39 commented Feb 14, 2024

I'm in the process of migrating a number of agents from @aries-framework 0.4.x to @credo-ts 0.5.x-alpha.y - I've commented on #1569 regarding an issue backing up postgres backends but this is a separate issue, as the default storage config uses sqlite.

2 of these agents, both of which are part of react-native applications, run into an error when automatically updating their storage, during the backup step. Both agents use the default storage config (i.e walletConfig.storage is undefined).

The short version of the error is:

ERROR  [StorageUpdateError: Error updating storage (updateIdentifier: 1707910790588): Error exporting wallet '{WALLET LABEL}': this.store.copyTo is not a function (it is undefined)]

And here is the full error:

Full error + stack (wallet label & app ID redacted)
ERROR  ERROR: Error updating storage (updateIdentifier: 1707910790588) {
  "cause": {
    "name": "WalletError",
    "message": "Error exporting wallet '{WALLET LABEL}': this.store.copyTo is not a function (it is undefined)",
    "stack": "WalletError: Error exporting wallet '{WALLET LABEL}': this.store.copyTo is not a function (it is undefined)\n    at ?anon_0_ (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:489710:85)\n    at next (native)\n    at asyncGeneratorStep (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:28298:26)\n    at _next (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:28317:29)\n    at tryCallOne (/Users/distiller/react-native/packages/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:53:16)\n    at anonymous (/Users/distiller/react-native/packages/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:139:27)\n    at apply (native)\n    at anonymous (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:34928:26)\n    at _callTimer (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:34807:17)\n    at _callReactNativeMicrotasksPass (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:34852:17)\n    at callReactNativeMicrotasks (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:35058:44)\n    at __callReactNativeMicrotasks (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6540:46)\n    at anonymous (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6314:45)\n    at __guard (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6513:15)\n    at flushedQueue (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6313:21)\n    at invokeCallbackAndReturnFlushedQueue (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6307:33)",
    "cause": {
      "name": "TypeError",
      "stack": "TypeError: this.store.copyTo is not a function (it is undefined)\n    at ?anon_0_ (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:489697:36)\n    at next (native)\n    at asyncGeneratorStep (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:28298:26)\n    at _next (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:28317:29)\n    at tryCallOne (/Users/distiller/react-native/packages/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:53:16)\n    at anonymous (/Users/distiller/react-native/packages/react-native/sdks/hermes/build_iphonesimulator/lib/InternalBytecode/InternalBytecode.js:139:27)\n    at apply (native)\n    at anonymous (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:34928:26)\n    at _callTimer (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:34807:17)\n    at _callReactNativeMicrotasksPass (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:34852:17)\n    at callReactNativeMicrotasks (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:35058:44)\n    at __callReactNativeMicrotasks (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6540:46)\n    at anonymous (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6314:45)\n    at __guard (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6513:15)\n    at flushedQueue (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6313:21)\n    at invokeCallbackAndReturnFlushedQueue (http://localhost:8081/src/main.bundle//&platform=ios&dev=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app={APP ID}:6307:33)",
      "message": "this.store.copyTo is not a function (it is undefined)"
    }
  }
}

I assume that the default storage backend should work with the auto update assistant, but this is not the case. Is this because I'm trying to adopt v0.5.x a bit early, or is it a sign of an issue that needs addressing?

@genaris
Copy link
Contributor

genaris commented Feb 14, 2024

It looks like a problem on the @hyperledger/aries-askar-react-native and @hyperledger/aries-askar-shared you are using, since this copyTo method belongs to them. When upgrading to credo-ts 0.5.0 you must make sure that your app is importing 0.2.0 version of askar wrapper (and also indy-vdr and anoncreds-rs). Can you check again by using the latest credo alpha and a matching askar version?

@DJHunn39
Copy link
Author

Thanks for the quick response @genaris - I've upgraded to the following in my package.json (this is from the package config for a monorepo containing the 2 react-native apps, as well as a Node app with its own agent, which is why the node modules are listed):

    "@credo-ts/anoncreds": "0.5.0-alpha.132",
    "@credo-ts/askar": "0.5.0-alpha.132",
    "@credo-ts/core": "0.5.0-alpha.132",
    "@credo-ts/indy-vdr": "0.5.0-alpha.132",
    "@credo-ts/node": "0.5.0-alpha.132",
    "@credo-ts/react-native": "0.5.0-alpha.132",
...
    "@hyperledger/anoncreds-nodejs": "0.2.0",
    "@hyperledger/anoncreds-react-native": "0.2.0",
    "@hyperledger/aries-askar-nodejs": "0.2.0",
    "@hyperledger/aries-askar-react-native": "0.2.0",
    "@hyperledger/indy-vdr-nodejs": "0.2.0",
    "@hyperledger/indy-vdr-react-native": "0.2.0",

However, I'm still seeing the same type of error, though the undefined function has a slightly different name:

ERROR  StorageUpdateError: Error updating storage (updateIdentifier: 1707917838571): Error exporting wallet '{WALLET LABEL}': Function: storeCopyTo is not defined
Full error
ERROR: Error exporting wallet '{WALLET LABEL}': Function: storeCopyTo is not defined {
  "error": {
    "name": "Error",
    "stack": "Error: Function: storeCopyTo is not defined\n    at anonymous (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:473309:68)\n    at anonymous (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:472635:17)\n    at tryCallTwo (/root/react-native/packages/react-native/ReactAndroid/hermes-engine/.cxx/Release/1i515cg5/arm64-v8a/lib/InternalBytecode/InternalBytecode.js:61:9)\n    at doResolve (/root/react-native/packages/react-native/ReactAndroid/hermes-engine/.cxx/Release/1i515cg5/arm64-v8a/lib/InternalBytecode/InternalBytecode.js:216:25)\n    at Promise (/root/react-native/packages/react-native/ReactAndroid/hermes-engine/.cxx/Release/1i515cg5/arm64-v8a/lib/InternalBytecode/InternalBytecode.js:82:14)\n    at promisify (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:472623:27)\n    at storeCopyTo (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:473308:30)\n    at ?anon_0_ (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:467183:87)\n    at next (native)\n    at asyncGeneratorStep (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:28792:26)\n    at _next (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:28811:29)\n    at anonymous (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:28816:14)\n    at tryCallTwo (/root/react-native/packages/react-native/ReactAndroid/hermes-engine/.cxx/Release/1i515cg5/arm64-v8a/lib/InternalBytecode/InternalBytecode.js:61:9)\n    at doResolve (/root/react-native/packages/react-native/ReactAndroid/hermes-engine/.cxx/Release/1i515cg5/arm64-v8a/lib/InternalBytecode/InternalBytecode.js:216:25)\n    at Promise (/root/react-native/packages/react-native/ReactAndroid/hermes-engine/.cxx/Release/1i515cg5/arm64-v8a/lib/InternalBytecode/InternalBytecode.js:82:14)\n    at anonymous (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:28808:25)\n    at apply (native)\n    at copyTo (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:467192:31)\n    at ?anon_0_ (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:465243:36)\n    at next (native)\n    at asyncGeneratorStep (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:28792:26)\n    at _next (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:28811:29)\n    at tryCallOne (/root/react-native/packages/react-native/ReactAndroid/hermes-engine/.cxx/Release/1i515cg5/arm64-v8a/lib/InternalBytecode/InternalBytecode.js:53:16)\n    at anonymous (/root/react-native/packages/react-native/ReactAndroid/hermes-engine/.cxx/Release/1i515cg5/arm64-v8a/lib/InternalBytecode/InternalBytecode.js:139:27)\n    at apply (native)\n    at anonymous (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:35422:26)\n    at _callTimer (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:35301:17)\n    at _callReactNativeMicrotasksPass (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:35346:17)\n    at callReactNativeMicrotasks (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:35552:44)\n    at __callReactNativeMicrotasks (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:6538:46)\n    at anonymous (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:6312:45)\n    at __guard (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:6511:15)\n    at flushedQueue (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:6311:21)\n    at invokeCallbackAndReturnFlushedQueue (http://localhost:8082/src/main.tsx.bundle//&platform=android&dev=true&minify=false&app={APP ID}&modulesOnly=false&runModule=true:6305:33)",
    "message": "Function: storeCopyTo is not defined"
  },
  "errorMessage": "Function: storeCopyTo is not defined"
}

@TimoGlastra
Copy link
Contributor

TimoGlastra commented Feb 14, 2024

I think you may have multiple versions of askar shared installed. Could you check your yarn.lock?

Or add a dependency on the shared package in your package.json directly to pin the version.

@DJHunn39
Copy link
Author

DJHunn39 commented Feb 15, 2024

@TimoGlastra In my yarn.lock I can only see "@hyperledger/aries-askar-shared@0.2.0" - here's a screenshot showing all references to it in the file:

Screenshot 2024-02-15 at 13 52 36

The only other shared modules in there are @hyperledger/anoncreds-shared@0.2.0 & @hyperledger/indy-vdr-shared@0.2.0, here are all the references to those:

Screenshot 2024-02-15 at 13 53 58 Screenshot 2024-02-15 at 13 55 31

Adding @hyperledger/aries-askar-shared directly does not result in any changes to the yarn.lock, nor the behaviour of the agents in either RN app.

I'll try to dig into the modules themselves to figure out how the default storage is set up, but are there any other ideas?

@TimoGlastra
Copy link
Contributor

Can you see if the value of this.store is defined? Are you able to reproduce the issue in Node.JS? (Or in react native otherwise?) then i could also dive into it a bit more. Hard to tell right now what the issue is

@DJHunn39
Copy link
Author

@TimoGlastra

Can you see if the value of this.store is defined?

Yes, it's defined as:

{"_handle": {"handle": 2}, "_uri": "sqlite:///data/user/0/{APP ID}/files/.afj/wallet/{WALLET LABEL}/sqlite.db"}

Are you able to reproduce the issue in Node.JS?

I haven't tried this yet, I can give that a go if it would help to debug

Or in react native otherwise?

Yes, this happens consistently when the agent attempts to auto update its storage, on both iOS and Android. The only thing that's changed in terms of agent config that's Askar related is the change in namespace for each imported module (to @credo-ts), and the addition of the autoUpdateStorageOnStartup: true flag. Here are the relevant parts of the code:

Agent config
import {
  ConsoleLogger,
  LogLevel,
  Agent,
  ... // more imports
} from '@credo-ts/core'
import { agentDependencies } from '@credo-ts/react-native'
import { ariesAskar } from '@hyperledger/aries-askar-react-native'
...
  const config = {
    logger: new ConsoleLogger(LogLevel.info),
    label: `some label`,
    walletConfig: {
      id: `some id`,
      key: `some key`
    },
    autoUpdateStorageOnStartup: true
  }

  const agent = new Agent({
    config,
    dependencies: agentDependencies,
    modules: {
      askar: new AskarModule({
        ariesAskar
      }),
      ... // more modules
    }
  })

On my side, I've managed to get as far as identifying that something is wrong with the TurboModuleRustHostObject created here.

The keys on the object assigned as a global variable in the JS runtime (on this line) are the following:

ariesAskar native object keys
[
"version", 
"storeOpen", 
"storeGenerateRawKey", 
"storeProvision", 
"storeClose", 
"storeCreateProfile", 
"storeGetProfileName", 
"storeRekey", 
"storeRemove", 
"storeRemoveProfile", 
"sessionClose", 
"sessionCount", 
"sessionFetch", 
"sessionFetchAll", 
"sessionFetchAllKeys", 
"sessionFetchKey", 
"sessionInsertKey", 
"sessionRemoveAll", 
"sessionRemoveKey", 
"sessionStart", 
"sessionUpdate", 
"sessionUpdateKey", 
"entryListGetName", 
"entryListGetValue", 
"entryListGetCategory", 
"entryListGetTags", 
"entryListCount", 
"entryListFree", 
"scanFree", 
"scanNext", 
"scanStart", 
"keyFromJwk", 
"keyFromKeyExchange", 
"keyFromPublicBytes", 
"keyFromSecretBytes", 
"keyFromSeed", 
"keyGenerate", 
"keyGetAlgorithm", 
"keyGetEphemeral", 
"keyGetJwkPublic", 
"keyGetJwkSecret", 
"keyGetJwkThumbprint", 
"keyGetPublicBytes", 
"keyGetSecretBytes", 
"keySignMessage", 
"keyUnwrapKey", 
"keyVerifySignature", 
"keyWrapKey", 
"keyConvert", 
"keyFree", 
"keyCryptoBox", 
"keyCryptoBoxOpen", 
"keyCryptoBoxRandomNonce", 
"keyCryptoBoxSeal", 
"keyCryptoBoxSealOpen", 
"keyDeriveEcdh1pu", 
"keyDeriveEcdhEs", 
"keyAeadDecrypt", 
"keyAeadEncrypt", 
"keyAeadGetPadding", 
"keyAeadGetParams", 
"keyAeadRandomNonce", 
"keyEntryListCount", 
"keyEntryListFree", 
"keyEntryListGetAlgorithm", 
"keyEntryListGetMetadata", 
"keyEntryListGetName", 
"keyEntryListGetTags", 
"keyEntryListLoadLocal", 
"migrateIndySdk", 
"getCurrentError", 
"setDefaultLogger"
]

storeCopyTo is not the only method missing in that list, but right now I'm not sure how this object is built.

@TimoGlastra
Copy link
Contributor

What seems weird to me is that this.store.copyTo is undefined. This is a JS method that eventually calls the native methods. But it seems that also the JS side of copyTo is not present -- as otherwise it'd fail at a different level I think. Can you look into the js bundle of shared and see if copyTo is present on Store class? And maybe add some logs at different levels to see where it hangs up? Also can you make sure your node_modules at different levels only contain a single shared install, and that the package.json contains 0.2.0?

Sorry with reproduce I meant whether you're able to provide me with a reproduction repo that i can run

@DJHunn39
Copy link
Author

DJHunn39 commented Feb 20, 2024

@TimoGlastra a reproduction repo would be difficult to setup quickly, I'll need to find some time to look into getting one ready without any info identifying the project I'm working on.

It does appear that Store.copyTo is present (not in my log since it exists on the __proto__ of this.store) - here's what this.store looks like from this line:

Screenshot 2024-02-20 at 11 40 15

The method is called as expected, but the storeCopyTo method on global._aries_askar is not - the error comes from this line, at which point ariesAskar === global._aries_askar, as ariesAskar is registered here, and the global _aries_askar variable is passed into the register function here, just after the native module is installed, which should set _aries_askar based on this line.

As mentioned in my other comment, the global object's keys do not include storeCopyTo - here's a screenshot from Flipper showing this:
Screenshot 2024-02-20 at 11 35 09

With regards to different levels of node_modules, yes it does look like everything is in order there - the overall project's modules are shared by all, and the @hyperledger/aries-askar-... modules all show 0.2.0 in their package.json files.

Since the issue appears to be in the native module, it might be worth noting that this is all on react-native 0.72.6

@TimoGlastra
Copy link
Contributor

Without a repro, it's quite hard for me to debug this issue further ... You can also send me something privately that reproduce the issue.

The storeCopyTo method you mention is still a JS method, so you should be able to find that in your node_modules: https://github.com/hyperledger/aries-askar/blob/1b51f9d327bce6460ec883c6584e86b752dad13f/wrappers/javascript/aries-askar-react-native/src/ReactNativeAriesAskar.ts#L625 (the built JS file of it). Is that present?

storeCopyTo is a newer method and so the most probably thing is that you're not using a version of Askar (for node.js / react native) that includes that method, and without a reproduction that is all the hints I can give your at this point.

@genaris
Copy link
Contributor

genaris commented May 9, 2024

Closing as it seems it could be a set-up issue with an earlier 0.5.0-alpha. Should be work fine with current released version (0.5.3). Feel free to re-open if it's still not working for you!

@genaris genaris closed this as completed May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants