From 61695ce7737ffef363b60e341ae5b0e67e0e2c90 Mon Sep 17 00:00:00 2001 From: Patrick Kenyon Date: Wed, 5 Jan 2022 02:07:32 -0700 Subject: [PATCH] feat: ledger connections happen on agent init in background (#580) * Connects to ledger on agent init by default, ledger calls will wait for connections to be complete if so * Updated version of indy-sdk-react-native to 0.1.16 Signed-off-by: Patrick Kenyon --- packages/core/src/agent/Agent.ts | 9 ++++++- packages/core/src/agent/AgentConfig.ts | 4 +++ packages/core/src/modules/ledger/IndyPool.ts | 25 +++++++++++++++++++ .../core/src/modules/ledger/LedgerModule.ts | 7 ++++++ .../ledger/services/IndyLedgerService.ts | 4 +++ .../ledger/services/IndyPoolService.ts | 10 ++++++++ packages/core/src/types.ts | 1 + packages/react-native/package.json | 4 +-- yarn.lock | 8 +++--- 9 files changed, 65 insertions(+), 7 deletions(-) diff --git a/packages/core/src/agent/Agent.ts b/packages/core/src/agent/Agent.ts index 09d9e31ee4..5fa60d0055 100644 --- a/packages/core/src/agent/Agent.ts +++ b/packages/core/src/agent/Agent.ts @@ -138,7 +138,7 @@ export class Agent { } public async initialize() { - const { publicDidSeed, walletConfig, mediatorConnectionsInvite } = this.agentConfig + const { connectToIndyLedgersOnStartup, publicDidSeed, walletConfig, mediatorConnectionsInvite } = this.agentConfig if (this._isInitialized) { throw new AriesFrameworkError( @@ -161,6 +161,13 @@ export class Agent { await this.wallet.initPublicDid({ seed: publicDidSeed }) } + // As long as value isn't false we will async connect to all genesis pools on startup + if (connectToIndyLedgersOnStartup) { + this.ledger.connectToPools().catch((error) => { + this.logger.warn('Error connecting to ledger, will try to reconnect when needed.', { error }) + }) + } + for (const transport of this.inboundTransports) { transport.start(this) } diff --git a/packages/core/src/agent/AgentConfig.ts b/packages/core/src/agent/AgentConfig.ts index e93d73c3da..1c7085ec3f 100644 --- a/packages/core/src/agent/AgentConfig.ts +++ b/packages/core/src/agent/AgentConfig.ts @@ -40,6 +40,10 @@ export class AgentConfig { } } + public get connectToIndyLedgersOnStartup() { + return this.initConfig.connectToIndyLedgersOnStartup ?? true + } + public get publicDidSeed() { return this.initConfig.publicDidSeed } diff --git a/packages/core/src/modules/ledger/IndyPool.ts b/packages/core/src/modules/ledger/IndyPool.ts index 1f3b65507f..12cce1a9db 100644 --- a/packages/core/src/modules/ledger/IndyPool.ts +++ b/packages/core/src/modules/ledger/IndyPool.ts @@ -22,6 +22,7 @@ export class IndyPool { private fileSystem: FileSystem private poolConfig: IndyPoolConfig private _poolHandle?: number + private poolConnected?: Promise public authorAgreement?: AuthorAgreement | null public constructor(agentConfig: AgentConfig, poolConfig: IndyPoolConfig) { @@ -74,6 +75,21 @@ export class IndyPool { } public async connect() { + if (!this.poolConnected) { + // Save the promise of connectToLedger to determine if we are done connecting + this.poolConnected = this.connectToLedger() + this.poolConnected.catch((error) => { + // Set poolConnected to undefined so we can retry connection upon failure + this.poolConnected = undefined + this.logger.error('Connection to pool: ' + this.poolConfig.genesisPath + ' failed.', { error }) + }) + return this.poolConnected + } else { + throw new AriesFrameworkError('Cannot attempt connection to ledger, already connecting.') + } + } + + private async connectToLedger() { const poolName = this.poolConfig.id const genesisPath = await this.getGenesisPath() @@ -130,6 +146,15 @@ export class IndyPool { } private async getPoolHandle() { + if (this.poolConnected) { + // If we have tried to already connect to pool wait for it + try { + await this.poolConnected + } catch (error) { + this.logger.error('Connection to pool: ' + this.poolConfig.genesisPath + ' failed.', { error }) + } + } + if (!this._poolHandle) { return this.connect() } diff --git a/packages/core/src/modules/ledger/LedgerModule.ts b/packages/core/src/modules/ledger/LedgerModule.ts index 751468c050..b004858c52 100644 --- a/packages/core/src/modules/ledger/LedgerModule.ts +++ b/packages/core/src/modules/ledger/LedgerModule.ts @@ -19,6 +19,13 @@ export class LedgerModule { this.wallet = wallet } + /** + * Connect to all the ledger pools + */ + public async connectToPools() { + await this.ledgerService.connectToPools() + } + public async registerPublicDid(did: string, verkey: string, alias: string, role?: NymRole) { const myPublicDid = this.wallet.publicDid?.did diff --git a/packages/core/src/modules/ledger/services/IndyLedgerService.ts b/packages/core/src/modules/ledger/services/IndyLedgerService.ts index 956c9fc2c1..1e4680081f 100644 --- a/packages/core/src/modules/ledger/services/IndyLedgerService.ts +++ b/packages/core/src/modules/ledger/services/IndyLedgerService.ts @@ -43,6 +43,10 @@ export class IndyLedgerService { this.indyPoolService = indyPoolService } + public async connectToPools() { + return this.indyPoolService.connectToPools() + } + public async registerPublicDid( submitterDid: string, targetDid: string, diff --git a/packages/core/src/modules/ledger/services/IndyPoolService.ts b/packages/core/src/modules/ledger/services/IndyPoolService.ts index 4a6eb5fce3..ba12b147aa 100644 --- a/packages/core/src/modules/ledger/services/IndyPoolService.ts +++ b/packages/core/src/modules/ledger/services/IndyPoolService.ts @@ -36,6 +36,16 @@ export class IndyPoolService { this.didCache = new PersistedLruCache(DID_POOL_CACHE_ID, DID_POOL_CACHE_LIMIT, cacheRepository) } + /** + * Create connections to all ledger pools + */ + public async connectToPools() { + const poolsPromises = this.pools.map((pool) => { + return pool.connect() + }) + return Promise.all(poolsPromises) + } + /** * Get the pool used for writing to the ledger. For now we always use the first pool * as the pool that writes to the ledger diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 1af46f2800..20939a1ca6 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -36,6 +36,7 @@ export interface InitConfig { didCommMimeType?: DidCommMimeType indyLedgers?: IndyPoolConfig[] + connectToIndyLedgersOnStartup?: boolean autoAcceptMediationRequests?: boolean mediatorConnectionsInvite?: string diff --git a/packages/react-native/package.json b/packages/react-native/package.json index 325d6f0527..d11e930701 100644 --- a/packages/react-native/package.json +++ b/packages/react-native/package.json @@ -31,7 +31,7 @@ "devDependencies": { "@types/indy-sdk-react-native": "npm:@types/indy-sdk@^1.16.6", "@types/react-native": "^0.64.10", - "indy-sdk-react-native": "^0.1.13", + "indy-sdk-react-native": "^0.1.16", "react": "17.0.1", "react-native": "0.64.2", "react-native-fs": "^2.18.0", @@ -40,7 +40,7 @@ "typescript": "~4.3.0" }, "peerDependencies": { - "indy-sdk-react-native": "^0.1.13", + "indy-sdk-react-native": "^0.1.16", "react-native-fs": "^2.18.0", "react-native-get-random-values": "^1.7.0" } diff --git a/yarn.lock b/yarn.lock index 2fa13757c5..e4e431b4f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5229,10 +5229,10 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -indy-sdk-react-native@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/indy-sdk-react-native/-/indy-sdk-react-native-0.1.13.tgz#7a131541f21d4fa5091d214ed75f2235977512e9" - integrity sha512-V0vfR6y8rOy9efc0An5FqSxeiynYFXrOd2tcXYVAA2iX5Y6OuOmbzAGHTTMfiagZaLyE+/1j7DSSaYlXo76VYA== +indy-sdk-react-native@^0.1.16: + version "0.1.16" + resolved "https://registry.yarnpkg.com/indy-sdk-react-native/-/indy-sdk-react-native-0.1.16.tgz#db956168cdd27e569c45ac88e8c12baa7a6ac85e" + integrity sha512-vsYfq/TNZbF3AYALySNrhtONnSKIHsPdFMo9LSlUNrNZEBQnnR0aZKjAnRSLSYXUo6hF5Njc+AJFpwawWLZqkg== dependencies: buffer "^6.0.2"