diff --git a/backend/package-lock.json b/backend/package-lock.json index d06a59f3d..5543d7312 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -17,7 +17,7 @@ "crypto-js": "~4.2.0", "express": "~4.22.1", "maxmind": "~4.3.11", - "mysql2": "~3.14.1", + "mysql2": "~3.16.0", "redis": "^4.7.0", "rust-gbt": "file:./rust-gbt", "socks-proxy-agent": "~7.0.0", @@ -5496,14 +5496,14 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mysql2": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.14.1.tgz", - "integrity": "sha512-7ytuPQJjQB8TNAYX/H2yhL+iQOnIBjAMam361R7UAL0lOVXWjtdrmoL9HYKqKoLp/8UUTRcvo1QPvK9KL7wA8w==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.16.0.tgz", + "integrity": "sha512-AEGW7QLLSuSnjCS4pk3EIqOmogegmze9h8EyrndavUQnIUcfkVal/sK7QznE+a3bc6rzPbAiui9Jcb+96tPwYA==", "dependencies": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", + "iconv-lite": "^0.7.0", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", @@ -5515,14 +5515,18 @@ } }, "node_modules/mysql2/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/named-placeholders": { @@ -11060,14 +11064,14 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "mysql2": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.14.1.tgz", - "integrity": "sha512-7ytuPQJjQB8TNAYX/H2yhL+iQOnIBjAMam361R7UAL0lOVXWjtdrmoL9HYKqKoLp/8UUTRcvo1QPvK9KL7wA8w==", + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.16.0.tgz", + "integrity": "sha512-AEGW7QLLSuSnjCS4pk3EIqOmogegmze9h8EyrndavUQnIUcfkVal/sK7QznE+a3bc6rzPbAiui9Jcb+96tPwYA==", "requires": { "aws-ssl-profiles": "^1.1.1", "denque": "^2.1.0", "generate-function": "^2.3.1", - "iconv-lite": "^0.6.3", + "iconv-lite": "^0.7.0", "long": "^5.2.1", "lru.min": "^1.0.0", "named-placeholders": "^1.1.3", @@ -11076,9 +11080,9 @@ }, "dependencies": { "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", "requires": { "safer-buffer": ">= 2.1.2 < 3.0.0" } diff --git a/backend/package.json b/backend/package.json index 15577fcef..583945e4d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -48,7 +48,7 @@ "crypto-js": "~4.2.0", "express": "~4.22.1", "maxmind": "~4.3.11", - "mysql2": "~3.14.1", + "mysql2": "~3.16.0", "rust-gbt": "file:./rust-gbt", "redis": "^4.7.0", "socks-proxy-agent": "~7.0.0", diff --git a/backend/src/api/prices/prices.routes.ts b/backend/src/api/prices/prices.routes.ts index e395fb44b..cdf435f32 100644 --- a/backend/src/api/prices/prices.routes.ts +++ b/backend/src/api/prices/prices.routes.ts @@ -1,14 +1,11 @@ import { Application, Request, Response } from 'express'; import config from '../../config'; import pricesUpdater from '../../tasks/price-updater'; -import logger from '../../logger'; -import PricesRepository from '../../repositories/PricesRepository'; class PricesRoutes { public initRoutes(app: Application): void { app .get(config.MEMPOOL.API_URL_PREFIX + 'prices', this.$getCurrentPrices.bind(this)) - .get(config.MEMPOOL.API_URL_PREFIX + 'internal/usd-price-history', this.$getAllPrices.bind(this)) ; } @@ -19,23 +16,6 @@ class PricesRoutes { res.json(pricesUpdater.getLatestPrices()); } - - private async $getAllPrices(req: Request, res: Response): Promise { - res.header('Pragma', 'public'); - res.header('Cache-control', 'public'); - res.setHeader('Expires', new Date(Date.now() + 360_0000 / config.MEMPOOL.PRICE_UPDATES_PER_HOUR).toUTCString()); - - try { - const usdPriceHistory = await PricesRepository.$getPricesTimesAndId(); - const responseData = usdPriceHistory.map(p => { - return { time: p.time, USD: p.USD }; - }); - res.status(200).json(responseData); - } catch (e: any) { - logger.err(`Exception ${e} in PricesRoutes::$getAllPrices. Code: ${e.code}. Message: ${e.message}`); - res.status(403).send(); - } - } } export default new PricesRoutes(); diff --git a/docker/frontend/entrypoint.sh b/docker/frontend/entrypoint.sh index 9727adb2d..64d545e50 100644 --- a/docker/frontend/entrypoint.sh +++ b/docker/frontend/entrypoint.sh @@ -3,6 +3,13 @@ __MEMPOOL_BACKEND_MAINNET_HTTP_HOST__=${BACKEND_MAINNET_HTTP_HOST:=127.0.0.1} __MEMPOOL_BACKEND_MAINNET_HTTP_PORT__=${BACKEND_MAINNET_HTTP_PORT:=8999} __MEMPOOL_FRONTEND_HTTP_PORT__=${FRONTEND_HTTP_PORT:=8080} +__PROXIED_SERVICES__=${PROXIED_SERVICES:=false} +__PROXIED_SERVICES_HOST__=${PROXIED_SERVICES_HOST:=https://mempool.space} + +if [ "${__PROXIED_SERVICES__}" = "true" ]; then + sed -i "s|proxy_pass https://mempool.space;|proxy_pass ${__PROXIED_SERVICES_HOST__};|g" /etc/nginx/conf.d/nginx-mempool.conf +fi + sed -i "s/__MEMPOOL_BACKEND_MAINNET_HTTP_HOST__/${__MEMPOOL_BACKEND_MAINNET_HTTP_HOST__}/g" /etc/nginx/conf.d/nginx-mempool.conf sed -i "s/__MEMPOOL_BACKEND_MAINNET_HTTP_PORT__/${__MEMPOOL_BACKEND_MAINNET_HTTP_PORT__}/g" /etc/nginx/conf.d/nginx-mempool.conf diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 105b3776c..5f7228340 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -31,10 +31,8 @@ "@types/qrcode": "~1.5.0", "bootstrap": "~4.6.2", "clipboard": "^2.0.11", - "cypress": "15.8.1", "domino": "^2.1.6", "echarts": "~5.4.0", - "esbuild": "^0.25.8", "ngx-echarts": "~20.0.2", "ngx-infinite-scroll": "^20.0.0", "qrcode": "1.5.1", diff --git a/frontend/package.json b/frontend/package.json index a386f3391..1234a9766 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -85,7 +85,6 @@ "ngx-infinite-scroll": "^20.0.0", "qrcode": "1.5.1", "rxjs": "~7.8.1", - "esbuild": "^0.25.8", "tslib": "~2.8.0", "zone.js": "~0.15.1" }, diff --git a/frontend/src/app/components/block/block.component.ts b/frontend/src/app/components/block/block.component.ts index bc20125f8..b1b055957 100644 --- a/frontend/src/app/components/block/block.component.ts +++ b/frontend/src/app/components/block/block.component.ts @@ -569,7 +569,7 @@ export class BlockComponent implements OnInit, OnDestroy { } else { this.showPreviousBlocklink = true; } - if (this.latestBlock.height && this.latestBlock.height === this.blockHeight) { + if (this.latestBlock.height != null && this.latestBlock.height === this.blockHeight) { this.showNextBlocklink = false; } else { this.showNextBlocklink = true; diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html index f38312c32..8b447ba5c 100644 --- a/frontend/src/app/components/transaction/transaction.component.html +++ b/frontend/src/app/components/transaction/transaction.component.html @@ -31,6 +31,21 @@
+ @if (duplicateTxBlocks) { +
+
+ +
+ + + This transaction ID appears twice in the blockchain as the coinbase of blocks {{ duplicateTxBlocks[0] }} and {{ duplicateTxBlocks[1] }}, due to a bug later mitigated by BIP-30. + + + Read more + +
+ } + @if (!error) { = { + 'e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468': [91722, 91880], + 'd5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599': [91812, 91842], +}; + @Component({ selector: 'app-transaction', templateUrl: './transaction.component.html', @@ -142,6 +148,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { waitingForAccelerationInfo: boolean = false; isLoadingFirstSeen = false; notAcceleratedOnLoad: boolean = null; + duplicateTxBlocks: [number, number] | undefined; featuresEnabled: boolean; segwitEnabled: boolean; @@ -584,6 +591,9 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { }); } } + if (this.network === '' && this.txId) { + this.duplicateTxBlocks = DUPLICATE_TX_BLOCKS[this.txId?.toLowerCase()]; + } if (window.innerWidth <= 767.98) { this.router.navigate([this.relativeUrlPipe.transform('/tx'), this.txId], { queryParamsHandling: 'merge',