diff --git a/backend/mempool-config.sample.json b/backend/mempool-config.sample.json index 86d226154..c4227adce 100644 --- a/backend/mempool-config.sample.json +++ b/backend/mempool-config.sample.json @@ -2,6 +2,7 @@ "MEMPOOL": { "NETWORK": "mainnet", "BACKEND": "electrum", + "ENABLED": true, "HTTP_PORT": 8999, "SPAWN_CLUSTER_PROCS": 0, "API_URL_PREFIX": "/api/v1/", diff --git a/backend/src/__fixtures__/mempool-config.template.json b/backend/src/__fixtures__/mempool-config.template.json index a42426249..e6c5428e5 100644 --- a/backend/src/__fixtures__/mempool-config.template.json +++ b/backend/src/__fixtures__/mempool-config.template.json @@ -1,7 +1,9 @@ { "MEMPOOL": { + "ENABLED": true, "NETWORK": "__MEMPOOL_NETWORK__", "BACKEND": "__MEMPOOL_BACKEND__", + "ENABLED": true, "BLOCKS_SUMMARIES_INDEXING": true, "HTTP_PORT": 1, "SPAWN_CLUSTER_PROCS": 2, diff --git a/backend/src/__tests__/config.test.ts b/backend/src/__tests__/config.test.ts index 7314fde6f..650beaac1 100644 --- a/backend/src/__tests__/config.test.ts +++ b/backend/src/__tests__/config.test.ts @@ -13,6 +13,7 @@ describe('Mempool Backend Config', () => { const config = jest.requireActual('../config').default; expect(config.MEMPOOL).toStrictEqual({ + ENABLED: true, NETWORK: 'mainnet', BACKEND: 'none', BLOCKS_SUMMARIES_INDEXING: false, diff --git a/backend/src/api/mempool.ts b/backend/src/api/mempool.ts index 43aea6059..76c8b169f 100644 --- a/backend/src/api/mempool.ts +++ b/backend/src/api/mempool.ts @@ -103,12 +103,11 @@ class Mempool { return txTimes; } - public async $updateMempool() { - logger.debug('Updating mempool'); + public async $updateMempool(): Promise { + logger.debug(`Updating mempool...`); const start = new Date().getTime(); let hasChange: boolean = false; const currentMempoolSize = Object.keys(this.mempoolCache).length; - let txCount = 0; const transactions = await bitcoinApi.$getRawMempool(); const diff = transactions.length - currentMempoolSize; const newTransactions: TransactionExtended[] = []; @@ -124,7 +123,6 @@ class Mempool { try { const transaction = await transactionUtils.$getTransactionExtended(txid); this.mempoolCache[txid] = transaction; - txCount++; if (this.inSync) { this.txPerSecondArray.push(new Date().getTime()); this.vBytesPerSecondArray.push({ @@ -133,14 +131,9 @@ class Mempool { }); } hasChange = true; - if (diff > 0) { - logger.debug('Fetched transaction ' + txCount + ' / ' + diff); - } else { - logger.debug('Fetched transaction ' + txCount); - } newTransactions.push(transaction); } catch (e) { - logger.debug('Error finding transaction in mempool: ' + (e instanceof Error ? e.message : e)); + logger.debug(`Error finding transaction '${txid}' in the mempool: ` + (e instanceof Error ? e.message : e)); } } @@ -197,8 +190,7 @@ class Mempool { const end = new Date().getTime(); const time = end - start; - logger.debug(`New mempool size: ${Object.keys(this.mempoolCache).length} Change: ${diff}`); - logger.debug('Mempool updated in ' + time / 1000 + ' seconds'); + logger.debug(`Mempool updated in ${time / 1000} seconds. New size: ${Object.keys(this.mempoolCache).length} (${diff > 0 ? '+' + diff : diff})`); } public handleRbfTransactions(rbfTransactions: { [txid: string]: TransactionExtended; }) { diff --git a/backend/src/config.ts b/backend/src/config.ts index 43ba16cb3..052affb45 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -4,6 +4,7 @@ const configFromFile = require( interface IConfig { MEMPOOL: { + ENABLED: boolean; NETWORK: 'mainnet' | 'testnet' | 'signet' | 'liquid' | 'liquidtestnet'; BACKEND: 'esplora' | 'electrum' | 'none'; HTTP_PORT: number; @@ -119,6 +120,7 @@ interface IConfig { const defaults: IConfig = { 'MEMPOOL': { + 'ENABLED': true, 'NETWORK': 'mainnet', 'BACKEND': 'none', 'HTTP_PORT': 8999, @@ -224,11 +226,11 @@ const defaults: IConfig = { 'BISQ_URL': 'https://bisq.markets/api', 'BISQ_ONION': 'http://bisqmktse2cabavbr2xjq7xw3h6g5ottemo5rolfcwt6aly6tp5fdryd.onion/api' }, - "MAXMIND": { + 'MAXMIND': { 'ENABLED': false, - "GEOLITE2_CITY": "/usr/local/share/GeoIP/GeoLite2-City.mmdb", - "GEOLITE2_ASN": "/usr/local/share/GeoIP/GeoLite2-ASN.mmdb", - "GEOIP2_ISP": "/usr/local/share/GeoIP/GeoIP2-ISP.mmdb" + 'GEOLITE2_CITY': '/usr/local/share/GeoIP/GeoLite2-City.mmdb', + 'GEOLITE2_ASN': '/usr/local/share/GeoIP/GeoLite2-ASN.mmdb', + 'GEOIP2_ISP': '/usr/local/share/GeoIP/GeoIP2-ISP.mmdb' }, }; diff --git a/backend/src/index.ts b/backend/src/index.ts index d1e3cee8d..2bcb98de1 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -1,4 +1,4 @@ -import express from "express"; +import express from 'express'; import { Application, Request, Response, NextFunction } from 'express'; import * as http from 'http'; import * as WebSocket from 'ws'; @@ -34,7 +34,7 @@ import miningRoutes from './api/mining/mining-routes'; import bisqRoutes from './api/bisq/bisq.routes'; import liquidRoutes from './api/liquid/liquid.routes'; import bitcoinRoutes from './api/bitcoin/bitcoin.routes'; -import fundingTxFetcher from "./tasks/lightning/sync-tasks/funding-tx-fetcher"; +import fundingTxFetcher from './tasks/lightning/sync-tasks/funding-tx-fetcher'; class Server { private wss: WebSocket.Server | undefined; @@ -74,7 +74,7 @@ class Server { } } - async startServer(worker = false) { + async startServer(worker = false): Promise { logger.notice(`Starting Mempool Server${worker ? ' (worker)' : ''}... (${backendInfo.getShortCommitHash()})`); this.app @@ -92,7 +92,9 @@ class Server { this.setUpWebsocketHandling(); await syncAssets.syncAssets$(); - diskCache.loadMempoolCache(); + if (config.MEMPOOL.ENABLED) { + diskCache.loadMempoolCache(); + } if (config.DATABASE.ENABLED) { await DB.checkDbConnection(); @@ -127,7 +129,10 @@ class Server { fiatConversion.startService(); this.setUpHttpApiRoutes(); - this.runMainUpdateLoop(); + + if (config.MEMPOOL.ENABLED) { + this.runMainUpdateLoop(); + } if (config.BISQ.ENABLED) { bisq.startBisqService(); @@ -149,7 +154,7 @@ class Server { }); } - async runMainUpdateLoop() { + async runMainUpdateLoop(): Promise { try { try { await memPool.$updateMemPoolInfo(); @@ -183,7 +188,7 @@ class Server { } } - async $runLightningBackend() { + async $runLightningBackend(): Promise { try { await fundingTxFetcher.$init(); await networkSyncService.$startService(); @@ -195,7 +200,7 @@ class Server { }; } - setUpWebsocketHandling() { + setUpWebsocketHandling(): void { if (this.wss) { websocketHandler.setWebsocketServer(this.wss); } @@ -209,19 +214,21 @@ class Server { }); } websocketHandler.setupConnectionHandling(); - statistics.setNewStatisticsEntryCallback(websocketHandler.handleNewStatistic.bind(websocketHandler)); - blocks.setNewBlockCallback(websocketHandler.handleNewBlock.bind(websocketHandler)); - memPool.setMempoolChangedCallback(websocketHandler.handleMempoolChange.bind(websocketHandler)); + if (config.MEMPOOL.ENABLED) { + statistics.setNewStatisticsEntryCallback(websocketHandler.handleNewStatistic.bind(websocketHandler)); + blocks.setNewBlockCallback(websocketHandler.handleNewBlock.bind(websocketHandler)); + memPool.setMempoolChangedCallback(websocketHandler.handleMempoolChange.bind(websocketHandler)); + } fiatConversion.setProgressChangedCallback(websocketHandler.handleNewConversionRates.bind(websocketHandler)); loadingIndicators.setProgressChangedCallback(websocketHandler.handleLoadingChanged.bind(websocketHandler)); } - - setUpHttpApiRoutes() { + + setUpHttpApiRoutes(): void { bitcoinRoutes.initRoutes(this.app); - if (config.STATISTICS.ENABLED && config.DATABASE.ENABLED) { + if (config.STATISTICS.ENABLED && config.DATABASE.ENABLED && config.MEMPOOL.ENABLED) { statisticsRoutes.initRoutes(this.app); } - if (Common.indexingEnabled()) { + if (Common.indexingEnabled() && config.MEMPOOL.ENABLED) { miningRoutes.initRoutes(this.app); } if (config.BISQ.ENABLED) { @@ -238,4 +245,4 @@ class Server { } } -const server = new Server(); +((): Server => new Server())(); diff --git a/docker/README.md b/docker/README.md index 92cc1df6d..4061f420c 100644 --- a/docker/README.md +++ b/docker/README.md @@ -89,6 +89,7 @@ Below we list all settings from `mempool-config.json` and the corresponding over "MEMPOOL": { "NETWORK": "mainnet", "BACKEND": "electrum", + "ENABLED": true, "HTTP_PORT": 8999, "SPAWN_CLUSTER_PROCS": 0, "API_URL_PREFIX": "/api/v1/", diff --git a/docker/backend/mempool-config.json b/docker/backend/mempool-config.json index 930430127..378bba8db 100644 --- a/docker/backend/mempool-config.json +++ b/docker/backend/mempool-config.json @@ -2,6 +2,7 @@ "MEMPOOL": { "NETWORK": "__MEMPOOL_NETWORK__", "BACKEND": "__MEMPOOL_BACKEND__", + "ENABLED": __MEMPOOL_ENABLED__, "HTTP_PORT": __MEMPOOL_HTTP_PORT__, "SPAWN_CLUSTER_PROCS": __MEMPOOL_SPAWN_CLUSTER_PROCS__, "API_URL_PREFIX": "__MEMPOOL_API_URL_PREFIX__", diff --git a/docker/backend/start.sh b/docker/backend/start.sh index 4933dc2ee..c8e2a1502 100755 --- a/docker/backend/start.sh +++ b/docker/backend/start.sh @@ -3,6 +3,7 @@ # MEMPOOL __MEMPOOL_NETWORK__=${MEMPOOL_NETWORK:=mainnet} __MEMPOOL_BACKEND__=${MEMPOOL_BACKEND:=electrum} +__MEMPOOL_ENABLED__=${MEMPOOL_ENABLED:=true} __MEMPOOL_HTTP_PORT__=${BACKEND_HTTP_PORT:=8999} __MEMPOOL_SPAWN_CLUSTER_PROCS__=${MEMPOOL_SPAWN_CLUSTER_PROCS:=0} __MEMPOOL_API_URL_PREFIX__=${MEMPOOL_API_URL_PREFIX:=/api/v1/} @@ -111,6 +112,7 @@ mkdir -p "${__MEMPOOL_CACHE_DIR__}" sed -i "s/__MEMPOOL_NETWORK__/${__MEMPOOL_NETWORK__}/g" mempool-config.json sed -i "s/__MEMPOOL_BACKEND__/${__MEMPOOL_BACKEND__}/g" mempool-config.json +sed -i "s/__MEMPOOL_ENABLED__/${__MEMPOOL_ENABLED__}/g" mempool-config.json sed -i "s/__MEMPOOL_HTTP_PORT__/${__MEMPOOL_HTTP_PORT__}/g" mempool-config.json sed -i "s/__MEMPOOL_SPAWN_CLUSTER_PROCS__/${__MEMPOOL_SPAWN_CLUSTER_PROCS__}/g" mempool-config.json sed -i "s!__MEMPOOL_API_URL_PREFIX__!${__MEMPOOL_API_URL_PREFIX__}!g" mempool-config.json diff --git a/frontend/angular.json b/frontend/angular.json index 1ed29cad9..a94b3b85f 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -222,6 +222,10 @@ "proxyConfig": "proxy.conf.local.js", "verbose": true }, + "local-esplora": { + "proxyConfig": "proxy.conf.local-esplora.js", + "verbose": true + }, "mixed": { "proxyConfig": "proxy.conf.mixed.js", "verbose": true diff --git a/frontend/package.json b/frontend/package.json index c5a062e01..9423eb901 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -29,6 +29,7 @@ "serve:local-prod": "npm run generate-config && npm run ng -- serve -c local-prod", "serve:local-staging": "npm run generate-config && npm run ng -- serve -c local-staging", "start": "npm run generate-config && npm run sync-assets-dev && npm run ng -- serve -c local", + "start:local-esplora": "npm run generate-config && npm run sync-assets-dev && npm run ng -- serve -c local-esplora", "start:stg": "npm run generate-config && npm run sync-assets-dev && npm run ng -- serve -c staging", "start:local-prod": "npm run generate-config && npm run sync-assets-dev && npm run ng -- serve -c local-prod", "start:local-staging": "npm run generate-config && npm run sync-assets-dev && npm run ng -- serve -c local-staging", diff --git a/frontend/proxy.conf.local-esplora.js b/frontend/proxy.conf.local-esplora.js new file mode 100644 index 000000000..8bb57e623 --- /dev/null +++ b/frontend/proxy.conf.local-esplora.js @@ -0,0 +1,137 @@ +const fs = require('fs'); + +const FRONTEND_CONFIG_FILE_NAME = 'mempool-frontend-config.json'; + +let configContent; + +// Read frontend config +try { + const rawConfig = fs.readFileSync(FRONTEND_CONFIG_FILE_NAME); + configContent = JSON.parse(rawConfig); + console.log(`${FRONTEND_CONFIG_FILE_NAME} file found, using provided config`); +} catch (e) { + console.log(e); + if (e.code !== 'ENOENT') { + throw new Error(e); + } else { + console.log(`${FRONTEND_CONFIG_FILE_NAME} file not found, using default config`); + } +} + +let PROXY_CONFIG = []; + +if (configContent && configContent.BASE_MODULE === 'liquid') { + PROXY_CONFIG.push(...[ + { + context: ['/liquid/api/v1/**'], + target: `http://127.0.0.1:8999`, + secure: false, + ws: true, + changeOrigin: true, + proxyTimeout: 30000, + pathRewrite: { + "^/liquid": "" + }, + }, + { + context: ['/liquid/api/**'], + target: `http://127.0.0.1:3000`, + secure: false, + changeOrigin: true, + proxyTimeout: 30000, + pathRewrite: { + "^/liquid/api/": "" + }, + }, + { + context: ['/liquidtestnet/api/v1/**'], + target: `http://127.0.0.1:8999`, + secure: false, + ws: true, + changeOrigin: true, + proxyTimeout: 30000, + pathRewrite: { + "^/liquidtestnet": "" + }, + }, + { + context: ['/liquidtestnet/api/**'], + target: `http://127.0.0.1:3000`, + secure: false, + changeOrigin: true, + proxyTimeout: 30000, + pathRewrite: { + "^/liquidtestnet/api/": "/" + }, + }, + ]); +} + + +if (configContent && configContent.BASE_MODULE === 'bisq') { + PROXY_CONFIG.push(...[ + { + context: ['/bisq/api/v1/ws'], + target: `http://127.0.0.1:8999`, + secure: false, + ws: true, + changeOrigin: true, + proxyTimeout: 30000, + pathRewrite: { + "^/bisq": "" + }, + }, + { + context: ['/bisq/api/v1/**'], + target: `http://127.0.0.1:8999`, + secure: false, + changeOrigin: true, + proxyTimeout: 30000, + }, + { + context: ['/bisq/api/**'], + target: `http://127.0.0.1:8999`, + secure: false, + changeOrigin: true, + proxyTimeout: 30000, + pathRewrite: { + "^/bisq/api/": "/api/v1/bisq/" + }, + } + ]); +} + +PROXY_CONFIG.push(...[ + { + context: ['/testnet/api/v1/lightning/**'], + target: `http://127.0.0.1:8999`, + secure: false, + changeOrigin: true, + proxyTimeout: 30000, + pathRewrite: { + "^/testnet": "" + }, + }, + { + context: ['/api/v1/**'], + target: `http://127.0.0.1:8999`, + secure: false, + ws: true, + changeOrigin: true, + proxyTimeout: 30000, + }, + { + context: ['/api/**'], + target: `http://127.0.0.1:3000`, + secure: false, + changeOrigin: true, + proxyTimeout: 30000, + pathRewrite: { + "^/api": "" + }, + } +]); + +console.log(PROXY_CONFIG); + +module.exports = PROXY_CONFIG; \ No newline at end of file diff --git a/frontend/src/app/components/search-form/search-form.component.html b/frontend/src/app/components/search-form/search-form.component.html index 1303f4a62..4e38ea6e0 100644 --- a/frontend/src/app/components/search-form/search-form.component.html +++ b/frontend/src/app/components/search-form/search-form.component.html @@ -2,9 +2,7 @@
- - - +