From e00a4fbf1c2c2d03ad5437db39514f27e370e6f4 Mon Sep 17 00:00:00 2001 From: Mondei1 Date: Mon, 25 Jan 2021 19:10:13 +0100 Subject: [PATCH] Provider are now starting asynchronously --- src/helper/backendProvider.ts | 2 +- src/helper/providerManager.ts | 13 +++--- src/helper/providers/bitcoinCore.ts | 31 +++++++++------ src/helper/providers/dogecoinCore.ts | 32 +++++++++------ src/helper/providers/litecoinCore.ts | 31 +++++++++------ src/helper/providers/moneroCLI.ts | 59 ++++++++++++++-------------- 6 files changed, 96 insertions(+), 72 deletions(-) diff --git a/src/helper/backendProvider.ts b/src/helper/backendProvider.ts index ab35c12..45a325a 100644 --- a/src/helper/backendProvider.ts +++ b/src/helper/backendProvider.ts @@ -25,7 +25,7 @@ export abstract class BackendProvider { * * @returns If `false` is returned, then the provider failed to initialize. */ - abstract onEnable(): boolean; + abstract onEnable(): Promise; /** * Generate a new address to receive new funds. diff --git a/src/helper/providerManager.ts b/src/helper/providerManager.ts index c486c03..e2557ec 100644 --- a/src/helper/providerManager.ts +++ b/src/helper/providerManager.ts @@ -28,7 +28,7 @@ export class ProviderManager { .filter(dirent => dirent.name.endsWith('.ts')) .map(dirent => dirent.name) - getDirectories().forEach(file => { + getDirectories().forEach(async file => { const absolutePath = join(this.providerFilePath, file); const providerModule = require(absolutePath); const provider = new providerModule.Provider() as BackendProvider; @@ -44,13 +44,14 @@ export class ProviderManager { }); // Execute onEnable() function of this provider - const startUp = provider.onEnable(); - if (!startUp) { - logger.error(`Provider "${provider.NAME}" by ${provider.AUTHOR} (${provider.VERSION}) failed to start! (check previous logs)`); - return; + try { + await provider.onEnable(); + logger.info(`Loaded provider "${provider.NAME}" by ${provider.AUTHOR} (${provider.VERSION}) for ${provider.CRYPTO.join(', ')}`); + } catch (err) { + logger.error(`Provider "${provider.NAME}" by ${provider.AUTHOR} (${provider.VERSION}) failed to start: ${err}`); + this.disable(provider.NAME); } - logger.info(`Loaded provider "${provider.NAME}" by ${provider.AUTHOR} (${provider.VERSION}) for ${provider.CRYPTO.join(', ')}`); }); } diff --git a/src/helper/providers/bitcoinCore.ts b/src/helper/providers/bitcoinCore.ts index 91c9686..99e0aff 100644 --- a/src/helper/providers/bitcoinCore.ts +++ b/src/helper/providers/bitcoinCore.ts @@ -18,19 +18,26 @@ export class Provider implements BackendProvider { CRYPTO = [CryptoUnits.BITCOIN]; onEnable() { - this.sock = new Subscriber(); - this.sock.connect('tcp://127.0.0.1:29000'); - this.sock.subscribe('rawtx'); + return new Promise((resolve, reject) => { + this.sock = new Subscriber(); + this.sock.connect('tcp://127.0.0.1:29000'); + this.sock.subscribe('rawtx'); + + this.rpcClient = rpc.Client.http({ + port: 18332, + auth: 'admin:admin' + }); - - this.rpcClient = rpc.Client.http({ - port: 18332, - auth: 'admin:admin' - }); - - this.listener(); - - return true; + // We perfom a small test call to check if everything works. + this.rpcClient.request('getblockchaininfo', [], (err, message) => { + if (err) { + reject(`Cannot connect with Bitcoin Core: ${err.message}`); + return; + } + this.listener(); + resolve(); + }); + }); } async getNewAddress(): Promise { diff --git a/src/helper/providers/dogecoinCore.ts b/src/helper/providers/dogecoinCore.ts index 1fbfca7..b2bf19d 100644 --- a/src/helper/providers/dogecoinCore.ts +++ b/src/helper/providers/dogecoinCore.ts @@ -18,20 +18,28 @@ export class Provider implements BackendProvider { CRYPTO = [CryptoUnits.DOGECOIN]; onEnable() { - this.sock = new Subscriber(); - this.sock.connect('tcp://127.0.0.1:30000'); - this.sock.subscribe('rawtx'); - - - this.rpcClient = rpc.Client.http({ - port: 22556, - auth: 'admin:admin' + return new Promise((resolve, reject) => { + this.sock = new Subscriber(); + this.sock.connectTimeout = 2; + this.sock.connect('tcp://127.0.0.1:30000'); + this.sock.subscribe('rawtx'); + + this.rpcClient = rpc.Client.http({ + port: 22556, + auth: 'admin:admin' + }); + + // We perfom a small test call to check if everything works. + this.rpcClient.request('getblockchaininfo', [], (err, message) => { + if (err) { + reject(`Cannot connect with Dogecoin Core: ${err.message}`); + return; + } + this.listener(); + resolve(); + }); }); - this.listener(); - - return true; - //logger.info('The Bitcoin Core backend is now available!'); } diff --git a/src/helper/providers/litecoinCore.ts b/src/helper/providers/litecoinCore.ts index 3ee57ef..e6db9ee 100644 --- a/src/helper/providers/litecoinCore.ts +++ b/src/helper/providers/litecoinCore.ts @@ -18,19 +18,28 @@ export class Provider implements BackendProvider { CRYPTO = [CryptoUnits.LITECOIN]; onEnable() { - this.sock = new Subscriber(); - this.sock.connect('tcp://127.0.0.1:40000'); - this.sock.subscribe('rawtx'); + return new Promise((resolve, reject) => { + this.sock = new Subscriber(); + this.sock.connectTimeout = 2; + this.sock.connect('tcp://127.0.0.1:40000'); + this.sock.subscribe('rawtx'); - - this.rpcClient = rpc.Client.http({ - port: 22557, - auth: 'admin:admin' + + this.rpcClient = rpc.Client.http({ + port: 22557, + auth: 'admin:admin' + }); + + // We perfom a small test call to check if everything works. + this.rpcClient.request('getblockchaininfo', [], (err, message) => { + if (err) { + reject(`Cannot connect with Bitcoin Core: ${err.message}`); + return; + } + this.listener(); + resolve(); + }); }); - - this.listener(); - - return true; } async getNewAddress(): Promise { diff --git a/src/helper/providers/moneroCLI.ts b/src/helper/providers/moneroCLI.ts index f44065c..18016e0 100644 --- a/src/helper/providers/moneroCLI.ts +++ b/src/helper/providers/moneroCLI.ts @@ -19,39 +19,38 @@ export class Provider implements BackendProvider { CRYPTO = [CryptoUnits.MONERO]; onEnable() { - if (process.env.MONERO_WALLET_PASSWORD === undefined) { - logger.error(`Enviroment variable MONERO_WALLET_PASSWORD is required but not set!`); - return false; - } - - if (process.env.MONERO_WALLET_NAME === undefined) { - logger.error(`Enviroment variable MONERO_WALLET_FILEPATH is required but not set!`); - return false; - } - - if (process.env.MONERO_ZMQ_ADDRESS === undefined) { - logger.error(`Enviroment variable MONERO_ZMQ_ADDRESS is required but not set!`); - return false; - } - - this.rpcClient = rpc.Client.http({ - path: '/json_rpc', - port: 38085 - }); - this.rpcClient.request('open_wallet', { - filename: process.env.MONERO_WALLET_NAME, - password: process.env.MONERO_WALLET_PASSWORD - }, (err, message) => { - if (err) { - console.log(err); - logger.error(`Failed to open Monero wallet: ${err}\nMaybe a wrong password or path?`); + return new Promise((resolve, reject) => { + if (process.env.MONERO_WALLET_PASSWORD === undefined) { + reject('Enviroment variable MONERO_WALLET_PASSWORD is required but not set!'); return; } + + if (process.env.MONERO_WALLET_NAME === undefined) { + reject('Enviroment variable MONERO_WALLET_FILEPATH is required but not set!'); + return; + } + + if (process.env.MONERO_ZMQ_ADDRESS === undefined) { + reject('Enviroment variable MONERO_ZMQ_ADDRESS is required but not set!'); + return; + } + + this.rpcClient = rpc.Client.http({ + path: '/json_rpc', + port: 38085 + }); + this.rpcClient.request('open_wallet', { + filename: process.env.MONERO_WALLET_NAME, + password: process.env.MONERO_WALLET_PASSWORD + }, (err, message) => { + if (err) { + reject(`Failed to open Monero wallet: ${err}\nMaybe a wrong password or path?`) + return; + } + this.listener(); + resolve(); + }); }); - - this.listener(); - - return true; } async listener() {