- ETA |
+ ETA |
= 7" [ngIfElse]="belowBlockLimit">
-
- In several hours (or more)
- Accelerate
+
+ In several hours (or more)
+
@@ -109,9 +144,11 @@
-
-
- Accelerate
+
+
+
diff --git a/frontend/src/app/components/transaction/transaction.component.scss b/frontend/src/app/components/transaction/transaction.component.scss
index 5bef401d7..45357471a 100644
--- a/frontend/src/app/components/transaction/transaction.component.scss
+++ b/frontend/src/app/components/transaction/transaction.component.scss
@@ -228,11 +228,15 @@
}
}
+.link.accelerator {
+ cursor: pointer;
+}
+
.accelerate {
align-self: auto;
margin-top: 3px;
+ margin-left: 10px;
@media (min-width: 850px) {
justify-self: start;
- margin-left: 0px;
}
}
\ No newline at end of file
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index f1f3850e4..db200e9b1 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -19,6 +19,7 @@ import { WebsocketService } from '../../services/websocket.service';
import { AudioService } from '../../services/audio.service';
import { ApiService } from '../../services/api.service';
import { SeoService } from '../../services/seo.service';
+import { StorageService } from '../../services/storage.service';
import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment } from '../../interfaces/node-api.interface';
import { LiquidUnblinding } from './liquid-ublinding';
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
@@ -88,6 +89,9 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
rbfEnabled: boolean;
taprootEnabled: boolean;
hasEffectiveFeeRate: boolean;
+ accelerateCtaType: 'alert' | 'button' = 'alert';
+ acceleratorAvailable: boolean = this.stateService.env.OFFICIAL_MEMPOOL_SPACE && this.stateService.env.ACCELERATOR && this.stateService.network === '';
+ showAccelerationSummary = false;
@ViewChild('graphContainer')
graphContainer: ElementRef;
@@ -104,14 +108,20 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
private apiService: ApiService,
private seoService: SeoService,
private priceService: PriceService,
+ private storageService: StorageService
) {}
ngOnInit() {
this.websocketService.want(['blocks', 'mempool-blocks']);
this.stateService.networkChanged$.subscribe(
- (network) => (this.network = network)
+ (network) => {
+ this.network = network;
+ this.acceleratorAvailable = this.stateService.env.OFFICIAL_MEMPOOL_SPACE && this.stateService.env.ACCELERATOR && this.stateService.network === '';
+ }
);
+ this.accelerateCtaType = (this.storageService.getValue('accel-cta-type') as 'alert' | 'button') ?? 'alert';
+
this.setFlowEnabled();
this.flowPrefSubscription = this.stateService.hideFlow.subscribe((hide) => {
this.hideFlow = !!hide;
@@ -486,6 +496,19 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.setGraphSize();
}
+ dismissAccelAlert(): void {
+ this.storageService.setValue('accel-cta-type', 'button');
+ this.accelerateCtaType = 'button';
+ }
+
+ onAccelerateClicked(): void {
+ if (!this.txId) {
+ return;
+ }
+
+ this.showAccelerationSummary = true && this.acceleratorAvailable;
+ }
+
handleLoadElectrsTransactionError(error: any): Observable {
if (error.status === 404 && /^[a-fA-F0-9]{64}$/.test(this.txId)) {
this.websocketService.startMultiTrackTransaction(this.txId);
diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts
index cd1109da1..2d9077a97 100644
--- a/frontend/src/app/services/api.service.ts
+++ b/frontend/src/app/services/api.service.ts
@@ -388,4 +388,8 @@ export class ApiService {
getServicesBackendInfo$(): Observable {
return this.httpClient.get(`${SERVICES_API_PREFIX}/version`);
}
+
+ estimate$(txInput: string) {
+ return this.httpClient.post(`${SERVICES_API_PREFIX}/accelerator/estimate`, { txInput: txInput }, { observe: 'response' });
+ }
}
diff --git a/frontend/src/app/shared/components/confirmations/confirmations.component.html b/frontend/src/app/shared/components/confirmations/confirmations.component.html
index db3f1f38a..4ad3cb33a 100644
--- a/frontend/src/app/shared/components/confirmations/confirmations.component.html
+++ b/frontend/src/app/shared/components/confirmations/confirmations.component.html
@@ -1,19 +1,19 @@
-
- Confirmed
+ Confirmed
- Replaced
+ Replaced
- Removed
+ Removed
- Unconfirmed
+ Unconfirmed
\ No newline at end of file
diff --git a/frontend/src/app/shared/components/confirmations/confirmations.component.scss b/frontend/src/app/shared/components/confirmations/confirmations.component.scss
index e69de29bb..c8af7dd76 100644
--- a/frontend/src/app/shared/components/confirmations/confirmations.component.scss
+++ b/frontend/src/app/shared/components/confirmations/confirmations.component.scss
@@ -0,0 +1,4 @@
+.no-cursor {
+ cursor: default !important;
+ pointer-events: none;
+}
\ No newline at end of file
From c1b2f1f2c7d575b65ca679aa55577f9e373df7a2 Mon Sep 17 00:00:00 2001
From: wiz
Date: Fri, 25 Aug 2023 23:24:51 +0900
Subject: [PATCH 049/128] ops: Disable tor in prod install script
---
production/install | 71 +++++++++++++++++++++++++++-------------------
1 file changed, 42 insertions(+), 29 deletions(-)
diff --git a/production/install b/production/install
index 67e2f7d78..13449a904 100755
--- a/production/install
+++ b/production/install
@@ -1857,22 +1857,22 @@ ln -s "${MEMPOOL_HOME}/mempool" "${NGINX_ETC_FOLDER}/mempool"
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_USER__!${NGINX_USER}!" "${NGINX_CONFIGURATION}"
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_ETC_FOLDER__!${NGINX_ETC_FOLDER}!" "${NGINX_CONFIGURATION}"
-if [ "${TOR_INSTALL}" = ON ];then
- echo "[*] Read tor v3 onion hostnames"
-
- NGINX_MEMPOOL_ONION=$(cat "${TOR_RESOURCES}/mempool/hostname")
- osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_MEMPOOL_ONION__!${NGINX_MEMPOOL_ONION%.onion}!" "${NGINX_CONFIGURATION}"
-
- if [ "${ELEMENTS_LIQUID_ENABLE}" = "ON" ];then
- NGINX_LIQUID_ONION=$(cat "${TOR_RESOURCES}/liquid/hostname")
- osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_LIQUID_ONION__!${NGINX_LIQUID_ONIONi%.onion}!" "${NGINX_CONFIGURATION}"
- fi
-
- if [ "${BISQ_MAINNET_ENABLE}" = "ON" ];then
- NGINX_BISQ_ONION=$(cat "${TOR_RESOURCES}/bisq/hostname")
- osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_BISQ_ONION__!${NGINX_BISQ_ONION%.onion}!" "${NGINX_CONFIGURATION}"
- fi
-fi
+#if [ "${TOR_INSTALL}" = ON ];then
+# echo "[*] Read tor v3 onion hostnames"
+#
+# NGINX_MEMPOOL_ONION=$(cat "${TOR_RESOURCES}/mempool/hostname")
+# osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_MEMPOOL_ONION__!${NGINX_MEMPOOL_ONION%.onion}!" "${NGINX_CONFIGURATION}"
+#
+# if [ "${ELEMENTS_LIQUID_ENABLE}" = "ON" ];then
+# NGINX_LIQUID_ONION=$(cat "${TOR_RESOURCES}/liquid/hostname")
+# osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_LIQUID_ONION__!${NGINX_LIQUID_ONIONi%.onion}!" "${NGINX_CONFIGURATION}"
+# fi
+#
+# if [ "${BISQ_MAINNET_ENABLE}" = "ON" ];then
+# NGINX_BISQ_ONION=$(cat "${TOR_RESOURCES}/bisq/hostname")
+# osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_BISQ_ONION__!${NGINX_BISQ_ONION%.onion}!" "${NGINX_CONFIGURATION}"
+# fi
+#fi
##### OS systemd
@@ -1896,13 +1896,26 @@ echo "[*] Updating system startup configuration"
case $OS in
FreeBSD)
- echo 'nginx_enable="YES"' >> /etc/rc.conf
- echo 'bitcoin_enable="YES"' >> /etc/rc.conf
- echo 'tor_enable="YES"' >> /etc/rc.conf
- echo 'postfix_enable="YES"' >> /etc/rc.conf
- echo 'mysql_enable="YES"' >> /etc/rc.conf
- echo 'mysql_dbdir="/mysql"' >> /etc/rc.conf
- echo 'tor_enable="YES"' >> /etc/rc.conf
+ cat >> /etc/rc.conf <
Date: Fri, 25 Aug 2023 23:29:03 +0900
Subject: [PATCH 050/128] ops: Increase FreeBSD bitcoin node shutdown timeout
to 600
---
production/freebsd/rc.d/bitcoin | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/production/freebsd/rc.d/bitcoin b/production/freebsd/rc.d/bitcoin
index 76c217589..c22fbbabc 100644
--- a/production/freebsd/rc.d/bitcoin
+++ b/production/freebsd/rc.d/bitcoin
@@ -48,7 +48,7 @@ load_rc_config ${name}
: ${bitcoin_syslog_facility:="local0"}
: ${bitcoin_syslog_priority:="info"}
: ${bitcoin_syslog_tag:="bitcoin"}
-: ${bitcoin_kill_after:="300"}
+: ${bitcoin_kill_after:="600"}
: ${bitcoinlimits_args:="-e -U ${bitcoin_user}"}
# set up dependant variables
From 0fde6dd908864b741fa0adb82e6fb007a462a1a1 Mon Sep 17 00:00:00 2001
From: wiz
Date: Fri, 25 Aug 2023 23:34:50 +0900
Subject: [PATCH 051/128] ops: Bump prod NodeJS version to v20.5.1
---
production/install | 8 +++-----
production/mempool-start-all | 2 +-
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/production/install b/production/install
index 13449a904..7ab1e657b 100755
--- a/production/install
+++ b/production/install
@@ -1045,11 +1045,9 @@ osSudo "${ROOT_USER}" crontab -u "${MEMPOOL_USER}" "${MEMPOOL_HOME}/${MEMPOOL_RE
echo "[*] Installing nvm.sh from GitHub"
osSudo "${MEMPOOL_USER}" sh -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh'
-echo "[*] Building NodeJS v20.4.0 via nvm.sh"
-osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v20.4.0 --shared-zlib'
-echo "[*] Building NodeJS v18.16.1 via nvm.sh"
-osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v18.16.1 --shared-zlib'
-osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm alias default 18.16.1'
+echo "[*] Building NodeJS v20.5.1 via nvm.sh"
+osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v20.5.1 --shared-zlib'
+osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm alias default 20.5.1'
####################
# Tor installation #
diff --git a/production/mempool-start-all b/production/mempool-start-all
index 7efbf7dd6..5b4f85577 100755
--- a/production/mempool-start-all
+++ b/production/mempool-start-all
@@ -1,7 +1,7 @@
#!/usr/bin/env zsh
export NVM_DIR="$HOME/.nvm"
source "$NVM_DIR/nvm.sh"
-nvm use v20.4.0
+nvm use v20.5.1
# start all mempool backends that exist
for site in mainnet mainnet-lightning testnet testnet-lightning signet signet-lightning bisq liquid liquidtestnet;do
From dc44f1b618cf364a1eeddbb6c298cf1fca9ed47c Mon Sep 17 00:00:00 2001
From: wiz
Date: Sat, 26 Aug 2023 04:40:12 +0900
Subject: [PATCH 052/128] ops: Fix WebGL for unfurler
---
unfurler/puppeteer.config.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/unfurler/puppeteer.config.json b/unfurler/puppeteer.config.json
index 4d525755e..583ce7148 100644
--- a/unfurler/puppeteer.config.json
+++ b/unfurler/puppeteer.config.json
@@ -42,6 +42,6 @@
"--use-mock-keychain",
"--ignore-gpu-blacklist",
"--ignore-gpu-blocklist",
- "--use-gl=egl"
+ "--use-angle=default"
]
}
From d42a3f74ec895f5b5921a2669b0daf55196d6964 Mon Sep 17 00:00:00 2001
From: hunicus <93150691+hunicus@users.noreply.github.com>
Date: Sat, 26 Aug 2023 14:18:55 +0900
Subject: [PATCH 053/128] Add description to index html and seo service
---
frontend/src/app/services/seo.service.ts | 6 ++++++
frontend/src/index.bisq.html | 18 +++++++++---------
frontend/src/index.liquid.html | 17 +++++++++--------
frontend/src/index.mempool.html | 17 +++++++++--------
4 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/frontend/src/app/services/seo.service.ts b/frontend/src/app/services/seo.service.ts
index 4fc25be52..37387e6bf 100644
--- a/frontend/src/app/services/seo.service.ts
+++ b/frontend/src/app/services/seo.service.ts
@@ -52,6 +52,12 @@ export class SeoService {
this.resetTitle();
}
+ setDescription(newDescription: string): void {
+ this.metaService.updateTag({ name: 'description', content: newDescription});
+ this.metaService.updateTag({ name: 'twitter:description', content: newDescription});
+ this.metaService.updateTag({ property: 'og:description', content: newDescription});
+ }
+
getTitle(): string {
if (this.network === 'testnet')
return this.baseTitle + ' - Bitcoin Testnet';
diff --git a/frontend/src/index.bisq.html b/frontend/src/index.bisq.html
index 6d3bcb130..614c06bd4 100644
--- a/frontend/src/index.bisq.html
+++ b/frontend/src/index.bisq.html
@@ -7,18 +7,18 @@
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/frontend/src/index.liquid.html b/frontend/src/index.liquid.html
index ce57e5873..37e4241a0 100644
--- a/frontend/src/index.liquid.html
+++ b/frontend/src/index.liquid.html
@@ -7,18 +7,19 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/frontend/src/index.mempool.html b/frontend/src/index.mempool.html
index ec026b63b..e0816f6b3 100644
--- a/frontend/src/index.mempool.html
+++ b/frontend/src/index.mempool.html
@@ -7,18 +7,19 @@
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
From fcecbe49677144328c743ba86b6d3fbd95305cc8 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Sat, 26 Aug 2023 09:52:55 +0200
Subject: [PATCH 054/128] [tx] integrated accelerator
---
.../accelerate-preview.component.html | 231 ++++++++++++++++++
.../accelerate-preview.component.scss | 20 ++
.../accelerate-preview.component.ts | 163 +++++++++++-
.../transaction/transaction.component.html | 32 +--
.../transaction/transaction.component.scss | 59 +++--
.../transaction/transaction.component.ts | 7 +-
frontend/src/app/services/api.service.ts | 4 +
.../mempool-error.component.html | 2 +
.../mempool-error/mempool-error.component.ts | 47 ++++
frontend/src/app/shared/shared.module.ts | 8 +-
10 files changed, 519 insertions(+), 54 deletions(-)
create mode 100644 frontend/src/app/shared/components/mempool-error/mempool-error.component.html
create mode 100644 frontend/src/app/shared/components/mempool-error/mempool-error.component.ts
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
index e69de29bb..e2c6e3c22 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
@@ -0,0 +1,231 @@
+
+
+
+ Transaction has now been submitted to mining pools for acceleration. You can track the progress here.
+
+
+
+
+
+
+ 1">
+
+
+ This transactions is part of a CPFP tree. Fee rates (in sats/vb) are provided for your information. Change in the CPFP tree will lead to different fee rates values.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Next block market price
+ |
+
+ {{ estimate.targetFeeRate | number : '1.0-0' }} sat/vB
+ |
+
+
+
+ Currently estimated fee to get into next block
+ |
+
+
+ {{ estimate.nextBlockFee| number }} sats
+
+
+ |
+
+
+
+
+
+ Fees paid in-band
+ |
+
+ ~{{ (estimate.txSummary.effectiveFee / estimate.txSummary.effectiveVsize) | number : '1.0-0' }} sat/vB
+ |
+
+
+
+ What you already paid when you made the transaction
+ |
+
+
+ {{ estimate.txSummary.effectiveFee | number }} sats
+
+
+ |
+
+
+
+
+
+ Extra fee required
+ |
+
+ {{ math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee) | number }} sats
+
+ |
+
+
+
+ Difference between the next block fee and your tx fee
+ |
+
+
+
+
+
+
+ How much more are you willing to pay at most to get into the next block?
+
+
+
+ The maximum extra transaction fee you're willing to pay to get into the next block. If the next block market price becomes too expensive for you, we will automatically cancel your acceleration request. Final charged fee may be smaller based on the fee market.
+
+
+
+
+
+ Acceleration summary
+
+
+
+
+
+
+
+ Your maximum tx fees
+ |
+
+ ~{{ ((estimate.txSummary.effectiveFee + userBid) / estimate.txSummary.effectiveVsize) | number : '1.0-0' }} sat/vB
+ |
+
+
+
+ The maximum extra transaction fee you're willing to pay
+ |
+
+
+ {{ userBid | number }} sats
+
+
+ |
+
+
+
+
+
+ Mempool Acceleratorâ„¢ fee
+ |
+
+ +{{ estimate.mempoolBaseFee + estimate.vsizeFee | number }} sats
+
+ |
+
+
+
+ mempool.space fee
+ |
+
+
+ {{ estimate.mempoolBaseFee | number }} sats
+
+
+ |
+
+
+
+ Transaction vsize fee
+ |
+
+
+ {{ estimate.vsizeFee | number }} sats
+
+
+ |
+
+
+
+
+
+ Estimated acceleration cost
+ |
+
+
+ {{ estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee | number }} satss
+
+
+ |
+
+
+
+ Cost if your tx is accelerated using {{ estimate.targetFeeRate | number : '1.0-0' }} sat/vB
+ |
+
+
+
+
+
+ Maximum acceleration cost
+ |
+
+ {{ maxCost | number }} satss
+
+
+
+ |
+
+
+
+ Cost if your tx is accelerated using ~{{ ((estimate.txSummary.effectiveFee + userBid) / estimate.txSummary.effectiveVsize) | number : '1.0-0' }} sat/vB
+ |
+
+
+
+
+
+ Available balance
+ |
+
+ {{ estimate.userBalance | number }} satss
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss
index e69de29bb..b6981b8a7 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss
@@ -0,0 +1,20 @@
+.fee-card {
+ padding: 15px;
+ background-color: #1d1f31;
+}
+
+.btn-border {
+ border: solid 1px black;
+ background-color: #0c4a87;
+}
+
+.feerate.active {
+ background-color: #105fb0 !important;
+ opacity: 1;
+ border: 1px solid white !important;
+}
+
+.estimateDisabled {
+ opacity: 0.5;
+ pointer-events: none;
+}
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts
index dc8b9b5df..bea0efb88 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts
@@ -1,24 +1,169 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges } from '@angular/core';
+import { ApiService } from '../../services/api.service';
+import { Subscription, catchError, of, tap } from 'rxjs';
+
+export type AccelerationEstimate = {
+ txSummary: TxSummary;
+ nextBlockFee: number;
+ targetFeeRate: number;
+ userBalance: number;
+ enoughBalance: boolean;
+ cost: number;
+ mempoolBaseFee: number;
+ vsizeFee: number;
+}
+export type TxSummary = {
+ txid: string; // txid of the current transaction
+ effectiveVsize: number; // Total vsize of the dependency tree
+ effectiveFee: number; // Total fee of the dependency tree in sats
+ ancestorCount: number; // Number of ancestors
+}
+
+export const DEFAULT_BID_RATIO = 5;
+export const MIN_BID_RATIO = 2;
+export const MAX_BID_RATIO = 20;
@Component({
- selector: 'app-accelerator-preview',
+ selector: 'app-accelerate-preview',
templateUrl: 'accelerate-preview.component.html',
styleUrls: ['accelerate-preview.component.scss']
})
+export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges {
+ @Input() txid: string | undefined;
+ @Input() scrollEvent: boolean;
+
+ math = Math;
+ error = '';
+ showSuccess = false;
+ estimateSubscription: Subscription;
+ accelerationSubscription: Subscription;
+ estimate: any;
+ minExtraCost = 0;
+ minBidAllowed = 0;
+ maxBidAllowed = 0;
+ defaultBid = 0;
+ maxCost = 0;
+ userBid = 0;
+ selectFeeRateIndex = 2;
-export class AcceleratePreviewComponent implements OnInit {
constructor(
private apiService: ApiService
) { }
+ ngOnDestroy(): void {
+ if (this.estimateSubscription) {
+ this.estimateSubscription.unsubscribe();
+ }
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ if (changes.scrollEvent) {
+ this.scrollToPreview('acceleratePreviewAnchor', 'center');
+ }
+ }
+
ngOnInit() {
- this.apiService.estimate$(this.txId).subscribe((estimate) => {
- console.log(estimate.body);
- document.getElementById('acceleratePreviewAnchor').scrollIntoView({
+ this.estimateSubscription = this.apiService.estimate$(this.txid).pipe(
+ tap((response) => {
+ if (response.status === 204) {
+ this.estimate = undefined;
+ this.error = `cannot_accelerate_tx`;
+ this.scrollToPreviewWithTimeout('mempoolError', 'center');
+ this.estimateSubscription.unsubscribe();
+ } else {
+ this.estimate = response.body;
+ if (!this.estimate) {
+ this.error = `cannot_accelerate_tx`;
+ this.scrollToPreviewWithTimeout('mempoolError', 'center');
+ this.estimateSubscription.unsubscribe();
+ }
+
+ if (this.estimate.userBalance <= 0) {
+ this.error = `not_enough_balance`;
+ this.scrollToPreviewWithTimeout('mempoolError', 'center');
+ }
+
+ // Make min extra fee at least 50% of the current tx fee
+ this.minExtraCost = Math.max(this.estimate.cost, this.estimate.txSummary.effectiveFee / 2);
+ this.minExtraCost = Math.round(this.minExtraCost);
+
+ this.minBidAllowed = this.minExtraCost * MIN_BID_RATIO;
+ this.maxBidAllowed = this.minExtraCost * MAX_BID_RATIO;
+ this.defaultBid = this.minExtraCost * DEFAULT_BID_RATIO;
+
+ this.userBid = this.defaultBid;
+ if (this.userBid < this.minBidAllowed) {
+ this.userBid = this.minBidAllowed;
+ } else if (this.userBid > this.maxBidAllowed) {
+ this.userBid = this.maxBidAllowed;
+ }
+ this.maxCost = this.userBid + this.estimate.mempoolBaseFee + this.estimate.vsizeFee;
+
+ if (!this.error) {
+ this.scrollToPreview('acceleratePreviewAnchor', 'center');
+ }
+ }
+ }),
+ catchError((response) => {
+ this.estimate = undefined;
+ this.error = response.error;
+ this.scrollToPreviewWithTimeout('mempoolError', 'center');
+ this.estimateSubscription.unsubscribe();
+ return of(null);
+ })
+ ).subscribe();
+ }
+
+ /**
+ * User changed his bid
+ */
+ setUserBid(multiplier: number, index: number) {
+ if (this.estimate) {
+ this.selectFeeRateIndex = index;
+ this.userBid = Math.max(0, this.minExtraCost * multiplier);
+ this.maxCost = this.userBid + this.estimate.mempoolBaseFee + this.estimate.vsizeFee;
+ }
+ }
+
+ /**
+ * Scroll to element id with or without setTimeout
+ */
+ scrollToPreviewWithTimeout(id: string, position: ScrollLogicalPosition) {
+ setTimeout(() => {
+ this.scrollToPreview(id, position);
+ }, 100);
+ }
+ scrollToPreview(id: string, position: ScrollLogicalPosition) {
+ const acceleratePreviewAnchor = document.getElementById(id);
+ if (acceleratePreviewAnchor) {
+ acceleratePreviewAnchor.scrollIntoView({
behavior: 'smooth',
- inline: 'center',
- block: 'center',
+ inline: position,
+ block: position,
});
- })
+ }
+}
+
+ /**
+ * Send acceleration request
+ */
+ accelerate() {
+ if (this.accelerationSubscription) {
+ this.accelerationSubscription.unsubscribe();
+ }
+ this.accelerationSubscription = this.apiService.accelerate$(
+ this.txid,
+ this.userBid
+ ).subscribe({
+ next: () => {
+ this.showSuccess = true;
+ this.scrollToPreviewWithTimeout('successAlert', 'center');
+ this.estimateSubscription.unsubscribe();
+ },
+ error: (response) => {
+ this.error = response.error;
+ this.scrollToPreviewWithTimeout('mempoolError', 'center');
+ }
+ });
}
}
\ No newline at end of file
diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html
index 36c7ab9f3..f7dd45d3b 100644
--- a/frontend/src/app/components/transaction/transaction.component.html
+++ b/frontend/src/app/components/transaction/transaction.component.html
@@ -6,7 +6,7 @@
-
+
Accelerate this transaction using the Mempool Accelerator ™
×
@@ -78,33 +78,17 @@
+
Accelerate
-
-
-
@@ -132,10 +116,9 @@
= 7" [ngIfElse]="belowBlockLimit">
-
+
In several hours (or more)
-
- Accelerate
+ Accelerate
@@ -143,10 +126,9 @@
-
+
-
- Accelerate
+ Accelerate
diff --git a/frontend/src/app/components/transaction/transaction.component.scss b/frontend/src/app/components/transaction/transaction.component.scss
index 45357471a..2e076600e 100644
--- a/frontend/src/app/components/transaction/transaction.component.scss
+++ b/frontend/src/app/components/transaction/transaction.component.scss
@@ -130,7 +130,7 @@
}
.table {
- tr td {
+ tr td {
padding: 0.75rem 0.5rem;
@media (min-width: 576px) {
padding: 0.75rem 0.75rem;
@@ -138,7 +138,7 @@
&:last-child {
text-align: right;
@media (min-width: 850px) {
- text-align: left;
+ text-align: left;
}
}
.btn {
@@ -218,25 +218,52 @@
}
}
-.eta {
- display: flex;
- justify-content: end;
- flex-wrap: wrap;
- align-content: center;
- @media (min-width: 850px) {
- justify-content: space-between;
- }
-}
-
.link.accelerator {
cursor: pointer;
}
+.eta {
+ display: flex;
+ flex-wrap: wrap;
+ align-content: center;
+ @media (min-width: 850px) {
+ justify-content: left !important;
+ }
+}
+
.accelerate {
+ display: flex !important;
align-self: auto;
margin-top: 3px;
- margin-left: 10px;
- @media (min-width: 850px) {
- justify-self: start;
+ margin-left: auto;
+ background-color: #653b9c;
+ @media (max-width: 849px) {
+ margin-left: 5px;
}
-}
\ No newline at end of file
+}
+
+.etaDeepMempool {
+ display: flex !important;
+ justify-content: end;
+ flex-wrap: wrap;
+ align-content: center;
+ @media (max-width: 995px) {
+ justify-content: left !important;
+ }
+ @media (max-width: 849px) {
+ justify-content: right !important;
+ }
+}
+
+.accelerateDeepMempool {
+ align-self: auto;
+ margin-top: 3px;
+ margin-left: auto;
+ background-color: #653b9c;
+ @media (max-width: 995px) {
+ margin-left: 0px;
+ }
+ @media (max-width: 849px) {
+ margin-left: 5px;
+ }
+}
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index c3e4cc25c..ac1452835 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -83,7 +83,6 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
blockConversion: Price;
tooltipPosition: { x: number, y: number };
isMobile: boolean;
- acceleratorAvailable: boolean = false;
featuresEnabled: boolean;
segwitEnabled: boolean;
@@ -93,6 +92,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
accelerateCtaType: 'alert' | 'button' = 'alert';
acceleratorAvailable: boolean = this.stateService.env.OFFICIAL_MEMPOOL_SPACE && this.stateService.env.ACCELERATOR && this.stateService.network === '';
showAccelerationSummary = false;
+ scrollIntoAccelPreview = false;
@ViewChild('graphContainer')
graphContainer: ElementRef;
@@ -504,12 +504,13 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.accelerateCtaType = 'button';
}
- onAccelerateClicked(): void {
+ onAccelerateClicked() {
if (!this.txId) {
return;
}
-
this.showAccelerationSummary = true && this.acceleratorAvailable;
+ this.scrollIntoAccelPreview = !this.scrollIntoAccelPreview;
+ return false;
}
handleLoadElectrsTransactionError(error: any): Observable {
diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts
index 2d9077a97..ea185b1ec 100644
--- a/frontend/src/app/services/api.service.ts
+++ b/frontend/src/app/services/api.service.ts
@@ -392,4 +392,8 @@ export class ApiService {
estimate$(txInput: string) {
return this.httpClient.post(`${SERVICES_API_PREFIX}/accelerator/estimate`, { txInput: txInput }, { observe: 'response' });
}
+
+ accelerate$(txInput: string, userBid: number) {
+ return this.httpClient.post(`${SERVICES_API_PREFIX}/accelerator/accelerate`, { txInput: txInput, userBid: userBid });
+ }
}
diff --git a/frontend/src/app/shared/components/mempool-error/mempool-error.component.html b/frontend/src/app/shared/components/mempool-error/mempool-error.component.html
new file mode 100644
index 000000000..020b147a9
--- /dev/null
+++ b/frontend/src/app/shared/components/mempool-error/mempool-error.component.html
@@ -0,0 +1,2 @@
+
+
diff --git a/frontend/src/app/shared/components/mempool-error/mempool-error.component.ts b/frontend/src/app/shared/components/mempool-error/mempool-error.component.ts
new file mode 100644
index 000000000..19e057950
--- /dev/null
+++ b/frontend/src/app/shared/components/mempool-error/mempool-error.component.ts
@@ -0,0 +1,47 @@
+import { Component, Input, OnInit } from "@angular/core";
+import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
+
+const MempoolErrors = {
+ 'acceleration_duplicated': `This transaction has already been accelerated.`,
+ 'acceleration_outbid': `Your fee delta is too low.`,
+ 'cannot_accelerate_tx': `Cannot accelerate this transaction.`,
+ 'cannot_decode_raw_tx': `Cannot decode this raw transaction.`,
+ 'cannot_fetch_raw_tx': `Cannot find this transaction.`,
+ 'database_error': `Something went wrong. Please try again later.`,
+ 'high_sigop_tx': `This transaction cannot be accelerated.`,
+ 'invalid_acceleration_request': `This acceleration request is not valid.`,
+ 'invalid_tx_dependencies': `This transaction dependencies are not valid.`,
+ 'mempool_rejected_raw_tx': `Our mempool rejected this transaction`,
+ 'no_mining_pool_available': `No mining pool available at the moment`,
+ 'not_available': `You current subscription does not allow you to access this feature. Consider upgrading.`,
+ 'not_enough_balance': `Your account balance is too low. Please make a deposit.`,
+ 'not_verified': `You must verify your account to use this feature.`,
+ 'recommended_fees_not_available': `Recommended fees are not available right now.`,
+ 'too_many_relatives': `This transaction has too many relatives.`,
+ 'txid_not_in_mempool': `This transaction is not in the mempool.`,
+ 'waitlisted': `You are currently on the wait list. You will get notified once you are granted access.`,
+ 'not_whitelisted_by_any_pool': `You are not whitelisted by any mining pool`,
+} as { [error: string]: string };
+
+export function isMempoolError(error: string) {
+ return Object.keys(MempoolErrors).includes(error);
+}
+
+@Component({
+ selector: 'app-mempool-error',
+ templateUrl: './mempool-error.component.html'
+})
+export class MempoolErrorComponent implements OnInit {
+ @Input() error: string;
+ errorContent: SafeHtml;
+
+ constructor(private sanitizer: DomSanitizer) { }
+
+ ngOnInit(): void {
+ if (Object.keys(MempoolErrors).includes(this.error)) {
+ this.errorContent = this.sanitizer.bypassSecurityTrustHtml(MempoolErrors[this.error]);
+ } else {
+ this.errorContent = this.error;
+ }
+ }
+}
diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts
index 891f8f987..d77eea2cf 100644
--- a/frontend/src/app/shared/shared.module.ts
+++ b/frontend/src/app/shared/shared.module.ts
@@ -93,6 +93,8 @@ import { ToggleComponent } from './components/toggle/toggle.component';
import { GeolocationComponent } from '../shared/components/geolocation/geolocation.component';
import { TestnetAlertComponent } from './components/testnet-alert/testnet-alert.component';
import { GlobalFooterComponent } from './components/global-footer/global-footer.component';
+import { AcceleratePreviewComponent } from '../components/accelerate-preview/accelerate-preview.component';
+import { MempoolErrorComponent } from './components/mempool-error/mempool-error.component';
import { MempoolBlockOverviewComponent } from '../components/mempool-block-overview/mempool-block-overview.component';
import { ClockchainComponent } from '../components/clockchain/clockchain.component';
@@ -189,6 +191,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
GeolocationComponent,
TestnetAlertComponent,
GlobalFooterComponent,
+ AcceleratePreviewComponent,
CalculatorComponent,
BitcoinsatoshisPipe,
MempoolBlockOverviewComponent,
@@ -196,7 +199,8 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
ClockComponent,
ClockFaceComponent,
OnlyVsizeDirective,
- OnlyWeightDirective
+ OnlyWeightDirective,
+ MempoolErrorComponent,
],
imports: [
CommonModule,
@@ -310,6 +314,8 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
GeolocationComponent,
PreviewTitleComponent,
GlobalFooterComponent,
+ AcceleratePreviewComponent,
+ MempoolErrorComponent,
MempoolBlockOverviewComponent,
ClockchainComponent,
From 1fe08d1234d6cfcdbbe22d1aabfc9048e58a3ce9 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Sat, 26 Aug 2023 10:05:04 +0200
Subject: [PATCH 055/128] [accelerator] fix overflow in tx page integrated
accel
---
.../accelerate-preview/accelerate-preview.component.html | 4 ++--
.../accelerate-preview/accelerate-preview.component.scss | 7 +++++++
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
index e2c6e3c22..5afdc07f9 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
@@ -24,7 +24,7 @@
-
+
@@ -110,7 +110,7 @@
Acceleration summary
-
+
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss
index b6981b8a7..e6c717369 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.scss
@@ -18,3 +18,10 @@
opacity: 0.5;
pointer-events: none;
}
+
+.table-accelerator {
+ table-layout: fixed;
+ & tr {
+ text-wrap: wrap;
+ }
+}
\ No newline at end of file
From 726bd51abb9b26da9e3de74525df04fc9cb3780c Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Sat, 26 Aug 2023 11:27:45 +0200
Subject: [PATCH 056/128] [debug] update versioning print
---
frontend/src/app/interfaces/websocket.interface.ts | 2 +-
.../components/global-footer/global-footer.component.html | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/frontend/src/app/interfaces/websocket.interface.ts b/frontend/src/app/interfaces/websocket.interface.ts
index 43ab1e5f4..1d0414de7 100644
--- a/frontend/src/app/interfaces/websocket.interface.ts
+++ b/frontend/src/app/interfaces/websocket.interface.ts
@@ -95,7 +95,7 @@ export interface TransactionStripped {
}
export interface IBackendInfo {
- hostname: string;
+ hostname?: string;
gitCommit: string;
version: string;
}
diff --git a/frontend/src/app/shared/components/global-footer/global-footer.component.html b/frontend/src/app/shared/components/global-footer/global-footer.component.html
index 73b4d0975..b12874832 100644
--- a/frontend/src/app/shared/components/global-footer/global-footer.component.html
+++ b/frontend/src/app/shared/components/global-footer/global-footer.component.html
@@ -91,9 +91,11 @@
From a3d61fa52546b1406a8e932648c8c91b73055f5e Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Sat, 26 Aug 2023 15:07:05 +0200
Subject: [PATCH 057/128] [accelerator] show payment preview when not logged in
---
.../accelerate-preview.component.html | 2 +-
.../accelerate-preview.component.ts | 15 ++++++++++++---
frontend/src/app/services/api.service.ts | 12 +++---------
3 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
index 5afdc07f9..c546d3859 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
@@ -219,7 +219,7 @@
-
+
Accelerate
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts
index bea0efb88..b4c7af704 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.ts
@@ -1,6 +1,7 @@
import { Component, OnInit, Input, OnDestroy, OnChanges, SimpleChanges } from '@angular/core';
import { ApiService } from '../../services/api.service';
import { Subscription, catchError, of, tap } from 'rxjs';
+import { StorageService } from '../../services/storage.service';
export type AccelerationEstimate = {
txSummary: TxSummary;
@@ -47,7 +48,8 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
selectFeeRateIndex = 2;
constructor(
- private apiService: ApiService
+ private apiService: ApiService,
+ private storageService: StorageService
) { }
ngOnDestroy(): void {
@@ -79,8 +81,10 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
}
if (this.estimate.userBalance <= 0) {
- this.error = `not_enough_balance`;
- this.scrollToPreviewWithTimeout('mempoolError', 'center');
+ if (this.isLoggedIn()) {
+ this.error = `not_enough_balance`;
+ this.scrollToPreviewWithTimeout('mempoolError', 'center');
+ }
}
// Make min extra fee at least 50% of the current tx fee
@@ -166,4 +170,9 @@ export class AcceleratePreviewComponent implements OnInit, OnDestroy, OnChanges
}
});
}
+
+ isLoggedIn() {
+ const auth = this.storageService.getAuth();
+ return auth !== null;
+ }
}
\ No newline at end of file
diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts
index ea185b1ec..744474f9d 100644
--- a/frontend/src/app/services/api.service.ts
+++ b/frontend/src/app/services/api.service.ts
@@ -357,9 +357,7 @@ export class ApiService {
return of(null);
}
- return this.httpClient.get (`${SERVICES_API_PREFIX}/account/menu`, {
- headers: { 'Authorization': auth.token }
- });
+ return this.httpClient.get(`${SERVICES_API_PREFIX}/account/menu`);
}
getUserInfo$(): Observable {
@@ -368,9 +366,7 @@ export class ApiService {
return of(null);
}
- return this.httpClient.get(`${SERVICES_API_PREFIX}/account`, {
- headers: { 'Authorization': auth.token }
- });
+ return this.httpClient.get(`${SERVICES_API_PREFIX}/account`);
}
logout$(): Observable {
@@ -380,9 +376,7 @@ export class ApiService {
}
localStorage.removeItem('auth');
- return this.httpClient.post(`${SERVICES_API_PREFIX}/auth/logout`, {
- headers: { 'Authorization': auth.token }
- });
+ return this.httpClient.post(`${SERVICES_API_PREFIX}/auth/logout`, {});
}
getServicesBackendInfo$(): Observable {
From 528877f43f1f1a8fc3f74a96e97f042cf9469617 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Sun, 27 Aug 2023 00:30:33 +0900
Subject: [PATCH 058/128] Send cpfp/effective fee rate changes to subscribed ws
clients
---
backend/src/api/mempool-blocks.ts | 13 ++++
backend/src/api/websocket-handler.ts | 16 ++++-
backend/src/mempool.interfaces.ts | 1 +
.../transaction/transaction.component.ts | 64 +++++++++++--------
.../src/app/interfaces/electrs.interface.ts | 2 +-
.../src/app/interfaces/node-api.interface.ts | 2 +-
frontend/src/app/services/state.service.ts | 4 +-
7 files changed, 68 insertions(+), 34 deletions(-)
diff --git a/backend/src/api/mempool-blocks.ts b/backend/src/api/mempool-blocks.ts
index 1de4bbee7..15f9b6cf7 100644
--- a/backend/src/api/mempool-blocks.ts
+++ b/backend/src/api/mempool-blocks.ts
@@ -451,6 +451,7 @@ class MempoolBlocks {
private processBlockTemplates(mempool: { [txid: string]: MempoolTransactionExtended }, blocks: string[][], blockWeights: number[] | null, rates: [string, number][], clusters: string[][], accelerations, accelerationPool, saveResults): MempoolBlockWithTransactions[] {
for (const [txid, rate] of rates) {
if (txid in mempool) {
+ mempool[txid].cpfpDirty = (rate !== mempool[txid].effectiveFeePerVsize);
mempool[txid].effectiveFeePerVsize = rate;
mempool[txid].cpfpChecked = false;
}
@@ -494,6 +495,9 @@ class MempoolBlocks {
}
}
});
+ if (mempoolTx.ancestors?.length !== ancestors.length || mempoolTx.descendants?.length !== descendants.length) {
+ mempoolTx.cpfpDirty = true;
+ }
Object.assign(mempoolTx, {ancestors, descendants, bestDescendant: null, cpfpChecked: true});
}
}
@@ -531,12 +535,21 @@ class MempoolBlocks {
const acceleration = accelerations[txid];
if (isAccelerated[txid] || (acceleration && (!accelerationPool || acceleration.pools.includes(accelerationPool)))) {
+ if (!mempoolTx.acceleration) {
+ mempoolTx.cpfpDirty = true;
+ }
mempoolTx.acceleration = true;
for (const ancestor of mempoolTx.ancestors || []) {
+ if (!mempool[ancestor.txid].acceleration) {
+ mempool[ancestor.txid].cpfpDirty = true;
+ }
mempool[ancestor.txid].acceleration = true;
isAccelerated[ancestor.txid] = true;
}
} else {
+ if (mempoolTx.acceleration) {
+ mempoolTx.cpfpDirty = true;
+ }
delete mempoolTx.acceleration;
}
diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts
index 9cb24df10..41cb6b99c 100644
--- a/backend/src/api/websocket-handler.ts
+++ b/backend/src/api/websocket-handler.ts
@@ -586,13 +586,25 @@ class WebsocketHandler {
const mempoolTx = newMempool[trackTxid];
if (mempoolTx && mempoolTx.position) {
- response['txPosition'] = JSON.stringify({
+ const positionData = {
txid: trackTxid,
position: {
...mempoolTx.position,
accelerated: mempoolTx.acceleration || undefined,
}
- });
+ };
+ if (mempoolTx.cpfpDirty) {
+ positionData['cpfp'] = {
+ ancestors: mempoolTx.ancestors,
+ bestDescendant: mempoolTx.bestDescendant || null,
+ descendants: mempoolTx.descendants || null,
+ effectiveFeePerVsize: mempoolTx.effectiveFeePerVsize || null,
+ sigops: mempoolTx.sigops,
+ adjustedVsize: mempoolTx.adjustedVsize,
+ acceleration: mempoolTx.acceleration
+ };
+ }
+ response['txPosition'] = JSON.stringify(positionData);
}
}
diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts
index c08846191..b013f2f26 100644
--- a/backend/src/mempool.interfaces.ts
+++ b/backend/src/mempool.interfaces.ts
@@ -104,6 +104,7 @@ export interface MempoolTransactionExtended extends TransactionExtended {
adjustedFeePerVsize: number;
inputs?: number[];
lastBoosted?: number;
+ cpfpDirty?: boolean;
}
export interface AuditTransaction {
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index f1f3850e4..216079535 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -161,34 +161,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
})
)
.subscribe((cpfpInfo) => {
- if (!cpfpInfo || !this.tx) {
- this.cpfpInfo = null;
- this.hasEffectiveFeeRate = false;
- return;
- }
- // merge ancestors/descendants
- const relatives = [...(cpfpInfo.ancestors || []), ...(cpfpInfo.descendants || [])];
- if (cpfpInfo.bestDescendant && !cpfpInfo.descendants?.length) {
- relatives.push(cpfpInfo.bestDescendant);
- }
- const hasRelatives = !!relatives.length;
- if (!cpfpInfo.effectiveFeePerVsize && hasRelatives) {
- let totalWeight =
- this.tx.weight +
- relatives.reduce((prev, val) => prev + val.weight, 0);
- let totalFees =
- this.tx.fee +
- relatives.reduce((prev, val) => prev + val.fee, 0);
- this.tx.effectiveFeePerVsize = totalFees / (totalWeight / 4);
- } else {
- this.tx.effectiveFeePerVsize = cpfpInfo.effectiveFeePerVsize;
- }
- if (cpfpInfo.acceleration) {
- this.tx.acceleration = cpfpInfo.acceleration;
- }
-
- this.cpfpInfo = cpfpInfo;
- this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01));
+ this.setCpfpInfo(cpfpInfo);
});
this.fetchRbfSubscription = this.fetchRbfHistory$
@@ -259,6 +232,10 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
mempoolPosition: this.mempoolPosition
});
this.txInBlockIndex = this.mempoolPosition.block;
+
+ if (txPosition.cpfp !== undefined) {
+ this.setCpfpInfo(txPosition.cpfp);
+ }
}
} else {
this.mempoolPosition = null;
@@ -507,6 +484,37 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
});
}
+ setCpfpInfo(cpfpInfo: CpfpInfo): void {
+ if (!cpfpInfo || !this.tx) {
+ this.cpfpInfo = null;
+ this.hasEffectiveFeeRate = false;
+ return;
+ }
+ // merge ancestors/descendants
+ const relatives = [...(cpfpInfo.ancestors || []), ...(cpfpInfo.descendants || [])];
+ if (cpfpInfo.bestDescendant && !cpfpInfo.descendants?.length) {
+ relatives.push(cpfpInfo.bestDescendant);
+ }
+ const hasRelatives = !!relatives.length;
+ if (!cpfpInfo.effectiveFeePerVsize && hasRelatives) {
+ const totalWeight =
+ this.tx.weight +
+ relatives.reduce((prev, val) => prev + val.weight, 0);
+ const totalFees =
+ this.tx.fee +
+ relatives.reduce((prev, val) => prev + val.fee, 0);
+ this.tx.effectiveFeePerVsize = totalFees / (totalWeight / 4);
+ } else {
+ this.tx.effectiveFeePerVsize = cpfpInfo.effectiveFeePerVsize;
+ }
+ if (cpfpInfo.acceleration) {
+ this.tx.acceleration = cpfpInfo.acceleration;
+ }
+
+ this.cpfpInfo = cpfpInfo;
+ this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01));
+ }
+
setFeatures(): void {
if (this.tx) {
this.segwitEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'segwit');
diff --git a/frontend/src/app/interfaces/electrs.interface.ts b/frontend/src/app/interfaces/electrs.interface.ts
index 5c15b0ae4..2d604a9de 100644
--- a/frontend/src/app/interfaces/electrs.interface.ts
+++ b/frontend/src/app/interfaces/electrs.interface.ts
@@ -19,7 +19,7 @@ export interface Transaction {
ancestors?: Ancestor[];
bestDescendant?: BestDescendant | null;
cpfpChecked?: boolean;
- acceleration?: number;
+ acceleration?: boolean;
deleteAfter?: number;
_unblinded?: any;
_deduced?: boolean;
diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts
index fbf86aeb4..a9f069b56 100644
--- a/frontend/src/app/interfaces/node-api.interface.ts
+++ b/frontend/src/app/interfaces/node-api.interface.ts
@@ -27,7 +27,7 @@ export interface CpfpInfo {
effectiveFeePerVsize?: number;
sigops?: number;
adjustedVsize?: number;
- acceleration?: number;
+ acceleration?: boolean;
}
export interface RbfInfo {
diff --git a/frontend/src/app/services/state.service.ts b/frontend/src/app/services/state.service.ts
index 91e4d7475..23bca052c 100644
--- a/frontend/src/app/services/state.service.ts
+++ b/frontend/src/app/services/state.service.ts
@@ -2,7 +2,7 @@ import { Inject, Injectable, PLATFORM_ID, LOCALE_ID } from '@angular/core';
import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable, merge } from 'rxjs';
import { Transaction } from '../interfaces/electrs.interface';
import { IBackendInfo, MempoolBlock, MempoolBlockDelta, MempoolInfo, Recommendedfees, ReplacedTransaction, ReplacementInfo, TransactionStripped } from '../interfaces/websocket.interface';
-import { BlockExtended, DifficultyAdjustment, MempoolPosition, OptimizedMempoolStats, RbfTree } from '../interfaces/node-api.interface';
+import { BlockExtended, CpfpInfo, DifficultyAdjustment, MempoolPosition, OptimizedMempoolStats, RbfTree } from '../interfaces/node-api.interface';
import { Router, NavigationStart } from '@angular/router';
import { isPlatformBrowser } from '@angular/common';
import { filter, map, scan, shareReplay } from 'rxjs/operators';
@@ -113,7 +113,7 @@ export class StateService {
utxoSpent$ = new Subject
-
+
Accelerate this transaction using the Mempool Accelerator ™
×
@@ -116,9 +116,9 @@
= 7" [ngIfElse]="belowBlockLimit">
-
+
In several hours (or more)
- Accelerate
+ Accelerate
@@ -128,7 +128,7 @@
- Accelerate
+ Accelerate
From 78ea9cbd16aefb433eff3014723b4369327f45a3 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Sun, 27 Aug 2023 12:52:58 +0200
Subject: [PATCH 060/128] [ui] polish x1
---
.../master-page/master-page.component.html | 4 +--
.../master-page/master-page.component.ts | 19 ++++++++++++--
.../src/app/components/menu/menu.component.ts | 25 +++++++++++--------
3 files changed, 33 insertions(+), 15 deletions(-)
diff --git a/frontend/src/app/components/master-page/master-page.component.html b/frontend/src/app/components/master-page/master-page.component.html
index b24442f23..74a95daf5 100644
--- a/frontend/src/app/components/master-page/master-page.component.html
+++ b/frontend/src/app/components/master-page/master-page.component.html
@@ -77,12 +77,12 @@
-
+
-
+
diff --git a/frontend/src/app/components/master-page/master-page.component.ts b/frontend/src/app/components/master-page/master-page.component.ts
index 06ec1784e..49bed7a5d 100644
--- a/frontend/src/app/components/master-page/master-page.component.ts
+++ b/frontend/src/app/components/master-page/master-page.component.ts
@@ -1,4 +1,5 @@
import { Component, OnInit, Input, ViewChild } from '@angular/core';
+import { Router } from '@angular/router';
import { Env, StateService } from '../../services/state.service';
import { Observable, merge, of } from 'rxjs';
import { LanguageService } from '../../services/language.service';
@@ -31,9 +32,10 @@ export class MasterPageComponent implements OnInit {
userAuth: any | undefined;
user: any = undefined;
servicesEnabled = false;
+ menuOpen = false;
@ViewChild(MenuComponent)
- private menuComponent!: MenuComponent;
+ public menuComponent!: MenuComponent;
constructor(
public stateService: StateService,
@@ -42,6 +44,7 @@ export class MasterPageComponent implements OnInit {
private navigationService: NavigationService,
private storageService: StorageService,
private apiService: ApiService,
+ private router: Router,
) { }
ngOnInit(): void {
@@ -65,14 +68,21 @@ export class MasterPageComponent implements OnInit {
this.servicesEnabled = this.officialMempoolSpace && this.stateService.env.ACCELERATOR === true && this.stateService.network === '';
this.refreshAuth();
+
+ const isServicesPage = this.router.url.includes('/services/');
+ this.menuOpen = isServicesPage && !this.isSmallScreen();
}
collapse(): void {
this.navCollapsed = !this.navCollapsed;
}
+ isSmallScreen() {
+ return window.innerWidth <= 767.98;
+ }
+
onResize(): void {
- this.isMobile = window.innerWidth <= 767.98;
+ this.isMobile = this.isSmallScreen();
}
brandClick(e): void {
@@ -90,7 +100,12 @@ export class MasterPageComponent implements OnInit {
hamburgerClick(event): void {
if (this.menuComponent) {
this.menuComponent.hamburgerClick();
+ this.menuOpen = this.menuComponent.navOpen;
event.stopPropagation();
}
}
+
+ menuToggled(isOpen: boolean): void {
+ this.menuOpen = isOpen;
+ }
}
diff --git a/frontend/src/app/components/menu/menu.component.ts b/frontend/src/app/components/menu/menu.component.ts
index a560a1b49..e6ba848bc 100644
--- a/frontend/src/app/components/menu/menu.component.ts
+++ b/frontend/src/app/components/menu/menu.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit, Output, EventEmitter, HostListener } from '@angular/core';
+import { Component, OnInit, Input, Output, EventEmitter, HostListener } from '@angular/core';
import { Observable } from 'rxjs';
import { ApiService } from '../../services/api.service';
import { MenuGroup } from '../../interfaces/services.interface';
@@ -13,9 +13,10 @@ import { StateService } from '../../services/state.service';
})
export class MenuComponent implements OnInit {
+ @Input() navOpen: boolean = false;
@Output() loggedOut = new EventEmitter();
-
- navOpen: boolean = false;
+ @Output() menuToggled = new EventEmitter();
+
userMenuGroups$: Observable | undefined;
userAuth: any | undefined;
isServicesPage = false;
@@ -34,17 +35,20 @@ export class MenuComponent implements OnInit {
}
this.isServicesPage = this.router.url.includes('/services/');
- this.navOpen = this.isServicesPage && !this.isSmallScreen();
-
this.router.events.subscribe((event) => {
if (event instanceof NavigationStart) {
if (!this.isServicesPage) {
- this.navOpen = false;
+ this.toggleMenu(false);
}
}
});
}
+ toggleMenu(toggled: boolean) {
+ this.navOpen = toggled;
+ this.menuToggled.emit(toggled);
+ }
+
isSmallScreen() {
return window.innerWidth <= 767.98;
}
@@ -61,13 +65,13 @@ export class MenuComponent implements OnInit {
onLinkClick(link) {
if (!this.isServicesPage || this.isSmallScreen()) {
- this.navOpen = false;
+ this.toggleMenu(false);
}
this.router.navigateByUrl(link);
}
hamburgerClick() {
- this.navOpen = !this.navOpen;
+ this.toggleMenu(!this.navOpen);
this.stateService.menuOpen$.next(this.navOpen);
}
@@ -78,7 +82,7 @@ export class MenuComponent implements OnInit {
if (!cssClasses.indexOf) { // Click on chart or non html thingy, close the menu
if (!this.isServicesPage || isServicesPageOnMobile) {
- this.navOpen = false;
+ this.toggleMenu(false);
}
return;
}
@@ -86,8 +90,7 @@ export class MenuComponent implements OnInit {
const isHamburger = cssClasses.indexOf('profile_image') !== -1;
const isMenu = cssClasses.indexOf('menu-click') !== -1;
if (!isHamburger && !isMenu && (!this.isServicesPage || isServicesPageOnMobile)) {
- this.navOpen = false;
- return;
+ this.toggleMenu(false);
}
}
}
From 8ba4a7b4218459bfca33d6ee8b99258c1179682b Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Sun, 27 Aug 2023 19:17:03 +0200
Subject: [PATCH 061/128] [ui] polish x2
---
.../app/components/master-page/master-page.component.scss | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/frontend/src/app/components/master-page/master-page.component.scss b/frontend/src/app/components/master-page/master-page.component.scss
index 9477ca792..f0fec0536 100644
--- a/frontend/src/app/components/master-page/master-page.component.scss
+++ b/frontend/src/app/components/master-page/master-page.component.scss
@@ -234,3 +234,8 @@ nav {
height: 35px;
border-radius: 5px;
}
+
+main {
+ transition: 0.2s;
+ transition-property: max-width;
+}
\ No newline at end of file
From 7fd8790750b151d37566ef6b0f91fd5837c93cf0 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Mon, 28 Aug 2023 09:29:13 +0200
Subject: [PATCH 062/128] [auth] fix blinking profile picture
---
.../app/components/master-page/master-page.component.ts | 3 +--
frontend/src/app/components/menu/menu.component.ts | 5 +++++
.../components/global-footer/global-footer.component.ts | 9 +--------
3 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/frontend/src/app/components/master-page/master-page.component.ts b/frontend/src/app/components/master-page/master-page.component.ts
index 49bed7a5d..a92f77cf9 100644
--- a/frontend/src/app/components/master-page/master-page.component.ts
+++ b/frontend/src/app/components/master-page/master-page.component.ts
@@ -29,7 +29,6 @@ export class MasterPageComponent implements OnInit {
networkPaths: { [network: string]: string };
networkPaths$: Observable>;
footerVisible = true;
- userAuth: any | undefined;
user: any = undefined;
servicesEnabled = false;
menuOpen = false;
@@ -94,7 +93,7 @@ export class MasterPageComponent implements OnInit {
}
refreshAuth(): void {
- this.apiService.getUserInfo$().subscribe(user => this.user = user);
+ this.user = this.storageService.getAuth()?.user ?? null;
}
hamburgerClick(event): void {
diff --git a/frontend/src/app/components/menu/menu.component.ts b/frontend/src/app/components/menu/menu.component.ts
index e6ba848bc..2fb5c34d1 100644
--- a/frontend/src/app/components/menu/menu.component.ts
+++ b/frontend/src/app/components/menu/menu.component.ts
@@ -30,6 +30,11 @@ export class MenuComponent implements OnInit {
ngOnInit(): void {
this.userAuth = this.storageService.getAuth();
+ if (this.userAuth && this.userAuth.user && !this.userAuth.user.imageMd5) {
+ this.logout();
+ return;
+ }
+
if (this.stateService.env.GIT_COMMIT_HASH_MEMPOOL_SPACE) {
this.userMenuGroups$ = this.apiService.getUserMenuGroups$();
}
diff --git a/frontend/src/app/shared/components/global-footer/global-footer.component.ts b/frontend/src/app/shared/components/global-footer/global-footer.component.ts
index 75d989ff7..e76a5de0d 100644
--- a/frontend/src/app/shared/components/global-footer/global-footer.component.ts
+++ b/frontend/src/app/shared/components/global-footer/global-footer.component.ts
@@ -28,7 +28,6 @@ export class GlobalFooterComponent implements OnInit {
networkPaths: { [network: string]: string };
currentNetwork = '';
loggedIn = false;
- username = null;
urlSubscription: Subscription;
isServicesPage = false;
@@ -64,13 +63,7 @@ export class GlobalFooterComponent implements OnInit {
});
this.urlSubscription = this.route.url.subscribe((url) => {
- this.loggedIn = JSON.parse(this.storageService.getValue('auth')) !== null;
- const auth = JSON.parse(this.storageService.getValue('auth'));
- if (auth?.user?.username) {
- this.username = auth.user.username;
- } else {
- this.username = null;
- }
+ this.loggedIn = this.storageService.getAuth() !== null;
this.cd.markForCheck();
})
}
From 4abc4e96a889e7a92d9c0c5f96127b153df58251 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Mon, 28 Aug 2023 09:34:50 +0200
Subject: [PATCH 063/128] [typo] satss -> sats
---
.../accelerate-preview/accelerate-preview.component.html | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
index c546d3859..c2bcbb7bf 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
@@ -173,7 +173,7 @@
- {{ estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee | number }} satss
+ {{ estimate.cost + estimate.mempoolBaseFee + estimate.vsizeFee | number }} sats
|
@@ -190,7 +190,7 @@
Maximum acceleration cost
- {{ maxCost | number }} satss
+ {{ maxCost | number }} sats
@@ -208,7 +208,7 @@
Available balance
|
- {{ estimate.userBalance | number }} satss
+ {{ estimate.userBalance | number }} sats
From d787ef99c4001ed788b7cd26903512da28f8573c Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Mon, 28 Aug 2023 10:24:44 +0200
Subject: [PATCH 064/128] [typo] the Mempool Accelerator -> Mempool Accelerator
---
.../src/app/components/transaction/transaction.component.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html
index 141c536ee..8c8de7137 100644
--- a/frontend/src/app/components/transaction/transaction.component.html
+++ b/frontend/src/app/components/transaction/transaction.component.html
@@ -7,7 +7,7 @@
- Accelerate this transaction using the Mempool Accelerator ™
+ Accelerate this transaction using Mempool Accelerator ™
×
From c7b89f31dde20a1a0da6ce591296a8cd36da2ccf Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Mon, 28 Aug 2023 17:42:32 +0900
Subject: [PATCH 065/128] Fix bad blockchain offset after services -> dash
---
frontend/src/app/components/menu/menu.component.ts | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/frontend/src/app/components/menu/menu.component.ts b/frontend/src/app/components/menu/menu.component.ts
index 2fb5c34d1..faeca3d24 100644
--- a/frontend/src/app/components/menu/menu.component.ts
+++ b/frontend/src/app/components/menu/menu.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit, Input, Output, EventEmitter, HostListener } from '@angular/core';
+import { Component, OnInit, Input, Output, EventEmitter, HostListener, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs';
import { ApiService } from '../../services/api.service';
import { MenuGroup } from '../../interfaces/services.interface';
@@ -12,7 +12,7 @@ import { StateService } from '../../services/state.service';
styleUrls: ['./menu.component.scss']
})
-export class MenuComponent implements OnInit {
+export class MenuComponent implements OnInit, OnDestroy {
@Input() navOpen: boolean = false;
@Output() loggedOut = new EventEmitter();
@Output() menuToggled = new EventEmitter();
@@ -98,4 +98,8 @@ export class MenuComponent implements OnInit {
this.toggleMenu(false);
}
}
+
+ ngOnDestroy(): void {
+ this.stateService.menuOpen$.next(false);
+ }
}
From 7a765cecd967a0627817663dc06ae02accb4305a Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Mon, 28 Aug 2023 15:41:45 +0200
Subject: [PATCH 066/128] [footer] only show cta if official
---
.../components/global-footer/global-footer.component.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frontend/src/app/shared/components/global-footer/global-footer.component.html b/frontend/src/app/shared/components/global-footer/global-footer.component.html
index b12874832..ea3f70479 100644
--- a/frontend/src/app/shared/components/global-footer/global-footer.component.html
+++ b/frontend/src/app/shared/components/global-footer/global-footer.component.html
@@ -21,12 +21,12 @@
-
-
From 3060aecddb74630a600acfac8f3779baf9560a60 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Mon, 28 Aug 2023 15:57:06 +0200
Subject: [PATCH 067/128] [status badge] reposition a bit higher
---
.../src/app/components/master-page/master-page.component.scss | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/src/app/components/master-page/master-page.component.scss b/frontend/src/app/components/master-page/master-page.component.scss
index f0fec0536..b82d973de 100644
--- a/frontend/src/app/components/master-page/master-page.component.scss
+++ b/frontend/src/app/components/master-page/master-page.component.scss
@@ -109,7 +109,7 @@ nav {
.connection-badge {
position: absolute;
- top: 22px;
+ top: 12px;
width: 100%;
}
From bbd1f088d14dae9c1fc6a8aa53e1549a4f525eb7 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Mon, 28 Aug 2023 16:20:30 +0200
Subject: [PATCH 068/128] [footer] only show cta if official && ACCELERATOR
---
.../components/global-footer/global-footer.component.html | 4 ++--
.../components/global-footer/global-footer.component.ts | 2 ++
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/frontend/src/app/shared/components/global-footer/global-footer.component.html b/frontend/src/app/shared/components/global-footer/global-footer.component.html
index ea3f70479..34d47379e 100644
--- a/frontend/src/app/shared/components/global-footer/global-footer.component.html
+++ b/frontend/src/app/shared/components/global-footer/global-footer.component.html
@@ -21,12 +21,12 @@
-
-
diff --git a/frontend/src/app/shared/components/global-footer/global-footer.component.ts b/frontend/src/app/shared/components/global-footer/global-footer.component.ts
index e76a5de0d..2e3f98e2d 100644
--- a/frontend/src/app/shared/components/global-footer/global-footer.component.ts
+++ b/frontend/src/app/shared/components/global-footer/global-footer.component.ts
@@ -30,6 +30,7 @@ export class GlobalFooterComponent implements OnInit {
loggedIn = false;
urlSubscription: Subscription;
isServicesPage = false;
+ servicesEnabled = false;
constructor(
public stateService: StateService,
@@ -44,6 +45,7 @@ export class GlobalFooterComponent implements OnInit {
) {}
ngOnInit(): void {
+ this.servicesEnabled = this.officialMempoolSpace && this.stateService.env.ACCELERATOR === true && this.stateService.network === '';
this.isServicesPage = this.router.url.includes('/services/');
this.env = this.stateService.env;
From 7ae4b451e4dc2ac8c2d65d5d67ca06e4e5babd1c Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Tue, 29 Aug 2023 09:31:18 +0200
Subject: [PATCH 069/128] [auth] remove auto logout when imageMd5 no in
localstorage
---
frontend/src/app/components/menu/menu.component.ts | 4 ----
1 file changed, 4 deletions(-)
diff --git a/frontend/src/app/components/menu/menu.component.ts b/frontend/src/app/components/menu/menu.component.ts
index faeca3d24..28ba0a1ad 100644
--- a/frontend/src/app/components/menu/menu.component.ts
+++ b/frontend/src/app/components/menu/menu.component.ts
@@ -30,10 +30,6 @@ export class MenuComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.userAuth = this.storageService.getAuth();
- if (this.userAuth && this.userAuth.user && !this.userAuth.user.imageMd5) {
- this.logout();
- return;
- }
if (this.stateService.env.GIT_COMMIT_HASH_MEMPOOL_SPACE) {
this.userMenuGroups$ = this.apiService.getUserMenuGroups$();
From 7c11f0a3dab8adf65b18e6ed24cc8870d0d3606f Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Tue, 29 Aug 2023 10:50:13 +0200
Subject: [PATCH 070/128] [tx] fix eta css
---
.../src/app/components/transaction/transaction.component.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html
index 8c8de7137..ce5d703fb 100644
--- a/frontend/src/app/components/transaction/transaction.component.html
+++ b/frontend/src/app/components/transaction/transaction.component.html
@@ -126,7 +126,7 @@
-
+
Accelerate
From c2c4047ffd7ef3fcbdbb6fa645959966aa80566d Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Tue, 29 Aug 2023 14:19:02 +0200
Subject: [PATCH 071/128] [css] fix spacing at the top
---
frontend/src/app/components/about/about.component.scss | 1 +
frontend/src/styles.scss | 4 ----
2 files changed, 1 insertion(+), 4 deletions(-)
diff --git a/frontend/src/app/components/about/about.component.scss b/frontend/src/app/components/about/about.component.scss
index 2a5710ca1..f1b4d6e2b 100644
--- a/frontend/src/app/components/about/about.component.scss
+++ b/frontend/src/app/components/about/about.component.scss
@@ -22,6 +22,7 @@
.intro {
margin: 25px auto 30px;
+ margin-top: 49px;
width: 250px;
display: flex;
flex-direction: column;
diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss
index 078b6b30a..7c0ee160c 100644
--- a/frontend/src/styles.scss
+++ b/frontend/src/styles.scss
@@ -62,10 +62,6 @@ body {
position: relative;
}
-main {
- margin-top: 24px;
-}
-
.full-height {
@media (max-width: 767.98px) {
min-height: 100vh;
From 91fbd0864b458fe622fd9d37eff9590eb5b41ef8 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Tue, 29 Aug 2023 14:34:56 +0200
Subject: [PATCH 072/128] [css] fix footer position
---
.../src/app/components/master-page/master-page.component.html | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/frontend/src/app/components/master-page/master-page.component.html b/frontend/src/app/components/master-page/master-page.component.html
index 74a95daf5..8863b335f 100644
--- a/frontend/src/app/components/master-page/master-page.component.html
+++ b/frontend/src/app/components/master-page/master-page.component.html
@@ -79,13 +79,14 @@
-
From c44276027ce013feaa3e9d37190170b06cb760bf Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Tue, 29 Aug 2023 15:51:17 +0200
Subject: [PATCH 073/128] [auto scroll] fix documention anchor scrolling
---
frontend/src/app/docs/api-docs/api-docs.component.scss | 2 +-
frontend/src/app/docs/api-docs/api-docs.component.ts | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/frontend/src/app/docs/api-docs/api-docs.component.scss b/frontend/src/app/docs/api-docs/api-docs.component.scss
index 8e4c0c7a9..b90b843d9 100644
--- a/frontend/src/app/docs/api-docs/api-docs.component.scss
+++ b/frontend/src/app/docs/api-docs/api-docs.component.scss
@@ -155,7 +155,7 @@ ul.no-bull.block-audit code{
#doc-nav-desktop.fixed {
float: unset;
position: fixed;
- top: 20px;
+ top: 80px;
overflow-y: auto;
height: calc(100vh - 50px);
scrollbar-color: #2d3348 #11131f;
diff --git a/frontend/src/app/docs/api-docs/api-docs.component.ts b/frontend/src/app/docs/api-docs/api-docs.component.ts
index 62a0fadba..b0ae5967d 100644
--- a/frontend/src/app/docs/api-docs/api-docs.component.ts
+++ b/frontend/src/app/docs/api-docs/api-docs.component.ts
@@ -43,7 +43,7 @@ export class ApiDocsComponent implements OnInit, AfterViewInit {
if (this.faqTemplates) {
this.faqTemplates.forEach((x) => this.dict[x.type] = x.template);
}
- this.desktopDocsNavPosition = ( window.pageYOffset > 182 ) ? "fixed" : "relative";
+ this.desktopDocsNavPosition = ( window.pageYOffset > 115 ) ? "fixed" : "relative";
this.mobileViewport = window.innerWidth <= 992;
}
@@ -113,7 +113,7 @@ export class ApiDocsComponent implements OnInit, AfterViewInit {
}
onDocScroll() {
- this.desktopDocsNavPosition = ( window.pageYOffset > 182 ) ? "fixed" : "relative";
+ this.desktopDocsNavPosition = ( window.pageYOffset > 115 ) ? "fixed" : "relative";
}
anchorLinkClick( event: any ) {
From c753a8e92af5ec56599fa50c592c9430e1c3f8cc Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Tue, 29 Aug 2023 21:20:36 +0900
Subject: [PATCH 074/128] Accelerator fee diagram concept
---
.../accelerate-fee-graph.component.html | 21 +
.../accelerate-fee-graph.component.scss | 147 +++++++
.../accelerate-fee-graph.component.ts | 96 ++++
.../accelerate-preview.component.html | 413 +++++++++---------
.../accelerate-preview.component.scss | 7 +
.../accelerate-preview.component.ts | 31 +-
.../transaction/transaction.component.html | 2 +-
frontend/src/app/shared/shared.module.ts | 3 +
8 files changed, 511 insertions(+), 209 deletions(-)
create mode 100644 frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.html
create mode 100644 frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss
create mode 100644 frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.ts
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.html b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.html
new file mode 100644
index 000000000..727f833bc
--- /dev/null
+++ b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ {{ bar.label }}
+
+
+
+
+
+ {{ bar.class === 'tx' ? '' : '+' }} {{ bar.fee | number }} sat
+
+
+
+
+
+
+
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss
new file mode 100644
index 000000000..84d530e34
--- /dev/null
+++ b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss
@@ -0,0 +1,147 @@
+.fee-graph {
+ height: 100%;
+ width: 20%;
+ min-width: 100px;
+ max-width: 150px;
+ max-height: 100vh;
+ margin-left: 4em;
+ margin-right: 1.5em;
+ padding-bottom: 63px;
+
+ .column {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ background: #181b2d;
+
+ .bar {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ .fill {
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ opacity: 0.75;
+ pointer-events: none;
+ }
+
+ .fee {
+ position: absolute;
+ opacity: 0;
+ pointer-events: none;
+ }
+
+ .line {
+ position: absolute;
+ right: 0;
+ top: 0;
+ left: -4.5em;
+ border-top: dashed white 1.5px;
+
+ .fee-rate {
+ width: 100%;
+ position: absolute;
+ left: 0;
+ right: 0.2em;
+ font-size: 0.8em;
+ display: flex;
+ flex-direction: row-reverse;
+ justify-content: space-between;
+ margin: 0;
+
+ .label {
+ margin-right: .2em;
+ }
+
+ .rate .symbol {
+ color: white;
+ }
+ }
+ }
+
+ &.tx {
+ .fill {
+ background: #105fb0;
+ }
+ .line {
+ .fee-rate {
+ top: 0;
+ }
+ }
+ .fee {
+ opacity: 1;
+ z-index: 11;
+ }
+ }
+
+ &.target {
+ .fill {
+ background: #3bcc49;
+ }
+ .fee {
+ opacity: 1;
+ z-index: 11;
+ }
+ .line .fee-rate {
+ bottom: 2px;
+ }
+ }
+
+ &.max {
+ cursor: pointer;
+ .line .fee-rate {
+ .label {
+ opacity: 0;
+ }
+ bottom: 2px;
+ }
+ &.active, &:hover {
+ .fill {
+ background: #653b9c;
+ }
+ .line {
+ .fee-rate .label {
+ opacity: 1;
+ }
+ }
+ }
+ }
+
+ &:hover {
+ .fill {
+ z-index: 10;
+ }
+ .line {
+ z-index: 11;
+ }
+ .fee {
+ opacity: 1;
+ z-index: 12;
+ }
+ }
+ }
+
+ &:hover > .bar:not(:hover) {
+ &.target, &.max {
+ .fee {
+ opacity: 0;
+ }
+ .line .fee-rate .label {
+ opacity: 0;
+ }
+ }
+ }
+ }
+
+ .vsize {
+ text-align: center;
+ }
+}
\ No newline at end of file
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.ts b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.ts
new file mode 100644
index 000000000..98b47bea0
--- /dev/null
+++ b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.ts
@@ -0,0 +1,96 @@
+import { Component, OnInit, Input, Output, OnChanges, EventEmitter, HostListener, Inject, LOCALE_ID } from '@angular/core';
+import { StateService } from '../../services/state.service';
+import { Outspend, Transaction, Vin, Vout } from '../../interfaces/electrs.interface';
+import { Router } from '@angular/router';
+import { ReplaySubject, merge, Subscription, of } from 'rxjs';
+import { tap, switchMap } from 'rxjs/operators';
+import { ApiService } from '../../services/api.service';
+import { AccelerationEstimate, RateOption } from './accelerate-preview.component';
+
+interface GraphBar {
+ rate: number;
+ style: any;
+ class: 'tx' | 'target' | 'max';
+ label: string;
+ active?: boolean;
+ rateIndex?: number;
+ fee?: number;
+}
+
+@Component({
+ selector: 'app-accelerate-fee-graph',
+ templateUrl: './accelerate-fee-graph.component.html',
+ styleUrls: ['./accelerate-fee-graph.component.scss'],
+})
+export class AccelerateFeeGraphComponent implements OnInit, OnChanges {
+ @Input() tx: Transaction;
+ @Input() estimate: AccelerationEstimate;
+ @Input() maxRateOptions: RateOption[] = [];
+ @Input() maxRateIndex: number = 0;
+ @Output() setUserBid = new EventEmitter<{ fee: number, index: number }>();
+
+ bars: GraphBar[] = [];
+ tooltipPosition = { x: 0, y: 0 };
+
+ ngOnInit(): void {
+ this.initGraph();
+ }
+
+ ngOnChanges(): void {
+ this.initGraph();
+ }
+
+ initGraph(): void {
+ if (!this.tx || !this.estimate) {
+ return;
+ }
+ const maxRate = Math.max(...this.maxRateOptions.map(option => option.rate));
+ const baseRate = this.estimate.txSummary.effectiveFee / this.estimate.txSummary.effectiveVsize;
+ const baseHeight = baseRate / maxRate;
+ const bars: GraphBar[] = this.maxRateOptions.slice().reverse().map(option => {
+ return {
+ rate: option.rate,
+ style: this.getStyle(option.rate, maxRate, baseHeight),
+ class: 'max',
+ label: 'max',
+ active: option.index === this.maxRateIndex,
+ rateIndex: option.index,
+ fee: option.fee,
+ }
+ });
+ bars.push({
+ rate: this.estimate.targetFeeRate,
+ style: this.getStyle(this.estimate.targetFeeRate, maxRate, baseHeight),
+ class: 'target',
+ label: 'expected',
+ fee: this.estimate.nextBlockFee - this.estimate.txSummary.effectiveFee
+ });
+ bars.push({
+ rate: baseRate,
+ style: this.getStyle(baseRate, maxRate, 0),
+ class: 'tx',
+ label: 'paid',
+ fee: this.estimate.txSummary.effectiveFee,
+ });
+ this.bars = bars;
+ }
+
+ getStyle(rate, maxRate, base) {
+ const top = (rate / maxRate);
+ return {
+ height: `${(top - base) * 100}%`,
+ bottom: base ? `${base * 100}%` : '0',
+ }
+ }
+
+ onClick(event, bar): void {
+ if (bar.rateIndex != null) {
+ this.setUserBid.emit({ fee: bar.fee, index: bar.rateIndex });
+ }
+ }
+
+ @HostListener('pointermove', ['$event'])
+ onPointerMove(event) {
+ this.tooltipPosition = { x: event.offsetX, y: event.offsetY };
+ }
+}
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
index c2bcbb7bf..ad96eb671 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
@@ -20,212 +20,223 @@
-
-
-
-
-
-
-
-
-
- Next block market price
- |
-
- {{ estimate.targetFeeRate | number : '1.0-0' }} sat/vB
- |
-
-
-
- Currently estimated fee to get into next block
- |
-
-
- {{ estimate.nextBlockFee| number }} sats
-
-
- |
-
-
-
-
-
- Fees paid in-band
- |
-
- ~{{ (estimate.txSummary.effectiveFee / estimate.txSummary.effectiveVsize) | number : '1.0-0' }} sat/vB
- |
-
-
-
- What you already paid when you made the transaction
- |
-
-
- {{ estimate.txSummary.effectiveFee | number }} sats
-
-
- |
-
-
-
-
-
- Extra fee required
- |
-
- {{ math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee) | number }} sats
-
- |
-
-
-
- Difference between the next block fee and your tx fee
- |
-
-
-
-
-
+
+
- How much more are you willing to pay at most to get into the next block?
-
-
-
- The maximum extra transaction fee you're willing to pay to get into the next block. If the next block market price becomes too expensive for you, we will automatically cancel your acceleration request. Final charged fee may be smaller based on the fee market.
-
-
-
-
-
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss
index 84d530e34..6137b53ee 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss
+++ b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.scss
@@ -1,9 +1,8 @@
.fee-graph {
height: 100%;
- width: 20%;
- min-width: 100px;
- max-width: 150px;
- max-height: 100vh;
+ min-width: 120px;
+ width: 120px;
+ max-height: 90vh;
margin-left: 4em;
margin-right: 1.5em;
padding-bottom: 63px;
@@ -20,6 +19,7 @@
left: 0;
right: 0;
display: flex;
+ flex-direction: column;
justify-content: center;
align-items: center;
@@ -34,11 +34,18 @@
}
.fee {
- position: absolute;
+ font-size: 0.9em;
opacity: 0;
pointer-events: none;
}
+ .spacer {
+ width: 100%;
+ height: 1px;
+ flex-grow: 1;
+ pointer-events: none;
+ }
+
.line {
position: absolute;
right: 0;
@@ -69,7 +76,7 @@
&.tx {
.fill {
- background: #105fb0;
+ background: #3bcc49;
}
.line {
.fee-rate {
@@ -77,6 +84,7 @@
}
}
.fee {
+ position: absolute;
opacity: 1;
z-index: 11;
}
@@ -84,9 +92,10 @@
&.target {
.fill {
- background: #3bcc49;
+ background: #653b9c;
}
.fee {
+ position: absolute;
opacity: 1;
z-index: 11;
}
@@ -105,7 +114,7 @@
}
&.active, &:hover {
.fill {
- background: #653b9c;
+ background: #105fb0;
}
.line {
.fee-rate .label {
@@ -138,10 +147,11 @@
opacity: 0;
}
}
+ &.max {
+ .fill {
+ background: none;
+ }
+ }
}
}
-
- .vsize {
- text-align: center;
- }
}
\ No newline at end of file
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.ts b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.ts
index 98b47bea0..4d746a0d9 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.ts
+++ b/frontend/src/app/components/accelerate-preview/accelerate-fee-graph.component.ts
@@ -52,7 +52,7 @@ export class AccelerateFeeGraphComponent implements OnInit, OnChanges {
rate: option.rate,
style: this.getStyle(option.rate, maxRate, baseHeight),
class: 'max',
- label: 'max',
+ label: 'maximum',
active: option.index === this.maxRateIndex,
rateIndex: option.index,
fee: option.fee,
@@ -62,14 +62,14 @@ export class AccelerateFeeGraphComponent implements OnInit, OnChanges {
rate: this.estimate.targetFeeRate,
style: this.getStyle(this.estimate.targetFeeRate, maxRate, baseHeight),
class: 'target',
- label: 'expected',
+ label: 'next block',
fee: this.estimate.nextBlockFee - this.estimate.txSummary.effectiveFee
});
bars.push({
rate: baseRate,
style: this.getStyle(baseRate, maxRate, 0),
class: 'tx',
- label: 'paid',
+ label: '',
fee: this.estimate.txSummary.effectiveFee,
});
this.bars = bars;
diff --git a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
index ad96eb671..8fc77dae4 100644
--- a/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
+++ b/frontend/src/app/components/accelerate-preview/accelerate-preview.component.html
@@ -12,14 +12,6 @@
- 1">
-
-
- This transactions is part of a CPFP tree. Fee rates (in sats/vb) are provided for your information. Change in the CPFP tree will lead to different fee rates values.
-
-
-
-
-
+ Your transaction
+
+
+ Plus {{ estimate.txSummary.ancestorCount - 1 }} unconfirmed ancestor{{ estimate.txSummary.ancestorCount > 2 ? 's' : ''}}.
+
-
-
-
- Next block market price
+ |
+
+ Virtual size
|
-
- {{ estimate.targetFeeRate | number : '1.0-0' }} sat/vB
+ | |
+
+
+
+ Size in vbytes of this transaction and its unconfirmed ancestors
|
-
- Currently estimated fee to get into next block
+ |
+ In-band fees
|
-
-
- {{ estimate.nextBlockFee| number }} sats
-
-
+ |
+ {{ estimate.txSummary.effectiveFee | number : '1.0-0' }} sats
|
-
-
-
-
- Fees paid in-band
- |
-
- ~{{ (estimate.txSummary.effectiveFee / estimate.txSummary.effectiveVsize) | number : '1.0-0' }} sat/vB
- |
-
-
-
- What you already paid when you made the transaction
- |
-
-
- {{ estimate.txSummary.effectiveFee | number }} sats
-
-
- |
-
-
-
-
-
- Extra fee required
- |
-
- {{ math.max(0, estimate.nextBlockFee - estimate.txSummary.effectiveFee) | number }} sats
-
- |
-
-
-
- Difference between the next block fee and your tx fee
+ |
+
+ Fees already paid by this transaction and its unconfirmed ancestors
|
-
- How much more are you willing to pay at most to get into the next block?
+
+ How much more are you willing to pay?
- The maximum extra transaction fee you're willing to pay to get into the next block. If the next block market price becomes too expensive for you, we will automatically cancel your acceleration request. Final charged fee may be smaller based on the fee market.
+ Choose the maximum extra transaction fee you're willing to pay to get into the next block.
+ If the estimated next block rate rises beyond this limit, we will automatically cancel your acceleration request.
| `);
});
const classActive = (this.template === 'advanced') ? 'fees-wrapper-tooltip-chart-advanced' : '';
+ const titleCount = $localize`Count`;
const titleRange = $localize`Range`;
const titleSize = $localize`:@@7faaaa08f56427999f3be41df1093ce4089bbd75:Size`;
const titleSum = $localize`Sum`;
@@ -286,6 +333,25 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
${this.vbytesPipe.transform(totalValue, 2, 'vB', 'MvB', false)}
+ ` +
+ (this.showCount && countItem ? `
+
+
+
+
+
+
+ ${titleCount}
+
+ |
+
+ ${this.amountShortenerPipe.transform(countItem.value[1], 2, undefined, true)}
+ |
+
+
+
+ ` : '')
+ + `
@@ -305,12 +371,12 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
`;
}
},
- dataZoom: (this.template === 'widget' && this.isMobile()) ? null : [{
+ dataZoom: (this.isWidget && this.isMobile()) ? null : [{
type: 'inside',
realtime: true,
- zoomLock: (this.template === 'widget') ? true : false,
+ zoomLock: (this.isWidget) ? true : false,
zoomOnMouseWheel: (this.template === 'advanced') ? true : false,
- moveOnMouseMove: (this.template === 'widget') ? true : false,
+ moveOnMouseMove: (this.isWidget) ? true : false,
maxSpan: 100,
minSpan: 10,
}, {
@@ -339,7 +405,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
},
xAxis: [
{
- name: this.template === 'widget' ? '' : formatterXAxisLabel(this.locale, this.windowPreference),
+ name: this.isWidget ? '' : formatterXAxisLabel(this.locale, this.windowPreference),
nameLocation: 'middle',
nameTextStyle: {
padding: [20, 0, 0, 0],
@@ -357,7 +423,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
},
}
],
- yAxis: {
+ yAxis: [{
type: 'value',
axisLine: { onZero: false },
axisLabel: {
@@ -371,7 +437,17 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
opacity: 0.25,
}
}
- },
+ }, this.showCount ? {
+ type: 'value',
+ position: 'right',
+ axisLine: { onZero: false },
+ axisLabel: {
+ formatter: (value: number) => (`${this.amountShortenerPipe.transform(value, 2, undefined, true)}`),
+ },
+ splitLine: {
+ show: false,
+ }
+ } : null],
};
}
diff --git a/frontend/src/app/components/statistics/statistics.component.html b/frontend/src/app/components/statistics/statistics.component.html
index 29089e43d..02a26ed52 100644
--- a/frontend/src/app/components/statistics/statistics.component.html
+++ b/frontend/src/app/components/statistics/statistics.component.html
@@ -69,6 +69,12 @@
+ -
+
+ {{ titleCount }}
+
+
-
diff --git a/frontend/src/app/components/statistics/statistics.component.ts b/frontend/src/app/components/statistics/statistics.component.ts
index 69bf9ea8f..ba9068975 100644
--- a/frontend/src/app/components/statistics/statistics.component.ts
+++ b/frontend/src/app/components/statistics/statistics.component.ts
@@ -32,6 +32,7 @@ export class StatisticsComponent implements OnInit {
chartColors = chartColors;
filterSize = 100000;
filterFeeIndex = 1;
+ showCount = true;
maxFeeIndex: number;
dropDownOpen = false;
@@ -46,6 +47,7 @@ export class StatisticsComponent implements OnInit {
inverted: boolean;
feeLevelDropdownData = [];
timespan = '';
+ titleCount = $localize`Count`;
constructor(
@Inject(LOCALE_ID) private locale: string,
diff --git a/frontend/src/app/interfaces/node-api.interface.ts b/frontend/src/app/interfaces/node-api.interface.ts
index a9f069b56..08de11a6a 100644
--- a/frontend/src/app/interfaces/node-api.interface.ts
+++ b/frontend/src/app/interfaces/node-api.interface.ts
@@ -2,6 +2,7 @@ import { Block, Transaction } from "./electrs.interface";
export interface OptimizedMempoolStats {
added: number;
+ count: number;
vbytes_per_second: number;
total_fee: number;
mempool_byte_weight: number;
From 0712195de4c6a01e83930baa5939c1af93ee444a Mon Sep 17 00:00:00 2001
From: orangesurf
Date: Tue, 12 Sep 2023 19:29:33 +0100
Subject: [PATCH 090/128] Add orangesurf contributor declaration
---
contributors/orangesurf.txt | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 contributors/orangesurf.txt
diff --git a/contributors/orangesurf.txt b/contributors/orangesurf.txt
new file mode 100644
index 000000000..c760a9125
--- /dev/null
+++ b/contributors/orangesurf.txt
@@ -0,0 +1,3 @@
+I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of September 12, 2023.
+
+Signed: orange surf
From a1b75c377296d52f55a23258b7299095cfe555fb Mon Sep 17 00:00:00 2001
From: orangesurf
Date: Tue, 12 Sep 2023 19:45:18 +0100
Subject: [PATCH 091/128] Update to reflect registered trademark
---
frontend/src/app/components/about/about.component.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html
index 6bff838aa..ad05b7d71 100644
--- a/frontend/src/app/components/about/about.component.html
+++ b/frontend/src/app/components/about/about.component.html
@@ -10,7 +10,7 @@
- The Mempool Open Source Project ™
+ The Mempool Open Source Project ®
Our mempool and blockchain explorer for the Bitcoin community, focusing on the transaction fee market and multi-layer ecosystem, completely self-hosted without any trusted third-parties.
From 0ba4e98f52cc539cea112317b54f60c6388304f4 Mon Sep 17 00:00:00 2001
From: orangesurf
Date: Tue, 12 Sep 2023 19:55:00 +0100
Subject: [PATCH 092/128] Replace other instances of tm use for The Mempool
Open Source Project
---
frontend/src/app/components/about/about.component.ts | 2 +-
.../components/privacy-policy/privacy-policy.component.ts | 2 +-
.../trademark-policy/trademark-policy.component.ts | 2 +-
frontend/src/index.mempool.html | 6 +++---
4 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/frontend/src/app/components/about/about.component.ts b/frontend/src/app/components/about/about.component.ts
index 3cda0dc20..8aa0422e8 100644
--- a/frontend/src/app/components/about/about.component.ts
+++ b/frontend/src/app/components/about/about.component.ts
@@ -43,7 +43,7 @@ export class AboutComponent implements OnInit {
ngOnInit() {
this.backendInfo$ = this.stateService.backendInfo$;
this.seoService.setTitle($localize`:@@004b222ff9ef9dd4771b777950ca1d0e4cd4348a:About`);
- this.seoService.setDescription($localize`:@@meta.description.about:Learn more about The Mempool Open Source Projectâ„¢\: enterprise sponsors, individual sponsors, integrations, who contributes, FOSS licensing, and more.`);
+ this.seoService.setDescription($localize`:@@meta.description.about:Learn more about The Mempool Open Source Project®\: enterprise sponsors, individual sponsors, integrations, who contributes, FOSS licensing, and more.`);
this.websocketService.want(['blocks']);
this.profiles$ = this.apiService.getAboutPageProfiles$().pipe(
diff --git a/frontend/src/app/components/privacy-policy/privacy-policy.component.ts b/frontend/src/app/components/privacy-policy/privacy-policy.component.ts
index 7a44070eb..b98390731 100644
--- a/frontend/src/app/components/privacy-policy/privacy-policy.component.ts
+++ b/frontend/src/app/components/privacy-policy/privacy-policy.component.ts
@@ -17,6 +17,6 @@ export class PrivacyPolicyComponent {
ngOnInit(): void {
this.seoService.setTitle('Privacy Policy');
- this.seoService.setDescription('Trusted third parties are security holes, as are trusted first parties...you should only trust your own self-hosted instance of The Mempool Open Source Projectâ„¢.');
+ this.seoService.setDescription('Trusted third parties are security holes, as are trusted first parties...you should only trust your own self-hosted instance of The Mempool Open Source Project®.');
}
}
diff --git a/frontend/src/app/components/trademark-policy/trademark-policy.component.ts b/frontend/src/app/components/trademark-policy/trademark-policy.component.ts
index 08f16264a..b8f53afcf 100644
--- a/frontend/src/app/components/trademark-policy/trademark-policy.component.ts
+++ b/frontend/src/app/components/trademark-policy/trademark-policy.component.ts
@@ -17,6 +17,6 @@ export class TrademarkPolicyComponent {
ngOnInit(): void {
this.seoService.setTitle('Trademark Policy');
- this.seoService.setDescription('An overview of the trademarks registered by Mempool Space K.K. and The Mempool Open Source Projectâ„¢ and what we consider to be lawful usage of those trademarks.');
+ this.seoService.setDescription('An overview of the trademarks registered by Mempool Space K.K. and The Mempool Open Source Project® and what we consider to be lawful usage of those trademarks.');
}
}
diff --git a/frontend/src/index.mempool.html b/frontend/src/index.mempool.html
index 03edc08ef..def14434e 100644
--- a/frontend/src/index.mempool.html
+++ b/frontend/src/index.mempool.html
@@ -7,17 +7,17 @@
-
+
-
+
-
+
From 9b17c163257ecc0bae4fddc907e8b42c3e7f2907 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Fri, 25 Aug 2023 00:57:47 +0900
Subject: [PATCH 093/128] Notify address page of removed transactions
---
backend/src/api/websocket-handler.ts | 9 ++++--
.../components/address/address.component.ts | 29 +++++++++++++++++++
frontend/src/app/services/state.service.ts | 1 +
.../src/app/services/websocket.service.ts | 6 ++++
4 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts
index 41cb6b99c..c50941f39 100644
--- a/backend/src/api/websocket-handler.ts
+++ b/backend/src/api/websocket-handler.ts
@@ -486,6 +486,7 @@ class WebsocketHandler {
// pre-compute address transactions
const addressCache = this.makeAddressCache(newTransactions);
+ const removedAddressCache = this.makeAddressCache(deletedTransactions);
this.wss.clients.forEach(async (client) => {
if (client.readyState !== WebSocket.OPEN) {
@@ -526,11 +527,15 @@ class WebsocketHandler {
}
if (client['track-address']) {
- const foundTransactions = Array.from(addressCache[client['track-address']]?.values() || []);
+ const newTransactions = Array.from(addressCache[client['track-address']]?.values() || []);
+ const removedTransactions = Array.from(removedAddressCache[client['track-address']]?.values() || []);
// txs may be missing prevouts in non-esplora backends
// so fetch the full transactions now
- const fullTransactions = (config.MEMPOOL.BACKEND !== 'esplora') ? await this.getFullTransactions(foundTransactions) : foundTransactions;
+ const fullTransactions = (config.MEMPOOL.BACKEND !== 'esplora') ? await this.getFullTransactions(newTransactions) : newTransactions;
+ if (removedTransactions.length) {
+ response['address-removed-transactions'] = JSON.stringify(removedTransactions);
+ }
if (fullTransactions.length) {
response['address-transactions'] = JSON.stringify(fullTransactions);
}
diff --git a/frontend/src/app/components/address/address.component.ts b/frontend/src/app/components/address/address.component.ts
index e9cd0189b..0e10b207f 100644
--- a/frontend/src/app/components/address/address.component.ts
+++ b/frontend/src/app/components/address/address.component.ts
@@ -174,6 +174,11 @@ export class AddressComponent implements OnInit, OnDestroy {
this.addTransaction(tx);
});
+ this.stateService.mempoolRemovedTransactions$
+ .subscribe(tx => {
+ this.removeTransaction(tx);
+ });
+
this.stateService.blockTransactions$
.subscribe((transaction) => {
const tx = this.transactions.find((t) => t.txid === transaction.txid);
@@ -222,6 +227,30 @@ export class AddressComponent implements OnInit, OnDestroy {
return true;
}
+ removeTransaction(transaction: Transaction): boolean {
+ const index = this.transactions.findIndex(((tx) => tx.txid === transaction.txid));
+ if (index === -1) {
+ return false;
+ }
+
+ this.transactions.splice(index, 1);
+ this.transactions = this.transactions.slice();
+ this.txCount--;
+
+ transaction.vin.forEach((vin) => {
+ if (vin?.prevout?.scriptpubkey_address === this.address.address) {
+ this.sent -= vin.prevout.value;
+ }
+ });
+ transaction.vout.forEach((vout) => {
+ if (vout?.scriptpubkey_address === this.address.address) {
+ this.received -= vout.value;
+ }
+ });
+
+ return true;
+ }
+
loadMore() {
if (this.isLoadingTransactions || !this.totalConfirmedTxCount || this.loadedConfirmedTxCount >= this.totalConfirmedTxCount) {
return;
diff --git a/frontend/src/app/services/state.service.ts b/frontend/src/app/services/state.service.ts
index 878edf359..db1268379 100644
--- a/frontend/src/app/services/state.service.ts
+++ b/frontend/src/app/services/state.service.ts
@@ -117,6 +117,7 @@ export class StateService {
difficultyAdjustment$ = new ReplaySubject(1);
mempoolTransactions$ = new Subject();
mempoolTxPosition$ = new Subject<{ txid: string, position: MempoolPosition, cpfp: CpfpInfo | null}>();
+ mempoolRemovedTransactions$ = new Subject();
blockTransactions$ = new Subject();
isLoadingWebSocket$ = new ReplaySubject(1);
isLoadingMempool$ = new BehaviorSubject(true);
diff --git a/frontend/src/app/services/websocket.service.ts b/frontend/src/app/services/websocket.service.ts
index af2a15e8c..22da49f06 100644
--- a/frontend/src/app/services/websocket.service.ts
+++ b/frontend/src/app/services/websocket.service.ts
@@ -358,6 +358,12 @@ export class WebsocketService {
});
}
+ if (response['address-removed-transactions']) {
+ response['address-removed-transactions'].forEach((addressTransaction: Transaction) => {
+ this.stateService.mempoolRemovedTransactions$.next(addressTransaction);
+ });
+ }
+
if (response['block-transactions']) {
response['block-transactions'].forEach((addressTransaction: Transaction) => {
this.stateService.blockTransactions$.next(addressTransaction);
From 6b8db33a9c0d61fed9b87f2ecddbc16566316959 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Fri, 15 Sep 2023 17:11:52 +0200
Subject: [PATCH 094/128] [ui] don't add 120px to blockchain component on
liquid
---
frontend/src/app/components/start/start.component.html | 1 +
frontend/src/app/components/start/start.component.scss | 6 +++++-
frontend/src/app/components/start/start.component.ts | 5 +++++
3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/frontend/src/app/components/start/start.component.html b/frontend/src/app/components/start/start.component.html
index 709a230d9..862baf80a 100644
--- a/frontend/src/app/components/start/start.component.html
+++ b/frontend/src/app/components/start/start.component.html
@@ -14,6 +14,7 @@
Date: Sun, 17 Sep 2023 19:56:33 -0400
Subject: [PATCH 095/128] ops: Add VA1 servers to prod config
---
production/mempool-config.liquid.json | 6 ++++
production/mempool-config.liquidtestnet.json | 6 ++++
.../mempool-config.mainnet-lightning.json | 29 +++++++++++++++++--
production/mempool-config.mainnet.json | 12 ++++++++
.../mempool-config.signet-lightning.json | 29 +++++++++++++++++--
production/mempool-config.signet.json | 6 ++++
.../mempool-config.testnet-lightning.json | 29 +++++++++++++++++--
production/mempool-config.testnet.json | 6 ++++
8 files changed, 117 insertions(+), 6 deletions(-)
diff --git a/production/mempool-config.liquid.json b/production/mempool-config.liquid.json
index d67d7b794..a4f4bcd81 100644
--- a/production/mempool-config.liquid.json
+++ b/production/mempool-config.liquid.json
@@ -25,6 +25,12 @@
"ESPLORA": {
"UNIX_SOCKET_PATH": "/elements/socket/esplora-liquid-mainnet",
"FALLBACK": [
+ "http://node201.va1.mempool.space:3001",
+ "http://node202.va1.mempool.space:3001",
+ "http://node203.va1.mempool.space:3001",
+ "http://node204.va1.mempool.space:3001",
+ "http://node205.va1.mempool.space:3001",
+ "http://node206.va1.mempool.space:3001",
"http://node201.fmt.mempool.space:3001",
"http://node202.fmt.mempool.space:3001",
"http://node203.fmt.mempool.space:3001",
diff --git a/production/mempool-config.liquidtestnet.json b/production/mempool-config.liquidtestnet.json
index 3a76b4c86..cf2d70045 100644
--- a/production/mempool-config.liquidtestnet.json
+++ b/production/mempool-config.liquidtestnet.json
@@ -25,6 +25,12 @@
"ESPLORA": {
"UNIX_SOCKET_PATH": "/elements/socket/esplora-liquid-testnet",
"FALLBACK": [
+ "http://node201.va1.mempool.space:3004",
+ "http://node202.va1.mempool.space:3004",
+ "http://node203.va1.mempool.space:3004",
+ "http://node204.va1.mempool.space:3004",
+ "http://node205.va1.mempool.space:3004",
+ "http://node206.va1.mempool.space:3004",
"http://node201.fmt.mempool.space:3004",
"http://node202.fmt.mempool.space:3004",
"http://node203.fmt.mempool.space:3004",
diff --git a/production/mempool-config.mainnet-lightning.json b/production/mempool-config.mainnet-lightning.json
index 41e42a5bd..6bd326bfa 100644
--- a/production/mempool-config.mainnet-lightning.json
+++ b/production/mempool-config.mainnet-lightning.json
@@ -16,8 +16,33 @@
"PASSWORD": "__BITCOIN_RPC_PASS__"
},
"ESPLORA": {
- "REST_API_URL": "http://127.0.0.1:5000",
- "UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-mainnet"
+ "UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-mainnet",
+ "FALLBACK": [
+ "http://node201.va1.mempool.space:3000",
+ "http://node202.va1.mempool.space:3000",
+ "http://node203.va1.mempool.space:3000",
+ "http://node204.va1.mempool.space:3000",
+ "http://node205.va1.mempool.space:3000",
+ "http://node206.va1.mempool.space:3000",
+ "http://node201.fmt.mempool.space:3000",
+ "http://node202.fmt.mempool.space:3000",
+ "http://node203.fmt.mempool.space:3000",
+ "http://node204.fmt.mempool.space:3000",
+ "http://node205.fmt.mempool.space:3000",
+ "http://node206.fmt.mempool.space:3000",
+ "http://node201.fra.mempool.space:3000",
+ "http://node202.fra.mempool.space:3000",
+ "http://node203.fra.mempool.space:3000",
+ "http://node204.fra.mempool.space:3000",
+ "http://node205.fra.mempool.space:3000",
+ "http://node206.fra.mempool.space:3000",
+ "http://node201.tk7.mempool.space:3000",
+ "http://node202.tk7.mempool.space:3000",
+ "http://node203.tk7.mempool.space:3000",
+ "http://node204.tk7.mempool.space:3000",
+ "http://node205.tk7.mempool.space:3000",
+ "http://node206.tk7.mempool.space:3000"
+ ]
},
"LIGHTNING": {
"ENABLED": true,
diff --git a/production/mempool-config.mainnet.json b/production/mempool-config.mainnet.json
index d4222bd05..b2878ceef 100644
--- a/production/mempool-config.mainnet.json
+++ b/production/mempool-config.mainnet.json
@@ -37,6 +37,12 @@
"ESPLORA": {
"UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-mainnet",
"FALLBACK": [
+ "http://node201.va1.mempool.space:3000",
+ "http://node202.va1.mempool.space:3000",
+ "http://node203.va1.mempool.space:3000",
+ "http://node204.va1.mempool.space:3000",
+ "http://node205.va1.mempool.space:3000",
+ "http://node206.va1.mempool.space:3000",
"http://node201.fmt.mempool.space:3000",
"http://node202.fmt.mempool.space:3000",
"http://node203.fmt.mempool.space:3000",
@@ -74,6 +80,12 @@
"AUDIT": true,
"AUDIT_START_HEIGHT": 774000,
"SERVERS": [
+ "node201.va1.mempool.space",
+ "node202.va1.mempool.space",
+ "node203.va1.mempool.space",
+ "node204.va1.mempool.space",
+ "node205.va1.mempool.space",
+ "node206.va1.mempool.space",
"node201.fmt.mempool.space",
"node202.fmt.mempool.space",
"node203.fmt.mempool.space",
diff --git a/production/mempool-config.signet-lightning.json b/production/mempool-config.signet-lightning.json
index 9971729e2..229b226be 100644
--- a/production/mempool-config.signet-lightning.json
+++ b/production/mempool-config.signet-lightning.json
@@ -16,8 +16,33 @@
"PASSWORD": "__BITCOIN_RPC_PASS__"
},
"ESPLORA": {
- "REST_API_URL": "http://127.0.0.1:5003",
- "UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-signet"
+ "UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-signet",
+ "FALLBACK": [
+ "http://node201.va1.mempool.space:3003",
+ "http://node202.va1.mempool.space:3003",
+ "http://node203.va1.mempool.space:3003",
+ "http://node204.va1.mempool.space:3003",
+ "http://node205.va1.mempool.space:3003",
+ "http://node206.va1.mempool.space:3003",
+ "http://node201.fmt.mempool.space:3003",
+ "http://node202.fmt.mempool.space:3003",
+ "http://node203.fmt.mempool.space:3003",
+ "http://node204.fmt.mempool.space:3003",
+ "http://node205.fmt.mempool.space:3003",
+ "http://node206.fmt.mempool.space:3003",
+ "http://node201.fra.mempool.space:3003",
+ "http://node202.fra.mempool.space:3003",
+ "http://node203.fra.mempool.space:3003",
+ "http://node204.fra.mempool.space:3003",
+ "http://node205.fra.mempool.space:3003",
+ "http://node206.fra.mempool.space:3003",
+ "http://node201.tk7.mempool.space:3003",
+ "http://node202.tk7.mempool.space:3003",
+ "http://node203.tk7.mempool.space:3003",
+ "http://node204.tk7.mempool.space:3003",
+ "http://node205.tk7.mempool.space:3003",
+ "http://node206.tk7.mempool.space:3003"
+ ]
},
"LIGHTNING": {
"ENABLED": true,
diff --git a/production/mempool-config.signet.json b/production/mempool-config.signet.json
index 38d59c0e9..c4b84f11b 100644
--- a/production/mempool-config.signet.json
+++ b/production/mempool-config.signet.json
@@ -27,6 +27,12 @@
"ESPLORA": {
"UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-signet",
"FALLBACK": [
+ "http://node201.va1.mempool.space:3003",
+ "http://node202.va1.mempool.space:3003",
+ "http://node203.va1.mempool.space:3003",
+ "http://node204.va1.mempool.space:3003",
+ "http://node205.va1.mempool.space:3003",
+ "http://node206.va1.mempool.space:3003",
"http://node201.fmt.mempool.space:3003",
"http://node202.fmt.mempool.space:3003",
"http://node203.fmt.mempool.space:3003",
diff --git a/production/mempool-config.testnet-lightning.json b/production/mempool-config.testnet-lightning.json
index ff7d4766f..60ee128a2 100644
--- a/production/mempool-config.testnet-lightning.json
+++ b/production/mempool-config.testnet-lightning.json
@@ -16,8 +16,33 @@
"PASSWORD": "__BITCOIN_RPC_PASS__"
},
"ESPLORA": {
- "REST_API_URL": "http://127.0.0.1:5002",
- "UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-testnet"
+ "UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-testnet",
+ "FALLBACK": [
+ "http://node201.va1.mempool.space:3002",
+ "http://node202.va1.mempool.space:3002",
+ "http://node203.va1.mempool.space:3002",
+ "http://node204.va1.mempool.space:3002",
+ "http://node205.va1.mempool.space:3002",
+ "http://node206.va1.mempool.space:3002",
+ "http://node201.fmt.mempool.space:3002",
+ "http://node202.fmt.mempool.space:3002",
+ "http://node203.fmt.mempool.space:3002",
+ "http://node204.fmt.mempool.space:3002",
+ "http://node205.fmt.mempool.space:3002",
+ "http://node206.fmt.mempool.space:3002",
+ "http://node201.fra.mempool.space:3002",
+ "http://node202.fra.mempool.space:3002",
+ "http://node203.fra.mempool.space:3002",
+ "http://node204.fra.mempool.space:3002",
+ "http://node205.fra.mempool.space:3002",
+ "http://node206.fra.mempool.space:3002",
+ "http://node201.tk7.mempool.space:3002",
+ "http://node202.tk7.mempool.space:3002",
+ "http://node203.tk7.mempool.space:3002",
+ "http://node204.tk7.mempool.space:3002",
+ "http://node205.tk7.mempool.space:3002",
+ "http://node206.tk7.mempool.space:3002"
+ ]
},
"LIGHTNING": {
"ENABLED": true,
diff --git a/production/mempool-config.testnet.json b/production/mempool-config.testnet.json
index c5bdfc8d7..b3d7cfadd 100644
--- a/production/mempool-config.testnet.json
+++ b/production/mempool-config.testnet.json
@@ -27,6 +27,12 @@
"ESPLORA": {
"UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-testnet",
"FALLBACK": [
+ "http://node201.va1.mempool.space:3002",
+ "http://node202.va1.mempool.space:3002",
+ "http://node203.va1.mempool.space:3002",
+ "http://node204.va1.mempool.space:3002",
+ "http://node205.va1.mempool.space:3002",
+ "http://node206.va1.mempool.space:3002",
"http://node201.fmt.mempool.space:3002",
"http://node202.fmt.mempool.space:3002",
"http://node203.fmt.mempool.space:3002",
From 38d30d23e5eb8c3ca40f9a0969620daa7558ec13 Mon Sep 17 00:00:00 2001
From: wiz
Date: Sun, 17 Sep 2023 20:57:47 -0400
Subject: [PATCH 096/128] Add VA1 mempool.space lightning node pubkeys
---
backend/src/api/explorer/nodes.routes.ts | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/backend/src/api/explorer/nodes.routes.ts b/backend/src/api/explorer/nodes.routes.ts
index e2dbcb0b6..3636abe2b 100644
--- a/backend/src/api/explorer/nodes.routes.ts
+++ b/backend/src/api/explorer/nodes.routes.ts
@@ -42,6 +42,12 @@ class NodesRoutes {
switch (config.MEMPOOL.NETWORK) {
case 'testnet':
nodesList = [
+ '0259db43b4e4ac0ff12a805f2d81e521253ba2317f6739bc611d8e2fa156d64256',
+ '0352b9944b9a52bd2116c91f1ba70c4ef851ac5ba27e1b20f1d92da3ade010dd10',
+ '03424f5a7601eaa47482cb17100b31a84a04d14fb44b83a57eeceffd8e299878e3',
+ '032850492ee61a5f7006a2fda6925e4b4ec3782f2b6de2ff0e439ef5a38c3b2470',
+ '022c80bace98831c44c32fb69755f2b353434e0ee9e7fbda29507f7ef8abea1421',
+ '02c3559c833e6f99f9ca05fe503e0b4e7524dea9121344edfd3e811101e0c28680',
'032c7c7819276c4f706a04df1a0f1e10a5495994a7be4c1d3d28ca766e5a2b957b',
'025a7e38c2834dd843591a4d23d5f09cdeb77ddca85f673c2d944a14220ff14cf7',
'0395e2731a1673ef21d7a16a727c4fc4d4c35a861c428ce2c819c53d2b81c8bd55',
@@ -64,6 +70,12 @@ class NodesRoutes {
break;
case 'signet':
nodesList = [
+ '029fe3621fc0c6e08056a14b868f8fb9acca1aa28a129512f6cea0f0d7654d9f92',
+ '02f60cd7a3a4f1c953dd9554a6ebd51a34f8b10b8124b7fc43a0b381139b55c883',
+ '03cbbf581774700865eebd1be42d022bc004ba30881274ab304e088a25d70e773d',
+ '0243348cb3741cfe2d8485fa8375c29c7bc7cbb67577c363cb6987a5e5fd0052cc',
+ '02cb73e631af44bee600d80f8488a9194c9dc5c7590e575c421a070d1be05bc8e9',
+ '0306f55ee631aa1e2cd4d9b2bfcbc14404faec5c541cef8b2e6f779061029d09c4',
'03ddab321b760433cbf561b615ef62ac7d318630c5f51d523aaf5395b90b751956',
'033d92c7bfd213ef1b34c90e985fb5dc77f9ec2409d391492484e57a44c4aca1de',
'02ad010dda54253c1eb9efe38b0760657a3b43ecad62198c359c051c9d99d45781',
@@ -86,6 +98,12 @@ class NodesRoutes {
break;
default:
nodesList = [
+ '02b12b889fe3c943cb05645921040ef13d6d397a2e7a4ad000e28500c505ff26d6',
+ '0302240ac9d71b39617cbde2764837ec3d6198bd6074b15b75d2ff33108e89d2e1',
+ '03364a8ace313376e5e4b68c954e287c6388e16df9e9fdbaf0363ecac41105cbf6',
+ '03229ab4b7f692753e094b93df90530150680f86b535b5183b0cffd75b3df583fc',
+ '03a696eb7acde991c1be97a58a9daef416659539ae462b897f5e9ae361f990228e',
+ '0248bf26cf3a63ab8870f34dc0ec9e6c8c6288cdba96ba3f026f34ec0f13ac4055',
'03fbc17549ec667bccf397ababbcb4cdc0e3394345e4773079ab2774612ec9be61',
'03da9a8623241ccf95f19cd645c6cecd4019ac91570e976eb0a128bebbc4d8a437',
'03ca5340cf85cb2e7cf076e489f785410838de174e40be62723e8a60972ad75144',
From e79c32010dcef264e05bec909a2b730f1f318f23 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Mon, 18 Sep 2023 09:44:22 +0200
Subject: [PATCH 097/128] [lightning] fix js error when there is no geolocation
available
---
frontend/src/app/lightning/nodes-map/nodes-map.component.ts | 2 +-
.../shared/components/geolocation/geolocation.component.ts | 5 +++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/frontend/src/app/lightning/nodes-map/nodes-map.component.ts b/frontend/src/app/lightning/nodes-map/nodes-map.component.ts
index 4f74723cc..ea80d8799 100644
--- a/frontend/src/app/lightning/nodes-map/nodes-map.component.ts
+++ b/frontend/src/app/lightning/nodes-map/nodes-map.component.ts
@@ -114,7 +114,7 @@ export class NodesMap implements OnInit, OnChanges {
node[3], // Alias
node[2], // Public key
node[5], // Channels
- node[6].en, // Country
+ node[6]?.en, // Country
node[7], // ISO Code
]);
}
diff --git a/frontend/src/app/shared/components/geolocation/geolocation.component.ts b/frontend/src/app/shared/components/geolocation/geolocation.component.ts
index 9cce1ea08..1a498a1b2 100644
--- a/frontend/src/app/shared/components/geolocation/geolocation.component.ts
+++ b/frontend/src/app/shared/components/geolocation/geolocation.component.ts
@@ -20,6 +20,11 @@ export class GeolocationComponent implements OnChanges {
formattedLocation: string = '';
ngOnChanges(): void {
+ if (!this.data) {
+ this.formattedLocation = '-';
+ return;
+ }
+
const city = this.data.city ? this.data.city : '';
const subdivisionLikeCity = this.data.city === this.data.subdivision;
let subdivision = this.data.subdivision;
From ef5d2606b76b6e383346592ac5ffd4badec08efe Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Mon, 18 Sep 2023 21:07:24 +0000
Subject: [PATCH 098/128] Add missing count data to longer statistics timespans
---
backend/src/api/statistics/statistics-api.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/backend/src/api/statistics/statistics-api.ts b/backend/src/api/statistics/statistics-api.ts
index ecc0222c1..9518c4a0d 100644
--- a/backend/src/api/statistics/statistics-api.ts
+++ b/backend/src/api/statistics/statistics-api.ts
@@ -220,6 +220,7 @@ class StatisticsApi {
private getQueryForDays(div: number, interval: string) {
return `SELECT
UNIX_TIMESTAMP(added) as added,
+ CAST(avg(unconfirmed_transactions) as DOUBLE) as unconfirmed_transactions,
CAST(avg(vbytes_per_second) as DOUBLE) as vbytes_per_second,
vsize_1,
vsize_2,
From c80201e3dbb551ad480b71f824912e6d4cba377f Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Mon, 18 Sep 2023 21:13:11 +0000
Subject: [PATCH 099/128] hide mempool count line before start of data
---
.../src/app/components/mempool-graph/mempool-graph.component.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts
index d31044be9..935e79b2c 100644
--- a/frontend/src/app/components/mempool-graph/mempool-graph.component.ts
+++ b/frontend/src/app/components/mempool-graph/mempool-graph.component.ts
@@ -136,7 +136,7 @@ export class MempoolGraphComponent implements OnInit, OnChanges {
}
generateCountArray(mempoolStats: OptimizedMempoolStats[]) {
- return mempoolStats.map(stats => [stats.added * 1000, stats.count]);
+ return mempoolStats.filter(stats => stats.count > 0).map(stats => [stats.added * 1000, stats.count]);
}
mountFeeChart() {
From b645ad3fd89ffc269fb8195ede2147a3fc2daf75 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Tue, 19 Sep 2023 22:55:57 +0000
Subject: [PATCH 100/128] Reduce thrashing while initializing blockchain scroll
position
---
.../blockchain/blockchain.component.ts | 2 +-
.../app/components/start/start.component.ts | 144 ++++++++++--------
2 files changed, 85 insertions(+), 61 deletions(-)
diff --git a/frontend/src/app/components/blockchain/blockchain.component.ts b/frontend/src/app/components/blockchain/blockchain.component.ts
index 56b7c39e6..f8f2966dd 100644
--- a/frontend/src/app/components/blockchain/blockchain.component.ts
+++ b/frontend/src/app/components/blockchain/blockchain.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input, Output, EventEmitter, HostListener, ChangeDetectorRef, OnChanges, SimpleChanges } from '@angular/core';
+import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input, Output, EventEmitter, ChangeDetectorRef, OnChanges, SimpleChanges } from '@angular/core';
import { firstValueFrom, Subscription } from 'rxjs';
import { StateService } from '../../services/state.service';
diff --git a/frontend/src/app/components/start/start.component.ts b/frontend/src/app/components/start/start.component.ts
index 18cd0ed30..86748bc8c 100644
--- a/frontend/src/app/components/start/start.component.ts
+++ b/frontend/src/app/components/start/start.component.ts
@@ -1,4 +1,4 @@
-import { Component, ElementRef, HostListener, OnInit, OnDestroy, ViewChild, Input, DoCheck } from '@angular/core';
+import { Component, ElementRef, HostListener, OnInit, OnDestroy, ViewChild, Input, ChangeDetectorRef, ChangeDetectionStrategy, AfterViewChecked } from '@angular/core';
import { Subscription } from 'rxjs';
import { MarkBlockState, StateService } from '../../services/state.service';
import { specialBlocks } from '../../app.constants';
@@ -8,8 +8,9 @@ import { BlockExtended } from '../../interfaces/node-api.interface';
selector: 'app-start',
templateUrl: './start.component.html',
styleUrls: ['./start.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush
})
-export class StartComponent implements OnInit, OnDestroy, DoCheck {
+export class StartComponent implements OnInit, AfterViewChecked, OnDestroy {
@Input() showLoadingIndicator = false;
interval = 60;
@@ -42,6 +43,7 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
pageWidth: number;
firstPageWidth: number;
minScrollWidth: number;
+ currentScrollWidth: number = null;
pageIndex: number = 0;
pages: any[] = [];
pendingMark: number | null = null;
@@ -49,9 +51,10 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
lastUpdate: number = 0;
lastMouseX: number;
velocity: number = 0;
- mempoolOffset: number = 0;
+ mempoolOffset: number | null = null;
+ mempoolWidth: number = 0;
+ scrollLeft: number = null;
- private resizeObserver: ResizeObserver;
chainWidth: number = window.innerWidth;
menuOpen: boolean = false;
menuSliding: boolean = false;
@@ -59,19 +62,12 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
constructor(
private stateService: StateService,
+ private cd: ChangeDetectorRef,
) {
this.isiOS = ['iPhone','iPod','iPad'].includes((navigator as any)?.userAgentData?.platform || navigator.platform);
}
- ngDoCheck(): void {
- if (this.pendingOffset != null) {
- const offset = this.pendingOffset;
- this.pendingOffset = null;
- this.addConvertedScrollOffset(offset);
- }
- }
-
- ngOnInit() {
+ ngOnInit(): void {
this.firstPageWidth = 40 + (this.blockWidth * this.dynamicBlocksAmount);
this.blockCounterSubscription = this.stateService.blocks$.subscribe((blocks) => {
this.blockCount = blocks.length;
@@ -122,7 +118,7 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
this.scrollToBlock(scrollToHeight);
}
}
- if (!this.tipIsSet || (blockHeight < 0 && !this.mempoolOffset)) {
+ if (!this.tipIsSet || (blockHeight < 0 && this.mempoolOffset == null)) {
this.pendingMark = blockHeight;
}
}
@@ -168,11 +164,41 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
});
}
+ ngAfterViewChecked(): void {
+ if (this.currentScrollWidth !== this.blockchainContainer?.nativeElement?.scrollWidth) {
+ this.currentScrollWidth = this.blockchainContainer?.nativeElement?.scrollWidth;
+ if (this.pendingOffset != null) {
+ const delta = this.pendingOffset - (this.mempoolOffset || 0);
+ this.mempoolOffset = this.pendingOffset;
+ this.currentScrollWidth = this.blockchainContainer?.nativeElement?.scrollWidth;
+ this.pendingOffset = null;
+ this.addConvertedScrollOffset(delta);
+ this.applyPendingMarkArrow();
+ } else {
+ this.applyScrollLeft();
+ }
+ }
+ }
+
onMempoolOffsetChange(offset): void {
- const delta = offset - this.mempoolOffset;
- this.addConvertedScrollOffset(delta);
- this.mempoolOffset = offset;
- this.applyPendingMarkArrow();
+ this.pendingOffset = offset;
+ }
+
+ applyScrollLeft(): void {
+ if (this.blockchainContainer?.nativeElement?.scrollWidth) {
+ let lastScrollLeft = null;
+ while (this.scrollLeft < 0 && this.shiftPagesForward() && lastScrollLeft !== this.scrollLeft) {
+ lastScrollLeft = this.scrollLeft;
+ this.scrollLeft += this.pageWidth;
+ }
+ lastScrollLeft = null;
+ while (this.scrollLeft > this.blockchainContainer.nativeElement.scrollWidth && this.shiftPagesBack() && lastScrollLeft !== this.scrollLeft) {
+ lastScrollLeft = this.scrollLeft;
+ this.scrollLeft -= this.pageWidth;
+ }
+ this.blockchainContainer.nativeElement.scrollLeft = this.scrollLeft;
+ }
+ this.cd.markForCheck();
}
applyPendingMarkArrow(): void {
@@ -191,6 +217,7 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
window.clearTimeout(this.menuTimeout);
this.menuTimeout = window.setTimeout(() => {
this.menuSliding = false;
+ this.cd.markForCheck();
}, 300);
}
@@ -200,24 +227,22 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
this.isMobile = this.chainWidth <= 767.98;
let firstVisibleBlock;
let offset;
- if (this.blockchainContainer?.nativeElement != null) {
- this.pages.forEach(page => {
- const left = page.offset - this.getConvertedScrollOffset();
- const right = left + this.pageWidth;
- if (left <= 0 && right > 0) {
- const blockIndex = Math.max(0, Math.floor(left / -this.blockWidth));
- firstVisibleBlock = page.height - blockIndex;
- offset = left + (blockIndex * this.blockWidth);
- }
- });
- }
+ this.pages.forEach(page => {
+ const left = page.offset - this.getConvertedScrollOffset(this.scrollLeft);
+ const right = left + this.pageWidth;
+ if (left <= 0 && right > 0) {
+ const blockIndex = Math.max(0, Math.floor(left / -this.blockWidth));
+ firstVisibleBlock = page.height - blockIndex;
+ offset = left + (blockIndex * this.blockWidth);
+ }
+ });
this.blocksPerPage = Math.ceil(this.chainWidth / this.blockWidth);
this.pageWidth = this.blocksPerPage * this.blockWidth;
this.minScrollWidth = this.firstPageWidth + (this.pageWidth * 2);
if (firstVisibleBlock != null) {
- this.scrollToBlock(firstVisibleBlock, offset + (this.isMobile ? this.blockWidth : 0));
+ this.scrollToBlock(firstVisibleBlock, offset);
} else {
this.updatePages();
}
@@ -227,7 +252,7 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
if (!(event.which > 1 || event.button > 0)) {
this.mouseDragStartX = event.clientX;
this.resetMomentum(event.clientX);
- this.blockchainScrollLeftInit = this.blockchainContainer.nativeElement.scrollLeft;
+ this.blockchainScrollLeftInit = this.scrollLeft;
}
}
onPointerDown(event: PointerEvent) {
@@ -253,8 +278,8 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
if (this.mouseDragStartX != null) {
this.updateVelocity(event.clientX);
this.stateService.setBlockScrollingInProgress(true);
- this.blockchainContainer.nativeElement.scrollLeft =
- this.blockchainScrollLeftInit + this.mouseDragStartX - event.clientX;
+ this.scrollLeft = this.blockchainScrollLeftInit + this.mouseDragStartX - event.clientX;
+ this.applyScrollLeft();
}
}
@HostListener('document:mouseup', [])
@@ -310,25 +335,31 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
} else {
this.velocity += dv;
}
- this.blockchainContainer.nativeElement.scrollLeft -= displacement;
+ this.scrollLeft -= displacement;
+ this.applyScrollLeft();
this.animateMomentum();
}
});
}
onScroll(e) {
+ if (this.blockchainContainer?.nativeElement?.scrollLeft == null) {
+ return;
+ }
+ this.scrollLeft = this.blockchainContainer?.nativeElement?.scrollLeft;
const middlePage = this.pageIndex === 0 ? this.pages[0] : this.pages[1];
// compensate for css transform
const translation = (this.isMobile ? this.chainWidth * 0.95 : this.chainWidth * 0.5);
const backThreshold = middlePage.offset + (this.pageWidth * 0.5) + translation;
const forwardThreshold = middlePage.offset - (this.pageWidth * 0.5) + translation;
- const scrollLeft = this.getConvertedScrollOffset();
- if (scrollLeft > backThreshold) {
+ this.scrollLeft = this.blockchainContainer.nativeElement.scrollLeft;
+ const offsetScroll = this.getConvertedScrollOffset(this.scrollLeft);
+ if (offsetScroll > backThreshold) {
if (this.shiftPagesBack()) {
this.addConvertedScrollOffset(-this.pageWidth);
this.blockchainScrollLeftInit -= this.pageWidth;
}
- } else if (scrollLeft < forwardThreshold) {
+ } else if (offsetScroll < forwardThreshold) {
if (this.shiftPagesForward()) {
this.addConvertedScrollOffset(this.pageWidth);
this.blockchainScrollLeftInit += this.pageWidth;
@@ -337,10 +368,6 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
}
scrollToBlock(height, blockOffset = 0) {
- if (!this.blockchainContainer?.nativeElement) {
- setTimeout(() => { this.scrollToBlock(height, blockOffset); }, 50);
- return;
- }
if (this.isMobile) {
blockOffset -= this.blockWidth;
}
@@ -348,15 +375,15 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
const pages = [];
this.pageIndex = Math.max(viewingPageIndex - 1, 0);
let viewingPage = this.getPageAt(viewingPageIndex);
- const isLastPage = viewingPage.height < this.blocksPerPage;
+ const isLastPage = viewingPage.height <= 0;
if (isLastPage) {
this.pageIndex = Math.max(viewingPageIndex - 2, 0);
viewingPage = this.getPageAt(viewingPageIndex);
}
- const left = viewingPage.offset - this.getConvertedScrollOffset();
+ const left = viewingPage.offset - this.getConvertedScrollOffset(this.scrollLeft);
const blockIndex = viewingPage.height - height;
const targetOffset = (this.blockWidth * blockIndex) + left;
- let deltaOffset = targetOffset - blockOffset;
+ const deltaOffset = targetOffset - blockOffset;
if (isLastPage) {
pages.push(this.getPageAt(viewingPageIndex - 2));
@@ -386,6 +413,7 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
pages.push(this.getPageAt(this.pageIndex + 1));
pages.push(this.getPageAt(this.pageIndex + 2));
this.pages = pages;
+ this.cd.markForCheck();
}
shiftPagesBack(): boolean {
@@ -439,44 +467,40 @@ export class StartComponent implements OnInit, OnDestroy, DoCheck {
blockInViewport(height: number): boolean {
const firstHeight = this.pages[0].height;
const translation = (this.isMobile ? this.chainWidth * 0.95 : this.chainWidth * 0.5);
- const firstX = this.pages[0].offset - this.getConvertedScrollOffset() + translation;
+ const firstX = this.pages[0].offset - this.getConvertedScrollOffset(this.scrollLeft) + translation;
const xPos = firstX + ((firstHeight - height) * 155);
return xPos > -55 && xPos < (this.chainWidth - 100);
}
- getConvertedScrollOffset(): number {
+ getConvertedScrollOffset(scrollLeft): number {
if (this.timeLtr) {
- return -(this.blockchainContainer?.nativeElement?.scrollLeft || 0) - this.mempoolOffset;
+ return -(scrollLeft || 0) - (this.mempoolOffset || 0);
} else {
- return (this.blockchainContainer?.nativeElement?.scrollLeft || 0) - this.mempoolOffset;
+ return (scrollLeft || 0) - (this.mempoolOffset || 0);
}
}
setScrollLeft(offset: number): void {
if (this.timeLtr) {
- this.blockchainContainer.nativeElement.scrollLeft = offset - this.mempoolOffset;
+ this.scrollLeft = offset - (this.mempoolOffset || 0);
} else {
- this.blockchainContainer.nativeElement.scrollLeft = offset + this.mempoolOffset;
+ this.scrollLeft = offset + (this.mempoolOffset || 0);
}
+ this.applyScrollLeft();
}
addConvertedScrollOffset(offset: number): void {
- if (!this.blockchainContainer?.nativeElement) {
- this.pendingOffset = offset;
- return;
- }
if (this.timeLtr) {
- this.blockchainContainer.nativeElement.scrollLeft -= offset;
+ this.scrollLeft -= offset;
} else {
- this.blockchainContainer.nativeElement.scrollLeft += offset;
+ this.scrollLeft += offset;
}
+ this.applyScrollLeft();
}
ngOnDestroy() {
- if (this.blockchainContainer?.nativeElement) {
- // clean up scroll position to prevent caching wrong scroll in Firefox
- this.setScrollLeft(0);
- }
+ // clean up scroll position to prevent caching wrong scroll in Firefox
+ this.setScrollLeft(0);
this.timeLtrSubscription.unsubscribe();
this.chainTipSubscription.unsubscribe();
this.markBlockSubscription.unsubscribe();
From 1a6a0c12ec84f8e3ee8751c4f576127ddb028e4b Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Wed, 20 Sep 2023 03:07:35 +0000
Subject: [PATCH 101/128] Fix blockchain scroll jumping
---
.../app/components/block/block.component.ts | 2 +-
.../blockchain/blockchain.component.html | 2 +-
.../blockchain/blockchain.component.scss | 10 +-----
.../blockchain/blockchain.component.ts | 36 +++++++++++++++----
.../mempool-blocks.component.ts | 10 +++++-
.../app/components/start/start.component.ts | 20 ++++++-----
6 files changed, 53 insertions(+), 27 deletions(-)
diff --git a/frontend/src/app/components/block/block.component.ts b/frontend/src/app/components/block/block.component.ts
index e226807e3..cbe56ca15 100644
--- a/frontend/src/app/components/block/block.component.ts
+++ b/frontend/src/app/components/block/block.component.ts
@@ -166,7 +166,6 @@ export class BlockComponent implements OnInit, OnDestroy {
this.page = 1;
this.error = undefined;
this.fees = undefined;
- this.stateService.markBlock$.next({});
if (history.state.data && history.state.data.blockHeight) {
this.blockHeight = history.state.data.blockHeight;
@@ -176,6 +175,7 @@ export class BlockComponent implements OnInit, OnDestroy {
let isBlockHeight = false;
if (/^[0-9]+$/.test(blockHash)) {
isBlockHeight = true;
+ this.stateService.markBlock$.next({ blockHeight: parseInt(blockHash, 10)});
} else {
this.blockHash = blockHash;
}
diff --git a/frontend/src/app/components/blockchain/blockchain.component.html b/frontend/src/app/components/blockchain/blockchain.component.html
index 2c3f1ad8c..5f625e4b3 100644
--- a/frontend/src/app/components/blockchain/blockchain.component.html
+++ b/frontend/src/app/components/blockchain/blockchain.component.html
@@ -1,5 +1,5 @@
-
+
diff --git a/frontend/src/app/components/blockchain/blockchain.component.scss b/frontend/src/app/components/blockchain/blockchain.component.scss
index 135a8b842..eacd16118 100644
--- a/frontend/src/app/components/blockchain/blockchain.component.scss
+++ b/frontend/src/app/components/blockchain/blockchain.component.scss
@@ -26,15 +26,7 @@
position: absolute;
left: 0;
top: 75px;
- --divider-offset: 50vw;
- --mempool-offset: 0px;
- transform: translateX(calc(var(--divider-offset) + var(--mempool-offset)));
-}
-
-.blockchain-wrapper.time-ltr {
- .position-container {
- transform: translateX(calc(100vw - var(--divider-offset) - var(--mempool-offset)));
- }
+ transform: translateX(1280px);
}
.black-background {
diff --git a/frontend/src/app/components/blockchain/blockchain.component.ts b/frontend/src/app/components/blockchain/blockchain.component.ts
index f8f2966dd..2293b9479 100644
--- a/frontend/src/app/components/blockchain/blockchain.component.ts
+++ b/frontend/src/app/components/blockchain/blockchain.component.ts
@@ -27,8 +27,11 @@ export class BlockchainComponent implements OnInit, OnDestroy, OnChanges {
loadingTip: boolean = true;
connected: boolean = true;
- dividerOffset: number = 0;
- mempoolOffset: number = 0;
+ dividerOffset: number | null = null;
+ mempoolOffset: number | null = null;
+ positionStyle = {
+ transform: "translateX(1280px)",
+ };
constructor(
public stateService: StateService,
@@ -40,6 +43,7 @@ export class BlockchainComponent implements OnInit, OnDestroy, OnChanges {
this.network = this.stateService.network;
this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => {
this.timeLtr = !!ltr;
+ this.updateStyle();
});
this.connectionStateSubscription = this.stateService.connectionState$.subscribe(state => {
this.connected = (state === 2);
@@ -63,29 +67,47 @@ export class BlockchainComponent implements OnInit, OnDestroy, OnChanges {
const prevOffset = this.mempoolOffset;
this.mempoolOffset = 0;
this.mempoolOffsetChange.emit(0);
+ this.updateStyle();
setTimeout(() => {
this.ltrTransitionEnabled = true;
this.flipping = true;
this.stateService.timeLtr.next(!this.timeLtr);
+ this.cd.markForCheck();
setTimeout(() => {
this.ltrTransitionEnabled = false;
this.flipping = false;
this.mempoolOffset = prevOffset;
- this.mempoolOffsetChange.emit(this.mempoolOffset);
+ this.mempoolOffsetChange.emit((this.mempoolOffset || 0));
+ this.updateStyle();
+ this.cd.markForCheck();
}, 1000);
}, 0);
- this.cd.markForCheck();
}
onMempoolWidthChange(width): void {
if (this.flipping) {
return;
}
- this.mempoolOffset = Math.max(0, width - this.dividerOffset);
- this.cd.markForCheck();
+ this.mempoolOffset = Math.max(0, width - (this.dividerOffset || 0));
+ this.updateStyle();
this.mempoolOffsetChange.emit(this.mempoolOffset);
}
+ updateStyle(): void {
+ if (this.dividerOffset == null || this.mempoolOffset == null) {
+ return;
+ }
+ const oldTransform = this.positionStyle.transform;
+ this.positionStyle = this.timeLtr ? {
+ transform: `translateX(calc(100vw - ${this.dividerOffset + this.mempoolOffset}px)`,
+ } : {
+ transform: `translateX(${this.dividerOffset + this.mempoolOffset}px)`,
+ };
+ if (oldTransform !== this.positionStyle.transform) {
+ this.cd.detectChanges();
+ }
+ }
+
ngOnChanges(changes: SimpleChanges): void {
if (changes.containerWidth) {
this.onResize();
@@ -107,6 +129,6 @@ export class BlockchainComponent implements OnInit, OnDestroy, OnChanges {
this.dividerOffset = width * 0.95;
}
}
- this.cd.markForCheck();
+ this.updateStyle();
}
}
diff --git a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts
index 484389cd3..0ddbbd4b7 100644
--- a/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts
+++ b/frontend/src/app/components/mempool-blocks/mempool-blocks.component.ts
@@ -97,6 +97,10 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
ngOnInit() {
this.chainTip = this.stateService.latestBlockHeight;
+ const width = this.containerOffset + (this.stateService.env.MEMPOOL_BLOCKS_AMOUNT) * this.blockOffset;
+ this.mempoolWidth = width;
+ this.widthChange.emit(this.mempoolWidth);
+
if (['', 'testnet', 'signet'].includes(this.stateService.network)) {
this.enabledMiningInfoIfNeeded(this.location.path());
this.location.onUrlChange((url) => this.enabledMiningInfoIfNeeded(url));
@@ -161,11 +165,11 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
return this.mempoolBlocks;
}),
tap(() => {
- this.cd.markForCheck();
const width = this.containerOffset + this.mempoolBlocks.length * this.blockOffset;
if (this.mempoolWidth !== width) {
this.mempoolWidth = width;
this.widthChange.emit(this.mempoolWidth);
+ this.cd.markForCheck();
}
})
);
@@ -215,11 +219,13 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
if (isNewBlock && (block?.extras?.similarity == null || block?.extras?.similarity > 0.5) && !this.tabHidden) {
this.blockIndex++;
}
+ this.cd.markForCheck();
});
this.chainTipSubscription = this.stateService.chainTip$.subscribe((height) => {
if (this.chainTip === -1) {
this.chainTip = height;
+ this.cd.markForCheck();
}
});
@@ -257,6 +263,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
this.blockPadding = 0.24 * this.blockWidth;
this.containerOffset = 0.32 * this.blockWidth;
this.blockOffset = this.blockWidth + this.blockPadding;
+ this.cd.markForCheck();
}
}
@@ -275,6 +282,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
onResize(): void {
this.animateEntry = false;
this.reduceEmptyBlocksToFitScreen(this.mempoolEmptyBlocks);
+ this.cd.markForCheck();
}
trackByFn(index: number, block: MempoolBlock) {
diff --git a/frontend/src/app/components/start/start.component.ts b/frontend/src/app/components/start/start.component.ts
index 86748bc8c..4a15157f0 100644
--- a/frontend/src/app/components/start/start.component.ts
+++ b/frontend/src/app/components/start/start.component.ts
@@ -24,7 +24,7 @@ export class StartComponent implements OnInit, AfterViewChecked, OnDestroy {
timeLtrSubscription: Subscription;
timeLtr: boolean = this.stateService.timeLtr.value;
chainTipSubscription: Subscription;
- chainTip: number = -1;
+ chainTip: number = 100;
tipIsSet: boolean = false;
lastMark: MarkBlockState;
markBlockSubscription: Subscription;
@@ -42,7 +42,7 @@ export class StartComponent implements OnInit, AfterViewChecked, OnDestroy {
blocksPerPage: number = 1;
pageWidth: number;
firstPageWidth: number;
- minScrollWidth: number;
+ minScrollWidth: number = 40 + (155 * (8 + (2 * Math.ceil(window.innerWidth / 155))));
currentScrollWidth: number = null;
pageIndex: number = 0;
pages: any[] = [];
@@ -51,7 +51,7 @@ export class StartComponent implements OnInit, AfterViewChecked, OnDestroy {
lastUpdate: number = 0;
lastMouseX: number;
velocity: number = 0;
- mempoolOffset: number | null = null;
+ mempoolOffset: number = null;
mempoolWidth: number = 0;
scrollLeft: number = null;
@@ -67,12 +67,13 @@ export class StartComponent implements OnInit, AfterViewChecked, OnDestroy {
this.isiOS = ['iPhone','iPod','iPad'].includes((navigator as any)?.userAgentData?.platform || navigator.platform);
}
- ngOnInit(): void {
+ ngOnInit() {
this.firstPageWidth = 40 + (this.blockWidth * this.dynamicBlocksAmount);
this.blockCounterSubscription = this.stateService.blocks$.subscribe((blocks) => {
this.blockCount = blocks.length;
this.dynamicBlocksAmount = Math.min(this.blockCount, this.stateService.env.KEEP_BLOCKS_AMOUNT, 8);
this.firstPageWidth = 40 + (this.blockWidth * this.dynamicBlocksAmount);
+ this.minScrollWidth = 40 + (8 * this.blockWidth) + (this.pageWidth * 2);
if (this.blockCount <= Math.min(8, this.stateService.env.KEEP_BLOCKS_AMOUNT)) {
this.onResize();
}
@@ -181,7 +182,9 @@ export class StartComponent implements OnInit, AfterViewChecked, OnDestroy {
}
onMempoolOffsetChange(offset): void {
- this.pendingOffset = offset;
+ if (offset !== this.mempoolOffset) {
+ this.pendingOffset = offset;
+ }
}
applyScrollLeft(): void {
@@ -198,11 +201,11 @@ export class StartComponent implements OnInit, AfterViewChecked, OnDestroy {
}
this.blockchainContainer.nativeElement.scrollLeft = this.scrollLeft;
}
- this.cd.markForCheck();
+ this.cd.detectChanges();
}
applyPendingMarkArrow(): void {
- if (this.pendingMark != null) {
+ if (this.pendingMark != null && this.pendingMark <= this.chainTip) {
if (this.pendingMark < 0) {
this.scrollToBlock(this.chainTip - this.pendingMark);
} else {
@@ -239,13 +242,14 @@ export class StartComponent implements OnInit, AfterViewChecked, OnDestroy {
this.blocksPerPage = Math.ceil(this.chainWidth / this.blockWidth);
this.pageWidth = this.blocksPerPage * this.blockWidth;
- this.minScrollWidth = this.firstPageWidth + (this.pageWidth * 2);
+ this.minScrollWidth = 40 + (8 * this.blockWidth) + (this.pageWidth * 2);
if (firstVisibleBlock != null) {
this.scrollToBlock(firstVisibleBlock, offset);
} else {
this.updatePages();
}
+ this.cd.markForCheck();
}
onMouseDown(event: MouseEvent) {
From 368ab1dc668c52b0c0e1ca1348a0ec1312326262 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Tue, 22 Aug 2023 02:54:23 +0900
Subject: [PATCH 102/128] Update canonical link with block hash
---
.../src/app/bisq/bisq-block/bisq-block.component.ts | 1 +
frontend/src/app/components/block/block.component.ts | 1 +
frontend/src/app/services/seo.service.ts | 12 ++++++++++++
3 files changed, 14 insertions(+)
diff --git a/frontend/src/app/bisq/bisq-block/bisq-block.component.ts b/frontend/src/app/bisq/bisq-block/bisq-block.component.ts
index 42f62fbc0..59bb16a9e 100644
--- a/frontend/src/app/bisq/bisq-block/bisq-block.component.ts
+++ b/frontend/src/app/bisq/bisq-block/bisq-block.component.ts
@@ -69,6 +69,7 @@ export class BisqBlockComponent implements OnInit, OnDestroy {
this.location.replaceState(
this.router.createUrlTree(['/bisq/block/', hash]).toString()
);
+ this.seoService.updateCanonical(this.location.path());
return this.bisqApiService.getBlock$(this.blockHash)
.pipe(catchError(this.caughtHttpError.bind(this)));
}),
diff --git a/frontend/src/app/components/block/block.component.ts b/frontend/src/app/components/block/block.component.ts
index cbe56ca15..bb83494c5 100644
--- a/frontend/src/app/components/block/block.component.ts
+++ b/frontend/src/app/components/block/block.component.ts
@@ -202,6 +202,7 @@ export class BlockComponent implements OnInit, OnDestroy {
this.location.replaceState(
this.router.createUrlTree([(this.network ? '/' + this.network : '') + '/block/', hash]).toString()
);
+ this.seoService.updateCanonical(this.location.path());
return this.apiService.getBlock$(hash).pipe(
catchError((err) => {
this.error = err;
diff --git a/frontend/src/app/services/seo.service.ts b/frontend/src/app/services/seo.service.ts
index 2584cbaed..3d095e1c3 100644
--- a/frontend/src/app/services/seo.service.ts
+++ b/frontend/src/app/services/seo.service.ts
@@ -12,6 +12,8 @@ export class SeoService {
baseTitle = 'mempool';
baseDescription = 'Explore the full Bitcoin ecosystem with The Mempool Open Projectâ„¢.';
+ canonicalLink: HTMLElement = document.getElementById('canonical');
+
constructor(
private titleService: Title,
private metaService: Meta,
@@ -65,6 +67,16 @@ export class SeoService {
this.metaService.updateTag({ property: 'og:description', content: this.getDescription()});
}
+ updateCanonical(path) {
+ let domain = 'mempool.space';
+ if (this.stateService.env.BASE_MODULE === 'liquid') {
+ domain = 'liquid.network';
+ } else if (this.stateService.env.BASE_MODULE === 'bisq') {
+ domain = 'bisq.markets';
+ }
+ this.canonicalLink.setAttribute('href', 'https://' + domain + path);
+ }
+
getTitle(): string {
if (this.network === 'testnet')
return this.baseTitle + ' - Bitcoin Testnet';
From 593e72f90549644ad5bce68725fff39443184708 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 22 Sep 2023 18:51:29 -0700
Subject: [PATCH 103/128] Update Cypress to v13 and other test deps
---
frontend/package-lock.json | 183 +++++++++++++++----------------------
frontend/package.json | 6 +-
2 files changed, 77 insertions(+), 112 deletions(-)
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 666bfc33c..36049f9f0 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -59,9 +59,9 @@
"optionalDependencies": {
"@cypress/schematic": "^2.5.0",
"@types/cypress": "^1.1.3",
- "cypress": "^12.17.2",
- "cypress-fail-on-console-error": "~4.0.3",
- "cypress-wait-until": "^2.0.0",
+ "cypress": "^13.2.0",
+ "cypress-fail-on-console-error": "~5.0.0",
+ "cypress-wait-until": "^2.0.1",
"mock-socket": "~9.2.1",
"start-server-and-test": "~2.0.0"
}
@@ -3016,9 +3016,9 @@
}
},
"node_modules/@cypress/request": {
- "version": "2.88.11",
- "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz",
- "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz",
+ "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==",
"optional": true,
"dependencies": {
"aws-sign2": "~0.7.0",
@@ -3034,9 +3034,9 @@
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"performance-now": "^2.1.0",
- "qs": "~6.10.3",
+ "qs": "6.10.4",
"safe-buffer": "^5.1.2",
- "tough-cookie": "~2.5.0",
+ "tough-cookie": "^4.1.3",
"tunnel-agent": "^0.6.0",
"uuid": "^8.3.2"
},
@@ -4333,9 +4333,9 @@
"integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q=="
},
"node_modules/@types/node": {
- "version": "18.11.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
- "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg=="
+ "version": "18.17.18",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.18.tgz",
+ "integrity": "sha512-/4QOuy3ZpV7Ya1GTRz5CYSz3DgkKpyUptXuQ5PPce7uuyJAOR7r9FhkmxJfvcNUXyklbC63a+YvB3jxy7s9ngw=="
},
"node_modules/@types/qrcode": {
"version": "1.5.0",
@@ -7113,15 +7113,15 @@
"peer": true
},
"node_modules/cypress": {
- "version": "12.17.2",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.17.2.tgz",
- "integrity": "sha512-hxWAaWbqQBzzMuadSGSuQg5PDvIGOovm6xm0hIfpCVcORsCAj/gF2p0EvfnJ4f+jK2PCiDgP6D2eeE9/FK4Mjg==",
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.2.0.tgz",
+ "integrity": "sha512-AvDQxBydE771GTq0TR4ZUBvv9m9ffXuB/ueEtpDF/6gOcvFR96amgwSJP16Yhqw6VhmwqspT5nAGzoxxB+D89g==",
"hasInstallScript": true,
"optional": true,
"dependencies": {
- "@cypress/request": "^2.88.11",
+ "@cypress/request": "^3.0.0",
"@cypress/xvfb": "^1.2.4",
- "@types/node": "^14.14.31",
+ "@types/node": "^18.17.5",
"@types/sinonjs__fake-timers": "8.1.1",
"@types/sizzle": "^2.3.2",
"arch": "^2.2.0",
@@ -7154,6 +7154,7 @@
"minimist": "^1.2.8",
"ospath": "^1.2.2",
"pretty-bytes": "^5.6.0",
+ "process": "^0.11.10",
"proxy-from-env": "1.0.0",
"request-progress": "^3.0.0",
"semver": "^7.5.3",
@@ -7166,13 +7167,13 @@
"cypress": "bin/cypress"
},
"engines": {
- "node": "^14.0.0 || ^16.0.0 || >=18.0.0"
+ "node": "^16.0.0 || ^18.0.0 || >=20.0.0"
}
},
"node_modules/cypress-fail-on-console-error": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-4.0.3.tgz",
- "integrity": "sha512-v2nPupd2brtxKLkDQX58SbEPWRF/2nDbqPTnYyhPIYHqG7U3P2dGUZ3zraETKKoLhU3+C0otjgB6Vg/bHhocQw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-5.0.0.tgz",
+ "integrity": "sha512-xui/aSu8rmExZjZNgId3iX0MsGZih6ZoFH+54vNHrK3HaqIZZX5hUuNhAcmfSoM1rIDc2DeITeVaMn/hiQ9IWQ==",
"optional": true,
"dependencies": {
"chai": "^4.3.4",
@@ -7182,19 +7183,9 @@
}
},
"node_modules/cypress-wait-until": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-2.0.0.tgz",
- "integrity": "sha512-ulUZyrWBn+OuC8oiQuGKAScDYfpaWnE3dEE/raUo64w4RHQxZrQ/iMIWT4ZjGMMPr3P+BFEALCRnjQeRqzZj6g==",
- "optional": true,
- "engines": {
- "node": ">=18.16.0",
- "npm": ">=9.5.1"
- }
- },
- "node_modules/cypress/node_modules/@types/node": {
- "version": "14.18.53",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz",
- "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-2.0.1.tgz",
+ "integrity": "sha512-+IyVnYNiaX1+C+V/LazrJWAi/CqiwfNoRSrFviECQEyolW1gDRy765PZosL2alSSGK8V10Y7BGfOQyZUDgmnjQ==",
"optional": true
},
"node_modules/cypress/node_modules/ansi-styles": {
@@ -10976,28 +10967,6 @@
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
},
- "node_modules/jsdom/node_modules/tough-cookie": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
- "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
- "dependencies": {
- "psl": "^1.1.33",
- "punycode": "^2.1.1",
- "universalify": "^0.2.0",
- "url-parse": "^1.5.3"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/jsdom/node_modules/universalify": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
- "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
- "engines": {
- "node": ">= 4.0.0"
- }
- },
"node_modules/jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -15682,16 +15651,25 @@
}
},
"node_modules/tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "optional": true,
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
+ "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
"dependencies": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
},
"engines": {
- "node": ">=0.8"
+ "node": ">=6"
+ }
+ },
+ "node_modules/tough-cookie/node_modules/universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "engines": {
+ "node": ">= 4.0.0"
}
},
"node_modules/tr46": {
@@ -19010,9 +18988,9 @@
}
},
"@cypress/request": {
- "version": "2.88.11",
- "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz",
- "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@cypress/request/-/request-3.0.1.tgz",
+ "integrity": "sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==",
"optional": true,
"requires": {
"aws-sign2": "~0.7.0",
@@ -19028,9 +19006,9 @@
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"performance-now": "^2.1.0",
- "qs": "~6.10.3",
+ "qs": "6.10.4",
"safe-buffer": "^5.1.2",
- "tough-cookie": "~2.5.0",
+ "tough-cookie": "^4.1.3",
"tunnel-agent": "^0.6.0",
"uuid": "^8.3.2"
}
@@ -19927,9 +19905,9 @@
"integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q=="
},
"@types/node": {
- "version": "18.11.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.9.tgz",
- "integrity": "sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg=="
+ "version": "18.17.18",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.18.tgz",
+ "integrity": "sha512-/4QOuy3ZpV7Ya1GTRz5CYSz3DgkKpyUptXuQ5PPce7uuyJAOR7r9FhkmxJfvcNUXyklbC63a+YvB3jxy7s9ngw=="
},
"@types/qrcode": {
"version": "1.5.0",
@@ -22065,14 +22043,14 @@
"peer": true
},
"cypress": {
- "version": "12.17.2",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.17.2.tgz",
- "integrity": "sha512-hxWAaWbqQBzzMuadSGSuQg5PDvIGOovm6xm0hIfpCVcORsCAj/gF2p0EvfnJ4f+jK2PCiDgP6D2eeE9/FK4Mjg==",
+ "version": "13.2.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.2.0.tgz",
+ "integrity": "sha512-AvDQxBydE771GTq0TR4ZUBvv9m9ffXuB/ueEtpDF/6gOcvFR96amgwSJP16Yhqw6VhmwqspT5nAGzoxxB+D89g==",
"optional": true,
"requires": {
- "@cypress/request": "^2.88.11",
+ "@cypress/request": "^3.0.0",
"@cypress/xvfb": "^1.2.4",
- "@types/node": "^14.14.31",
+ "@types/node": "^18.17.5",
"@types/sinonjs__fake-timers": "8.1.1",
"@types/sizzle": "^2.3.2",
"arch": "^2.2.0",
@@ -22105,6 +22083,7 @@
"minimist": "^1.2.8",
"ospath": "^1.2.2",
"pretty-bytes": "^5.6.0",
+ "process": "^0.11.10",
"proxy-from-env": "1.0.0",
"request-progress": "^3.0.0",
"semver": "^7.5.3",
@@ -22114,12 +22093,6 @@
"yauzl": "^2.10.0"
},
"dependencies": {
- "@types/node": {
- "version": "14.18.53",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.53.tgz",
- "integrity": "sha512-soGmOpVBUq+gaBMwom1M+krC/NNbWlosh4AtGA03SyWNDiqSKtwp7OulO1M6+mg8YkHMvJ/y0AkCeO8d1hNb7A==",
- "optional": true
- },
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -22236,9 +22209,9 @@
}
},
"cypress-fail-on-console-error": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-4.0.3.tgz",
- "integrity": "sha512-v2nPupd2brtxKLkDQX58SbEPWRF/2nDbqPTnYyhPIYHqG7U3P2dGUZ3zraETKKoLhU3+C0otjgB6Vg/bHhocQw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cypress-fail-on-console-error/-/cypress-fail-on-console-error-5.0.0.tgz",
+ "integrity": "sha512-xui/aSu8rmExZjZNgId3iX0MsGZih6ZoFH+54vNHrK3HaqIZZX5hUuNhAcmfSoM1rIDc2DeITeVaMn/hiQ9IWQ==",
"optional": true,
"requires": {
"chai": "^4.3.4",
@@ -22248,9 +22221,9 @@
}
},
"cypress-wait-until": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-2.0.0.tgz",
- "integrity": "sha512-ulUZyrWBn+OuC8oiQuGKAScDYfpaWnE3dEE/raUo64w4RHQxZrQ/iMIWT4ZjGMMPr3P+BFEALCRnjQeRqzZj6g==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/cypress-wait-until/-/cypress-wait-until-2.0.1.tgz",
+ "integrity": "sha512-+IyVnYNiaX1+C+V/LazrJWAi/CqiwfNoRSrFviECQEyolW1gDRy765PZosL2alSSGK8V10Y7BGfOQyZUDgmnjQ==",
"optional": true
},
"d": {
@@ -24967,22 +24940,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
- },
- "tough-cookie": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
- "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
- "requires": {
- "psl": "^1.1.33",
- "punycode": "^2.1.1",
- "universalify": "^0.2.0",
- "url-parse": "^1.5.3"
- }
- },
- "universalify": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
- "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="
}
}
},
@@ -28497,13 +28454,21 @@
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
"tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "optional": true,
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
+ "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
"requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "dependencies": {
+ "universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg=="
+ }
}
},
"tr46": {
diff --git a/frontend/package.json b/frontend/package.json
index 2bb2ab2cd..31e584cb3 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -111,9 +111,9 @@
"optionalDependencies": {
"@cypress/schematic": "^2.5.0",
"@types/cypress": "^1.1.3",
- "cypress": "^12.17.2",
- "cypress-fail-on-console-error": "~4.0.3",
- "cypress-wait-until": "^2.0.0",
+ "cypress": "^13.2.0",
+ "cypress-fail-on-console-error": "~5.0.0",
+ "cypress-wait-until": "^2.0.1",
"mock-socket": "~9.2.1",
"start-server-and-test": "~2.0.0"
},
From e3cd7dbf34b3309ecd2752cb8741ef277c7b5a21 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Sat, 23 Sep 2023 07:57:49 -0700
Subject: [PATCH 104/128] Add script to print the backend info on all servers
---
scripts/get_backend_hash.sh | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 scripts/get_backend_hash.sh
diff --git a/scripts/get_backend_hash.sh b/scripts/get_backend_hash.sh
new file mode 100644
index 000000000..1e3935557
--- /dev/null
+++ b/scripts/get_backend_hash.sh
@@ -0,0 +1,7 @@
+for LOCATION in fmt va1 fra tk7
+do
+ for NODE in 201 202 203 204 205 206
+ do
+ echo $(curl -sk https://node$NODE.$LOCATION.mempool.space/api/v1/backend-info)
+ done
+done
\ No newline at end of file
From 52725df2962bad748c3d1a3fb98763aef9a19027 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Sat, 23 Sep 2023 07:58:09 -0700
Subject: [PATCH 105/128] Add workflow to run the backend info script
---
.github/workflows/get_backend_hash.yml | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 .github/workflows/get_backend_hash.yml
diff --git a/.github/workflows/get_backend_hash.yml b/.github/workflows/get_backend_hash.yml
new file mode 100644
index 000000000..57950dee4
--- /dev/null
+++ b/.github/workflows/get_backend_hash.yml
@@ -0,0 +1,19 @@
+name: 'Print backend hashes'
+
+on: [workflow_dispatch]
+
+jobs:
+ print-backend-sha:
+ runs-on: 'ubuntu-latest'
+ name: Print backend hashes
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ path: repo
+
+ - name: Run script
+ working-directory: repo
+ run: |
+ chmod +x ./scripts/get_backend_hash.sh
+ sh ./scripts/get_backend_hash.sh
From 928d3282a2f4d63ebcf890c26ac07c5a2cbcc06e Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 23 Sep 2023 15:20:54 +0000
Subject: [PATCH 106/128] Bump axios from 1.4.0 to 1.5.0 in /backend
Bumps [axios](https://github.com/axios/axios) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.4.0...v1.5.0)
---
updated-dependencies:
- dependency-name: axios
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
backend/package-lock.json | 14 +++++++-------
backend/package.json | 2 +-
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/backend/package-lock.json b/backend/package-lock.json
index f5452e908..c8dea34c0 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -12,7 +12,7 @@
"@babel/core": "^7.21.3",
"@mempool/electrum-client": "1.1.9",
"@types/node": "^18.15.3",
- "axios": "~1.4.0",
+ "axios": "~1.5.0",
"bitcoinjs-lib": "~6.1.3",
"crypto-js": "~4.1.1",
"express": "~4.18.2",
@@ -2321,9 +2321,9 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
- "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz",
+ "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
@@ -9397,9 +9397,9 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"axios": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
- "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.0.tgz",
+ "integrity": "sha512-D4DdjDo5CY50Qms0qGQTTw6Q44jl7zRwY7bthds06pUGfChBCTcQs+N743eFWGEd6pRTMd6A+I87aWyFV5wiZQ==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
diff --git a/backend/package.json b/backend/package.json
index 500cbf93c..2db8f2046 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -41,7 +41,7 @@
"@babel/core": "^7.21.3",
"@mempool/electrum-client": "1.1.9",
"@types/node": "^18.15.3",
- "axios": "~1.4.0",
+ "axios": "~1.5.0",
"bitcoinjs-lib": "~6.1.3",
"crypto-js": "~4.1.1",
"express": "~4.18.2",
From 67b2aa2ff0431c2500b69c27ef650d7c42f3d6c8 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Sat, 23 Sep 2023 14:42:54 -0700
Subject: [PATCH 107/128] Add trailing slash to the sync-assets script
---
frontend/package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/package.json b/frontend/package.json
index 31e584cb3..214cf9ff6 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -35,7 +35,7 @@
"start:local-staging": "npm run generate-config && npm run sync-assets-dev && npm run ng -- serve -c local-staging",
"start:mixed": "npm run generate-config && npm run sync-assets-dev && npm run ng -- serve -c mixed",
"build": "npm run generate-config && npm run ng -- build --configuration production --localize && npm run sync-assets && npm run build-mempool.js",
- "sync-assets": "rsync -av ./src/resources ./dist/mempool/browser && node sync-assets.js 'dist/mempool/browser/resources'",
+ "sync-assets": "rsync -av ./src/resources ./dist/mempool/browser && node sync-assets.js 'dist/mempool/browser/resources/'",
"sync-assets-dev": "node sync-assets.js 'src/resources/'",
"generate-config": "node generate-config.js",
"build-mempool.js": "npm run build-mempool-js && npm run build-mempool-liquid-js && npm run build-mempool-bisq-js",
From 4ed629a8ea45fb9c7be9ff4fb5ed692414383a10 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Sat, 23 Sep 2023 14:43:54 -0700
Subject: [PATCH 108/128] Minor improvements to sync-assets
---
frontend/sync-assets.js | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/frontend/sync-assets.js b/frontend/sync-assets.js
index 49618dea3..7e282eadc 100644
--- a/frontend/sync-assets.js
+++ b/frontend/sync-assets.js
@@ -1,6 +1,7 @@
var https = require('https');
var fs = require('fs');
var crypto = require('crypto');
+var path = require('node:path');
const CONFIG_FILE_NAME = 'mempool-frontend-config.json';
let configContent = {};
@@ -8,6 +9,13 @@ let configContent = {};
var PATH;
if (process.argv[2]) {
PATH = process.argv[2];
+ PATH += PATH.endsWith("/") ? "" : "/"
+ PATH = path.normalize(PATH);
+ console.log(`[sync-assets] using PATH ${PATH}`);
+ if (!fs.existsSync(PATH)){
+ console.log(`${PATH} does not exist, creating`);
+ fs.mkdirSync(PATH, { recursive: true });
+ }
}
if (!PATH) {
@@ -79,7 +87,7 @@ function downloadMiningPoolLogos$() {
}
let downloadedCount = 0;
for (const poolLogo of poolLogos) {
- const filePath = `${PATH}/mining-pools/${poolLogo.name}`;
+ const filePath = PATH + `mining-pools/${poolLogo.name}`;
if (fs.existsSync(filePath)) {
const localHash = getLocalHash(filePath);
if (localHash !== poolLogo.sha) {
@@ -89,6 +97,10 @@ function downloadMiningPoolLogos$() {
}
} else {
console.log(`${poolLogo.name} is missing, downloading...`);
+ const miningPoolsDir = PATH + `mining-pools/`;
+ if (!fs.existsSync(miningPoolsDir)){
+ fs.mkdirSync(miningPoolsDir, { recursive: true });
+ }
download(filePath, poolLogo.download_url);
downloadedCount++;
}
@@ -140,7 +152,7 @@ function downloadPromoVideoSubtiles$() {
}
let downloadedCount = 0;
for (const language of videoLanguages) {
- const filePath = `${PATH}/promo-video/${language.name}`;
+ const filePath = PATH + `promo-video/${language.name}`;
if (fs.existsSync(filePath)) {
const localHash = getLocalHash(filePath);
if (localHash !== language.sha) {
@@ -150,6 +162,11 @@ function downloadPromoVideoSubtiles$() {
}
} else {
console.log(`${language.name} is missing, downloading`);
+ const promoVideosDir = PATH + `promo-video/`;
+ if (!fs.existsSync(promoVideosDir)){
+ fs.mkdirSync(promoVideosDir, { recursive: true });
+ }
+
download(filePath, language.download_url);
downloadedCount++;
}
@@ -202,7 +219,7 @@ function downloadPromoVideo$() {
if (item.name !== 'promo.mp4') {
continue;
}
- const filePath = `${PATH}/promo-video/mempool-promo.mp4`;
+ const filePath = PATH + `promo-video/mempool-promo.mp4`;
if (fs.existsSync(filePath)) {
const localHash = getLocalHash(filePath);
if (localHash !== item.sha) {
@@ -246,10 +263,13 @@ const testnetAssetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstre
console.log('Downloading assets');
download(PATH + 'assets.json', assetsJsonUrl);
+
console.log('Downloading assets minimal');
download(PATH + 'assets.minimal.json', assetsMinimalJsonUrl);
+
console.log('Downloading testnet assets');
download(PATH + 'assets-testnet.json', testnetAssetsJsonUrl);
+
console.log('Downloading testnet assets minimal');
download(PATH + 'assets-testnet.minimal.json', testnetAssetsMinimalJsonUrl);
From c35f8a3f082dde162726889cf9fdcfdc038901fe Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Sat, 23 Sep 2023 15:39:00 -0700
Subject: [PATCH 109/128] Add SKIP_SYNC and verbosity from previous PR
---
frontend/sync-assets.js | 101 +++++++++++++++++++++++++++++-----------
1 file changed, 74 insertions(+), 27 deletions(-)
diff --git a/frontend/sync-assets.js b/frontend/sync-assets.js
index 7e282eadc..f7c8a455d 100644
--- a/frontend/sync-assets.js
+++ b/frontend/sync-assets.js
@@ -2,6 +2,18 @@ var https = require('https');
var fs = require('fs');
var crypto = require('crypto');
var path = require('node:path');
+const LOG_TAG = '[sync-assets]';
+let verbose = false;
+
+if (parseInt(process.env.SKIP_SYNC) === 1) {
+ console.log(`${LOG_TAG} SKIP_SYNC is set, not checking any assets`);
+ process.exit(0);
+}
+
+if (parseInt(process.env.VERBOSE) === 1) {
+ console.log(`${LOG_TAG} VERBOSE is set, logs will be more verbose`);
+ verbose = true;
+}
const CONFIG_FILE_NAME = 'mempool-frontend-config.json';
let configContent = {};
@@ -13,7 +25,7 @@ if (process.argv[2]) {
PATH = path.normalize(PATH);
console.log(`[sync-assets] using PATH ${PATH}`);
if (!fs.existsSync(PATH)){
- console.log(`${PATH} does not exist, creating`);
+ console.log(`${LOG_TAG} ${PATH} does not exist, creating`);
fs.mkdirSync(PATH, { recursive: true });
}
}
@@ -25,12 +37,12 @@ if (!PATH) {
try {
const rawConfig = fs.readFileSync(CONFIG_FILE_NAME);
configContent = JSON.parse(rawConfig);
- console.log(`${CONFIG_FILE_NAME} file found, using provided config`);
+ console.log(`${LOG_TAG} ${CONFIG_FILE_NAME} file found, using provided config`);
} catch (e) {
if (e.code !== 'ENOENT') {
throw new Error(e);
} else {
- console.log(`${CONFIG_FILE_NAME} file not found, using default config`);
+ console.log(`${LOG_TAG} ${CONFIG_FILE_NAME} file not found, using default config`);
}
}
@@ -45,6 +57,11 @@ function download(filename, url) {
})
.on('error', function(e) {
throw new Error(e);
+ })
+ .on('finish', () => {
+ if (verbose) {
+ console.log(`${LOG_TAG} Finished downloading ${url} to ${filename}`);
+ }
});
}
@@ -52,12 +69,18 @@ function getLocalHash(filePath) {
const size = fs.statSync(filePath);
const buffer = fs.readFileSync(filePath);
const bufferWithHeader = Buffer.concat([Buffer.from('blob '), Buffer.from(`${size.size}`), Buffer.from('\0'), buffer]);
- return crypto.createHash('sha1').update(bufferWithHeader).digest('hex');
+ const hash = crypto.createHash('sha1').update(bufferWithHeader).digest('hex');
+
+ if (verbose) {
+ console.log(`${LOG_TAG} \tgetLocalHash ${filePath} ${hash}`);
+ }
+
+ return hash;
}
function downloadMiningPoolLogos$() {
return new Promise((resolve, reject) => {
- console.log('Checking if mining pool logos needs downloading or updating...');
+ console.log(`${LOG_TAG} Checking if mining pool logos needs downloading or updating...`);
const options = {
host: 'api.github.com',
path: '/repos/mempool/mining-pool-logos/contents/',
@@ -66,7 +89,7 @@ function downloadMiningPoolLogos$() {
};
if (githubSecret) {
- console.log('Downloading the mining pool logos with authentication');
+ console.log(`${LOG_TAG} Downloading the mining pool logos with authentication`);
options.headers['authorization'] = `Bearer ${githubSecret}`;
options.headers['X-GitHub-Api-Version'] = '2022-11-28';
}
@@ -90,13 +113,17 @@ function downloadMiningPoolLogos$() {
const filePath = PATH + `mining-pools/${poolLogo.name}`;
if (fs.existsSync(filePath)) {
const localHash = getLocalHash(filePath);
+ if (verbose) {
+ console.log(`${LOG_TAG} Remote ${poolLogo.name} logo hash ${poolLogo.sha}`);
+ console.log(`${LOG_TAG} \tchecking if ${filePath} exists: ${fs.existsSync(filePath)}`);
+ }
if (localHash !== poolLogo.sha) {
- console.log(`${poolLogo.name} is different on the remote, downloading...`);
+ console.log(`${LOG_TAG} \t\t${poolLogo.name} is different on the remote, downloading...`);
download(filePath, poolLogo.download_url);
downloadedCount++;
}
} else {
- console.log(`${poolLogo.name} is missing, downloading...`);
+ console.log(`${LOG_TAG} ${poolLogo.name} is missing, downloading...`);
const miningPoolsDir = PATH + `mining-pools/`;
if (!fs.existsSync(miningPoolsDir)){
fs.mkdirSync(miningPoolsDir, { recursive: true });
@@ -105,7 +132,7 @@ function downloadMiningPoolLogos$() {
downloadedCount++;
}
}
- console.log(`Downloaded ${downloadedCount} and skipped ${poolLogos.length - downloadedCount} existing mining pool logos`);
+ console.log(`${LOG_TAG} Downloaded ${downloadedCount} and skipped ${poolLogos.length - downloadedCount} existing mining pool logos`);
resolve();
} catch (e) {
reject(`Unable to download mining pool logos. Trying again at next restart. Reason: ${e instanceof Error ? e.message : e}`);
@@ -121,7 +148,7 @@ function downloadMiningPoolLogos$() {
function downloadPromoVideoSubtiles$() {
return new Promise((resolve, reject) => {
- console.log('Checking if promo video subtitles needs downloading or updating...');
+ console.log(`${LOG_TAG} Checking if promo video subtitles needs downloading or updating...`);
const options = {
host: 'api.github.com',
path: '/repos/mempool/mempool-promo/contents/subtitles',
@@ -130,7 +157,7 @@ function downloadPromoVideoSubtiles$() {
};
if (githubSecret) {
- console.log('Downloading the promo video subtitles with authentication');
+ console.log(`${LOG_TAG} Downloading the promo video subtitles with authentication`);
options.headers['authorization'] = `Bearer ${githubSecret}`;
options.headers['X-GitHub-Api-Version'] = '2022-11-28';
}
@@ -154,14 +181,18 @@ function downloadPromoVideoSubtiles$() {
for (const language of videoLanguages) {
const filePath = PATH + `promo-video/${language.name}`;
if (fs.existsSync(filePath)) {
+ if (verbose) {
+ console.log(`${LOG_TAG} ${language.name} remote promo video hash ${language.sha}`);
+ }
const localHash = getLocalHash(filePath);
+
if (localHash !== language.sha) {
- console.log(`${language.name} is different on the remote, updating`);
+ console.log(`${LOG_TAG} ${language.name} is different on the remote, updating`);
download(filePath, language.download_url);
downloadedCount++;
}
} else {
- console.log(`${language.name} is missing, downloading`);
+ console.log(`${LOG_TAG} ${language.name} is missing, downloading`);
const promoVideosDir = PATH + `promo-video/`;
if (!fs.existsSync(promoVideosDir)){
fs.mkdirSync(promoVideosDir, { recursive: true });
@@ -171,7 +202,7 @@ function downloadPromoVideoSubtiles$() {
downloadedCount++;
}
}
- console.log(`Downloaded ${downloadedCount} and skipped ${videoLanguages.length - downloadedCount} existing video subtitles`);
+ console.log(`${LOG_TAG} Downloaded ${downloadedCount} and skipped ${videoLanguages.length - downloadedCount} existing video subtitles`);
resolve();
} catch (e) {
reject(`Unable to download video subtitles. Trying again at next restart. Reason: ${e instanceof Error ? e.message : e}`);
@@ -187,7 +218,7 @@ function downloadPromoVideoSubtiles$() {
function downloadPromoVideo$() {
return new Promise((resolve, reject) => {
- console.log('Checking if promo video needs downloading or updating...');
+ console.log(`${LOG_TAG} Checking if promo video needs downloading or updating...`);
const options = {
host: 'api.github.com',
path: '/repos/mempool/mempool-promo/contents',
@@ -196,7 +227,7 @@ function downloadPromoVideo$() {
};
if (githubSecret) {
- console.log('Downloading the promo videos with authentication');
+ console.log(`${LOG_TAG} Downloading the promo video with authentication`);
options.headers['authorization'] = `Bearer ${githubSecret}`;
options.headers['X-GitHub-Api-Version'] = '2022-11-28';
}
@@ -222,15 +253,16 @@ function downloadPromoVideo$() {
const filePath = PATH + `promo-video/mempool-promo.mp4`;
if (fs.existsSync(filePath)) {
const localHash = getLocalHash(filePath);
+
if (localHash !== item.sha) {
- console.log(`mempool-promo.mp4 is different on the remote, updating`);
+ console.log(`${LOG_TAG} \tmempool-promo.mp4 is different on the remote, updating`);
download(filePath, item.download_url);
- console.log('mempool-promo.mp4 downloaded.');
+ console.log(`${LOG_TAG} \tmempool-promo.mp4 downloaded.`);
} else {
- console.log(`mempool-promo.mp4 is already up to date. Skipping.`);
+ console.log(`${LOG_TAG} \tmempool-promo.mp4 is already up to date. Skipping.`);
}
} else {
- console.log(`mempool-promo.mp4 is missing, downloading`);
+ console.log(`${LOG_TAG} \tmempool-promo.mp4 is missing, downloading`);
download(filePath, item.download_url);
}
}
@@ -261,21 +293,36 @@ if (configContent.BASE_MODULE && configContent.BASE_MODULE === 'liquid') {
const testnetAssetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.json';
const testnetAssetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.minimal.json';
-console.log('Downloading assets');
+console.log(`${LOG_TAG} Downloading assets`);
download(PATH + 'assets.json', assetsJsonUrl);
-console.log('Downloading assets minimal');
+console.log(`${LOG_TAG} Downloading assets minimal`);
download(PATH + 'assets.minimal.json', assetsMinimalJsonUrl);
-console.log('Downloading testnet assets');
+console.log(`${LOG_TAG} Downloading testnet assets`);
download(PATH + 'assets-testnet.json', testnetAssetsJsonUrl);
-console.log('Downloading testnet assets minimal');
+console.log(`${LOG_TAG} Downloading testnet assets minimal`);
download(PATH + 'assets-testnet.minimal.json', testnetAssetsMinimalJsonUrl);
-downloadMiningPoolLogos$()
- .then(() => downloadPromoVideoSubtiles$())
- .then(() => downloadPromoVideo$())
+(() => {
+ if (verbose) {
+ console.log(`${LOG_TAG} Downloading mining pool logos`);
+ }
+ downloadMiningPoolLogos$()
+ .then(() => {
+ if (verbose) {
+ console.log(`${LOG_TAG} Downloading promo video subtitles`);
+ }
+ downloadPromoVideoSubtiles$();
+ })
+ .then(() => {
+ if (verbose) {
+ console.log(`${LOG_TAG} Downloading promo video`);
+ }
+ downloadPromoVideo$();
+ })
.catch((error) => {
throw new Error(error);
});
+})();
\ No newline at end of file
From 372fb38722f1cc9019cf186953bddd8e0ada298a Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Sun, 24 Sep 2023 10:31:14 -0700
Subject: [PATCH 110/128] Skip syncing Liquid assets if BASE_MODULE is not set
to liquid
---
frontend/sync-assets.js | 41 ++++++++++++++++++++---------------------
1 file changed, 20 insertions(+), 21 deletions(-)
diff --git a/frontend/sync-assets.js b/frontend/sync-assets.js
index f7c8a455d..a92c3b21d 100644
--- a/frontend/sync-assets.js
+++ b/frontend/sync-assets.js
@@ -281,30 +281,29 @@ function downloadPromoVideo$() {
}
-
-let assetsJsonUrl = 'https://raw.githubusercontent.com/mempool/asset_registry_db/master/index.json';
-let assetsMinimalJsonUrl = 'https://raw.githubusercontent.com/mempool/asset_registry_db/master/index.minimal.json';
-
if (configContent.BASE_MODULE && configContent.BASE_MODULE === 'liquid') {
- assetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.json';
- assetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.minimal.json';
+ const assetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.json';
+ const assetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_db/master/index.minimal.json';
+ const testnetAssetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.json';
+ const testnetAssetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.minimal.json';
+
+ console.log(`${LOG_TAG} Downloading assets`);
+ download(PATH + 'assets.json', assetsJsonUrl);
+
+ console.log(`${LOG_TAG} Downloading assets minimal`);
+ download(PATH + 'assets.minimal.json', assetsMinimalJsonUrl);
+
+ console.log(`${LOG_TAG} Downloading testnet assets`);
+ download(PATH + 'assets-testnet.json', testnetAssetsJsonUrl);
+
+ console.log(`${LOG_TAG} Downloading testnet assets minimal`);
+ download(PATH + 'assets-testnet.minimal.json', testnetAssetsMinimalJsonUrl);
+} else {
+ if (verbose) {
+ console.log(`${LOG_TAG} BASE_MODULE is not set to Liquid (${configContent.BASE_MODULE}), skipping downloading assets`);
+ }
}
-const testnetAssetsJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.json';
-const testnetAssetsMinimalJsonUrl = 'https://raw.githubusercontent.com/Blockstream/asset_registry_testnet_db/master/index.minimal.json';
-
-console.log(`${LOG_TAG} Downloading assets`);
-download(PATH + 'assets.json', assetsJsonUrl);
-
-console.log(`${LOG_TAG} Downloading assets minimal`);
-download(PATH + 'assets.minimal.json', assetsMinimalJsonUrl);
-
-console.log(`${LOG_TAG} Downloading testnet assets`);
-download(PATH + 'assets-testnet.json', testnetAssetsJsonUrl);
-
-console.log(`${LOG_TAG} Downloading testnet assets minimal`);
-download(PATH + 'assets-testnet.minimal.json', testnetAssetsMinimalJsonUrl);
-
(() => {
if (verbose) {
console.log(`${LOG_TAG} Downloading mining pool logos`);
From 72fdcb749f7cfadd54fdb71ba19d34385d12dd31 Mon Sep 17 00:00:00 2001
From: wiz
Date: Wed, 27 Sep 2023 14:23:07 +0900
Subject: [PATCH 111/128] Bump NodeJS version to v20.7.0
---
production/install | 6 +++---
production/mempool-start-all | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/production/install b/production/install
index 9761d2b33..0e11ab31a 100755
--- a/production/install
+++ b/production/install
@@ -1046,8 +1046,8 @@ echo "[*] Installing nvm.sh from GitHub"
osSudo "${MEMPOOL_USER}" sh -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh'
echo "[*] Building NodeJS v20.5.1 via nvm.sh"
-osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v20.5.1 --shared-zlib'
-osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm alias default 20.5.1'
+osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v20.7.0 --shared-zlib'
+osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm alias default 20.7.0'
####################
# Tor installation #
@@ -1489,7 +1489,7 @@ EOF
osSudo "${UNFURL_USER}" sh -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh'
echo "[*] Building NodeJS via nvm.sh"
- osSudo "${UNFURL_USER}" zsh -c 'source ~/.zshrc ; nvm install v16.16.0 --shared-zlib'
+ osSudo "${UNFURL_USER}" zsh -c 'source ~/.zshrc ; nvm install v20.7.0 --shared-zlib'
;;
esac
diff --git a/production/mempool-start-all b/production/mempool-start-all
index 5b4f85577..0fc9b17c9 100755
--- a/production/mempool-start-all
+++ b/production/mempool-start-all
@@ -1,7 +1,7 @@
#!/usr/bin/env zsh
export NVM_DIR="$HOME/.nvm"
source "$NVM_DIR/nvm.sh"
-nvm use v20.5.1
+nvm use v20.7.0
# start all mempool backends that exist
for site in mainnet mainnet-lightning testnet testnet-lightning signet signet-lightning bisq liquid liquidtestnet;do
From 7a1cd0ff6a5ec08f910b68b40f57f5a999e29b01 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 28 Sep 2023 02:23:46 +0000
Subject: [PATCH 112/128] Bump cypress from 13.2.0 to 13.3.0 in /frontend
Bumps [cypress](https://github.com/cypress-io/cypress) from 13.2.0 to 13.3.0.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/cypress-io/cypress/compare/v13.2.0...v13.3.0)
---
updated-dependencies:
- dependency-name: cypress
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
frontend/package-lock.json | 15 ++++++++-------
frontend/package.json | 2 +-
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 36049f9f0..087c738ac 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -31,6 +31,7 @@
"bootstrap": "~4.6.2",
"browserify": "^17.0.0",
"clipboard": "^2.0.11",
+ "cypress": "^13.3.0",
"domino": "^2.1.6",
"echarts": "~5.4.3",
"echarts-gl": "^2.0.9",
@@ -59,7 +60,7 @@
"optionalDependencies": {
"@cypress/schematic": "^2.5.0",
"@types/cypress": "^1.1.3",
- "cypress": "^13.2.0",
+ "cypress": "^13.3.0",
"cypress-fail-on-console-error": "~5.0.0",
"cypress-wait-until": "^2.0.1",
"mock-socket": "~9.2.1",
@@ -7113,9 +7114,9 @@
"peer": true
},
"node_modules/cypress": {
- "version": "13.2.0",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.2.0.tgz",
- "integrity": "sha512-AvDQxBydE771GTq0TR4ZUBvv9m9ffXuB/ueEtpDF/6gOcvFR96amgwSJP16Yhqw6VhmwqspT5nAGzoxxB+D89g==",
+ "version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.3.0.tgz",
+ "integrity": "sha512-mpI8qcTwLGiA4zEQvTC/U1xGUezVV4V8HQCOYjlEOrVmU1etVvxOjkCXHGwrlYdZU/EPmUiWfsO3yt1o+Q2bgw==",
"hasInstallScript": true,
"optional": true,
"dependencies": {
@@ -22043,9 +22044,9 @@
"peer": true
},
"cypress": {
- "version": "13.2.0",
- "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.2.0.tgz",
- "integrity": "sha512-AvDQxBydE771GTq0TR4ZUBvv9m9ffXuB/ueEtpDF/6gOcvFR96amgwSJP16Yhqw6VhmwqspT5nAGzoxxB+D89g==",
+ "version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-13.3.0.tgz",
+ "integrity": "sha512-mpI8qcTwLGiA4zEQvTC/U1xGUezVV4V8HQCOYjlEOrVmU1etVvxOjkCXHGwrlYdZU/EPmUiWfsO3yt1o+Q2bgw==",
"optional": true,
"requires": {
"@cypress/request": "^3.0.0",
diff --git a/frontend/package.json b/frontend/package.json
index 214cf9ff6..294ace61d 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -111,7 +111,7 @@
"optionalDependencies": {
"@cypress/schematic": "^2.5.0",
"@types/cypress": "^1.1.3",
- "cypress": "^13.2.0",
+ "cypress": "^13.3.0",
"cypress-fail-on-console-error": "~5.0.0",
"cypress-wait-until": "^2.0.1",
"mock-socket": "~9.2.1",
From e9e2c2f7b56f08a24f84749f4671e1736757d97e Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 19:03:29 -0700
Subject: [PATCH 113/128] Remove unused files
---
GNUmakefile | 47 --------------------------------------
Makefile | 1 -
docker/electrum/Dockerfile | 32 --------------------------
3 files changed, 80 deletions(-)
delete mode 100755 GNUmakefile
delete mode 100644 Makefile
delete mode 100644 docker/electrum/Dockerfile
diff --git a/GNUmakefile b/GNUmakefile
deleted file mode 100755
index de1144025..000000000
--- a/GNUmakefile
+++ /dev/null
@@ -1,47 +0,0 @@
-# If you see pwd_unknown showing up check permissions
-PWD ?= pwd_unknown
-
-# DATABASE DEPLOY FOLDER CONFIG - default ./data
-ifeq ($(data),)
-DATA := data
-export DATA
-else
-DATA := $(data)
-export DATA
-endif
-
-.PHONY: help
-help:
- @echo ''
- @echo ''
- @echo ' Usage: make [COMMAND]'
- @echo ''
- @echo ' make all # build init mempool and electrs'
- @echo ' make init # setup some useful configs'
- @echo ' make mempool # build q dockerized mempool.space'
- @echo ' make electrs # build a docker electrs image'
- @echo ''
-
-.PHONY: init
-init:
- @echo ''
- mkdir -p $(DATA) $(DATA)/mysql $(DATA)/mysql/data
- #REF: https://github.com/mempool/mempool/blob/master/docker/README.md
- cat docker/docker-compose.yml > docker-compose.yml
- cat backend/mempool-config.sample.json > backend/mempool-config.json
-.PHONY: mempool
-mempool: init
- @echo ''
- docker-compose up --force-recreate --always-recreate-deps
- @echo ''
-.PHONY: electrs
-electrum:
- #REF: https://hub.docker.com/r/beli/electrum
- @echo ''
- docker build -f docker/electrum/Dockerfile .
- @echo ''
-.PHONY: all
-all: init
- make mempool
-#######################
--include Makefile
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 53016c66f..000000000
--- a/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-# For additional configs/scripting
diff --git a/docker/electrum/Dockerfile b/docker/electrum/Dockerfile
deleted file mode 100644
index b7af48989..000000000
--- a/docker/electrum/Dockerfile
+++ /dev/null
@@ -1,32 +0,0 @@
-FROM ubuntu:18.04
-MAINTAINER mempool.space developers
-EXPOSE 50002
-
-# runs as UID 1000 GID 1000 inside the container
-
-ENV VERSION 4.0.9
-RUN set -x \
- && apt-get update \
- && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends gpg gpg-agent dirmngr \
- && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends wget xpra python3-pyqt5 python3-wheel python3-pip python3-setuptools libsecp256k1-0 libsecp256k1-dev python3-numpy python3-dev build-essential \
- && wget -O /tmp/Electrum-${VERSION}.tar.gz https://download.electrum.org/${VERSION}/Electrum-${VERSION}.tar.gz \
- && wget -O /tmp/Electrum-${VERSION}.tar.gz.asc https://download.electrum.org/${VERSION}/Electrum-${VERSION}.tar.gz.asc \
- && gpg --keyserver keys.gnupg.net --recv-keys 6694D8DE7BE8EE5631BED9502BD5824B7F9470E6 \
- && gpg --verify /tmp/Electrum-${VERSION}.tar.gz.asc /tmp/Electrum-${VERSION}.tar.gz \
- && pip3 install /tmp/Electrum-${VERSION}.tar.gz \
- && test -f /usr/local/bin/electrum \
- && rm -vrf /tmp/Electrum-${VERSION}.tar.gz /tmp/Electrum-${VERSION}.tar.gz.asc ${HOME}/.gnupg \
- && apt-get purge --autoremove -y python3-wheel python3-pip python3-setuptools python3-dev build-essential libsecp256k1-dev curl gpg gpg-agent dirmngr \
- && apt-get clean && rm -rf /var/lib/apt/lists/* \
- && useradd -d /home/mempool -m mempool \
- && mkdir /electrum \
- && ln -s /electrum /home/mempool/.electrum \
- && chown mempool:mempool /electrum
-
-USER mempool
-ENV HOME /home/mempool
-WORKDIR /home/mempool
-VOLUME /electrum
-
-CMD ["/usr/bin/xpra", "start", ":100", "--start-child=/usr/local/bin/electrum", "--bind-tcp=0.0.0.0:50002","--daemon=yes", "--notifications=no", "--mdns=no", "--pulseaudio=no", "--html=off", "--speaker=disabled", "--microphone=disabled", "--webcam=no", "--printing=no", "--dbus-launch=", "--exit-with-children"]
-ENTRYPOINT ["electrum"]
From 097db4edcdbea36174fd1d8c9ae95dec6551fd62 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 19:03:53 -0700
Subject: [PATCH 114/128] Update backend base images
---
docker/backend/Dockerfile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docker/backend/Dockerfile b/docker/backend/Dockerfile
index bbe4df3d2..1e28e3c1a 100644
--- a/docker/backend/Dockerfile
+++ b/docker/backend/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:16.16.0-buster-slim AS builder
+FROM node:20.7.0-buster-slim AS builder
ARG commitHash
ENV MEMPOOL_COMMIT_HASH=${commitHash}
@@ -17,7 +17,7 @@ ENV PATH="/root/.cargo/bin:$PATH"
RUN npm install --omit=dev --omit=optional
RUN npm run package
-FROM node:16.16.0-buster-slim
+FROM node:20.7.0-buster-slim
WORKDIR /backend
From ad77b3a6c97716de19dd63ab8544e5dc160d6d12 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 19:04:37 -0700
Subject: [PATCH 115/128] Update the frontend base and ngnix images
---
docker/frontend/Dockerfile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docker/frontend/Dockerfile b/docker/frontend/Dockerfile
index b54612e3d..e3f2b71f7 100644
--- a/docker/frontend/Dockerfile
+++ b/docker/frontend/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:16.16.0-buster-slim AS builder
+FROM node:20.7.0-buster-slim AS builder
ARG commitHash
ENV DOCKER_COMMIT_HASH=${commitHash}
@@ -13,7 +13,7 @@ RUN npm install --omit=dev --omit=optional
RUN npm run build
-FROM nginx:1.17.8-alpine
+FROM nginx:1.24.0-alpine
WORKDIR /patch
From ea2f39b18a91871c90e47c93ea92f6e7af8341d0 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 19:04:54 -0700
Subject: [PATCH 116/128] Update mariadb base image
---
docker/docker-compose.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index 68e73a1c8..4e1094306 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -38,7 +38,7 @@ services:
MYSQL_USER: "mempool"
MYSQL_PASSWORD: "mempool"
MYSQL_ROOT_PASSWORD: "admin"
- image: mariadb:10.5.8
+ image: mariadb:10.5.21
user: "1000:1000"
restart: on-failure
stop_grace_period: 1m
From fba4759ba1d7d66e204320e10734ee8b67de333e Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 19:16:06 -0700
Subject: [PATCH 117/128] Update node base images to 20.8.0
---
docker/backend/Dockerfile | 4 ++--
docker/frontend/Dockerfile | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/docker/backend/Dockerfile b/docker/backend/Dockerfile
index 1e28e3c1a..96b1a2d5b 100644
--- a/docker/backend/Dockerfile
+++ b/docker/backend/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:20.7.0-buster-slim AS builder
+FROM node:20.8.0-buster-slim AS builder
ARG commitHash
ENV MEMPOOL_COMMIT_HASH=${commitHash}
@@ -17,7 +17,7 @@ ENV PATH="/root/.cargo/bin:$PATH"
RUN npm install --omit=dev --omit=optional
RUN npm run package
-FROM node:20.7.0-buster-slim
+FROM node:20.8.0-buster-slim
WORKDIR /backend
diff --git a/docker/frontend/Dockerfile b/docker/frontend/Dockerfile
index e3f2b71f7..4d04ae88f 100644
--- a/docker/frontend/Dockerfile
+++ b/docker/frontend/Dockerfile
@@ -1,4 +1,4 @@
-FROM node:20.7.0-buster-slim AS builder
+FROM node:20.8.0-buster-slim AS builder
ARG commitHash
ENV DOCKER_COMMIT_HASH=${commitHash}
From 3ec8a6955ca4cb430eaf62942b7a839a6d20322f Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 19:23:38 -0700
Subject: [PATCH 118/128] Update Docker GHA
---
.github/workflows/on-tag.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/on-tag.yml b/.github/workflows/on-tag.yml
index 5d8d71104..26a1b8dcd 100644
--- a/.github/workflows/on-tag.yml
+++ b/.github/workflows/on-tag.yml
@@ -68,17 +68,17 @@ jobs:
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
- name: Checkout project
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Init repo for Dockerization
run: docker/init.sh "$TAG"
- name: Set up QEMU
- uses: docker/setup-qemu-action@v2
+ uses: docker/setup-qemu-action@v3
id: qemu
- name: Setup Docker buildx action
- uses: docker/setup-buildx-action@v2
+ uses: docker/setup-buildx-action@v3
id: buildx
- name: Available platforms
From 003f3cf8b1fa545691f3da2c43e3f9d7e6c9f1f5 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 19:30:56 -0700
Subject: [PATCH 119/128] Replace armv7 with x86
---
.github/workflows/on-tag.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/on-tag.yml b/.github/workflows/on-tag.yml
index 26a1b8dcd..1e4693ee2 100644
--- a/.github/workflows/on-tag.yml
+++ b/.github/workflows/on-tag.yml
@@ -98,7 +98,7 @@ jobs:
docker buildx build \
--cache-from "type=local,src=/tmp/.buildx-cache" \
--cache-to "type=local,dest=/tmp/.buildx-cache" \
- --platform linux/amd64,linux/arm64,linux/arm/v7 \
+ --platform linux/amd64,linux/arm64,linux/x86 \
--tag ${{ secrets.DOCKER_HUB_USER }}/${{ matrix.service }}:$TAG \
--tag ${{ secrets.DOCKER_HUB_USER }}/${{ matrix.service }}:latest \
--output "type=registry" ./${{ matrix.service }}/ \
From f21a31ce86a84f1a42e9acdb927a5510bbeed51e Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 19:32:38 -0700
Subject: [PATCH 120/128] Remove x86
---
.github/workflows/on-tag.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/on-tag.yml b/.github/workflows/on-tag.yml
index 1e4693ee2..55a5585cc 100644
--- a/.github/workflows/on-tag.yml
+++ b/.github/workflows/on-tag.yml
@@ -98,7 +98,7 @@ jobs:
docker buildx build \
--cache-from "type=local,src=/tmp/.buildx-cache" \
--cache-to "type=local,dest=/tmp/.buildx-cache" \
- --platform linux/amd64,linux/arm64,linux/x86 \
+ --platform linux/amd64,linux/arm64 \
--tag ${{ secrets.DOCKER_HUB_USER }}/${{ matrix.service }}:$TAG \
--tag ${{ secrets.DOCKER_HUB_USER }}/${{ matrix.service }}:latest \
--output "type=registry" ./${{ matrix.service }}/ \
From 679e967241092fc2fabe1c1d30ef2575709b8c78 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 20:14:40 -0700
Subject: [PATCH 121/128] Add missing ACCELERATOR variable
---
docker/frontend/entrypoint.sh | 2 ++
1 file changed, 2 insertions(+)
diff --git a/docker/frontend/entrypoint.sh b/docker/frontend/entrypoint.sh
index 7d5ee313d..4e14aefac 100644
--- a/docker/frontend/entrypoint.sh
+++ b/docker/frontend/entrypoint.sh
@@ -39,6 +39,7 @@ __AUDIT__=${AUDIT:=false}
__MAINNET_BLOCK_AUDIT_START_HEIGHT__=${MAINNET_BLOCK_AUDIT_START_HEIGHT:=0}
__TESTNET_BLOCK_AUDIT_START_HEIGHT__=${TESTNET_BLOCK_AUDIT_START_HEIGHT:=0}
__SIGNET_BLOCK_AUDIT_START_HEIGHT__=${SIGNET_BLOCK_AUDIT_START_HEIGHT:=0}
+__ACCELERATOR__=${ACCELERATOR:=false}
__HISTORICAL_PRICE__=${HISTORICAL_PRICE:=true}
# Export as environment variables to be used by envsubst
@@ -65,6 +66,7 @@ export __AUDIT__
export __MAINNET_BLOCK_AUDIT_START_HEIGHT__
export __TESTNET_BLOCK_AUDIT_START_HEIGHT__
export __SIGNET_BLOCK_AUDIT_START_HEIGHT__
+export __ACCELERATOR__
export __HISTORICAL_PRICE__
folder=$(find /var/www/mempool -name "config.js" | xargs dirname)
From 7c09dd1b70cf8b777b9ea1b4f03e79398a596079 Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Fri, 29 Sep 2023 22:14:29 -0700
Subject: [PATCH 122/128] Set REDIS as disabled by default
---
docker/backend/start.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docker/backend/start.sh b/docker/backend/start.sh
index 2e293ce34..1bfb06c24 100755
--- a/docker/backend/start.sh
+++ b/docker/backend/start.sh
@@ -139,7 +139,7 @@ __MEMPOOL_SERVICES_API__=${MEMPOOL_SERVICES_API:=""}
__MEMPOOL_SERVICES_ACCELERATIONS__=${MEMPOOL_SERVICES_ACCELERATIONS:=false}
# REDIS
-__REDIS_ENABLED__=${REDIS_ENABLED:=true}
+__REDIS_ENABLED__=${REDIS_ENABLED:=false}
__REDIS_UNIX_SOCKET_PATH__=${REDIS_UNIX_SOCKET_PATH:=true}
mkdir -p "${__MEMPOOL_CACHE_DIR__}"
From 0e4e0bff78902dc8862a4b8c98d36cae1e3d792b Mon Sep 17 00:00:00 2001
From: Felipe Knorr Kuhn
Date: Sat, 30 Sep 2023 08:57:57 -0700
Subject: [PATCH 123/128] Reduce the test matrix to node v18 and v20
---
.github/workflows/ci.yml | 4 ++--
.github/workflows/cypress.yml | 2 +-
.nvmrc | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6b9b1594b..f896a0631 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,7 +9,7 @@ jobs:
if: "!contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')"
strategy:
matrix:
- node: ["16", "17", "18", "20"]
+ node: ["18", "20"]
flavor: ["dev", "prod"]
fail-fast: false
runs-on: "ubuntu-latest"
@@ -58,7 +58,7 @@ jobs:
if: "!contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')"
strategy:
matrix:
- node: ["16", "17", "18", "20"]
+ node: ["18", "20"]
flavor: ["dev", "prod"]
fail-fast: false
runs-on: "ubuntu-latest"
diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml
index d067136bf..f12aebe8b 100644
--- a/.github/workflows/cypress.yml
+++ b/.github/workflows/cypress.yml
@@ -38,7 +38,7 @@ jobs:
- name: Setup node
uses: actions/setup-node@v3
with:
- node-version: 18
+ node-version: 20
cache: "npm"
cache-dependency-path: ${{ matrix.module }}/frontend/package-lock.json
diff --git a/.nvmrc b/.nvmrc
index f274881e5..a9b234d51 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v16.16.0
+v20.8.0
From 7dad00523ff53a9ad49730c3421b880bdaecc979 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Mon, 28 Aug 2023 19:20:58 +0900
Subject: [PATCH 124/128] Implement pid file & checks
---
backend/mempool-config.sample.json | 3 ++-
backend/src/__tests__/config.test.ts | 1 +
backend/src/config.ts | 2 ++
backend/src/database.ts | 29 ++++++++++++++++++++++++++++
backend/src/index.ts | 14 ++++++++++++++
docker/backend/mempool-config.json | 3 ++-
docker/backend/start.sh | 2 ++
7 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/backend/mempool-config.sample.json b/backend/mempool-config.sample.json
index 00fe95cc5..4bbf6cfad 100644
--- a/backend/mempool-config.sample.json
+++ b/backend/mempool-config.sample.json
@@ -68,7 +68,8 @@
"DATABASE": "mempool",
"USERNAME": "mempool",
"PASSWORD": "mempool",
- "TIMEOUT": 180000
+ "TIMEOUT": 180000,
+ "PID_DIR": ""
},
"SYSLOG": {
"ENABLED": true,
diff --git a/backend/src/__tests__/config.test.ts b/backend/src/__tests__/config.test.ts
index 8097a2465..1a21cd99b 100644
--- a/backend/src/__tests__/config.test.ts
+++ b/backend/src/__tests__/config.test.ts
@@ -84,6 +84,7 @@ describe('Mempool Backend Config', () => {
USERNAME: 'mempool',
PASSWORD: 'mempool',
TIMEOUT: 180000,
+ PID_DIR: ''
});
expect(config.SYSLOG).toStrictEqual({
diff --git a/backend/src/config.ts b/backend/src/config.ts
index ed320d957..9ded762fa 100644
--- a/backend/src/config.ts
+++ b/backend/src/config.ts
@@ -93,6 +93,7 @@ interface IConfig {
USERNAME: string;
PASSWORD: string;
TIMEOUT: number;
+ PID_DIR: string;
};
SYSLOG: {
ENABLED: boolean;
@@ -219,6 +220,7 @@ const defaults: IConfig = {
'USERNAME': 'mempool',
'PASSWORD': 'mempool',
'TIMEOUT': 180000,
+ 'PID_DIR': '',
},
'SYSLOG': {
'ENABLED': true,
diff --git a/backend/src/database.ts b/backend/src/database.ts
index 6ad545fda..c27f28d23 100644
--- a/backend/src/database.ts
+++ b/backend/src/database.ts
@@ -1,3 +1,5 @@
+import * as fs from 'fs';
+import path from 'path';
import config from './config';
import { createPool, Pool, PoolConnection } from 'mysql2/promise';
import logger from './logger';
@@ -101,6 +103,33 @@ import { FieldPacket, OkPacket, PoolOptions, ResultSetHeader, RowDataPacket } fr
}
}
+ public getPidLock(): boolean {
+ const filePath = path.join(config.DATABASE.PID_DIR || __dirname, `/mempool-${config.DATABASE.DATABASE}.pid`);
+ if (fs.existsSync(filePath)) {
+ const pid = fs.readFileSync(filePath).toString();
+ if (pid !== `${process.pid}`) {
+ const msg = `Already running on PID ${pid} (or pid file '${filePath}' is stale)`;
+ logger.err(msg);
+ throw new Error(msg);
+ } else {
+ return true;
+ }
+ } else {
+ fs.writeFileSync(filePath, `${process.pid}`);
+ return true;
+ }
+ }
+
+ public releasePidLock(): void {
+ const filePath = path.join(config.DATABASE.PID_DIR || __dirname, `/mempool-${config.DATABASE.DATABASE}.pid`);
+ if (fs.existsSync(filePath)) {
+ const pid = fs.readFileSync(filePath).toString();
+ if (pid === `${process.pid}`) {
+ fs.unlinkSync(filePath);
+ }
+ }
+ }
+
private async getPool(): Promise {
if (this.pool === null) {
this.pool = createPool(this.poolConfig);
diff --git a/backend/src/index.ts b/backend/src/index.ts
index 9d0fa07f5..a8af35d1c 100644
--- a/backend/src/index.ts
+++ b/backend/src/index.ts
@@ -91,11 +91,18 @@ class Server {
async startServer(worker = false): Promise {
logger.notice(`Starting Mempool Server${worker ? ' (worker)' : ''}... (${backendInfo.getShortCommitHash()})`);
+ // Register cleanup listeners for exit events
+ ['exit', 'SIGINT', 'SIGTERM', 'SIGUSR1', 'SIGUSR2', 'uncaughtException', 'unhandledRejection'].forEach(event => {
+ process.on(event, () => { this.onExit(event); });
+ });
+
if (config.MEMPOOL.BACKEND === 'esplora') {
bitcoinApi.startHealthChecks();
}
if (config.DATABASE.ENABLED) {
+ DB.getPidLock();
+
await DB.checkDbConnection();
try {
if (process.env.npm_config_reindex_blocks === 'true') { // Re-index requests
@@ -306,6 +313,13 @@ class Server {
this.lastHeapLogTime = now;
}
}
+
+ onExit(exitEvent): void {
+ DB.releasePidLock();
+ process.exit(0);
+ }
}
+
+
((): Server => new Server())();
diff --git a/docker/backend/mempool-config.json b/docker/backend/mempool-config.json
index aa084133f..5642b36d3 100644
--- a/docker/backend/mempool-config.json
+++ b/docker/backend/mempool-config.json
@@ -69,7 +69,8 @@
"DATABASE": "__DATABASE_DATABASE__",
"USERNAME": "__DATABASE_USERNAME__",
"PASSWORD": "__DATABASE_PASSWORD__",
- "TIMEOUT": __DATABASE_TIMEOUT__
+ "TIMEOUT": __DATABASE_TIMEOUT__,
+ "PID_DIR": "__PID_DIR__",
},
"SYSLOG": {
"ENABLED": __SYSLOG_ENABLED__,
diff --git a/docker/backend/start.sh b/docker/backend/start.sh
index 1bfb06c24..938a5c26f 100755
--- a/docker/backend/start.sh
+++ b/docker/backend/start.sh
@@ -71,6 +71,7 @@ __DATABASE_DATABASE__=${DATABASE_DATABASE:=mempool}
__DATABASE_USERNAME__=${DATABASE_USERNAME:=mempool}
__DATABASE_PASSWORD__=${DATABASE_PASSWORD:=mempool}
__DATABASE_TIMEOUT__=${DATABASE_TIMEOUT:=180000}
+__DATABASE_PID_DIR__=${DATABASE_PID_DIR:=""}
# SYSLOG
__SYSLOG_ENABLED__=${SYSLOG_ENABLED:=false}
@@ -209,6 +210,7 @@ sed -i "s!__DATABASE_DATABASE__!${__DATABASE_DATABASE__}!g" mempool-config.json
sed -i "s!__DATABASE_USERNAME__!${__DATABASE_USERNAME__}!g" mempool-config.json
sed -i "s!__DATABASE_PASSWORD__!${__DATABASE_PASSWORD__}!g" mempool-config.json
sed -i "s!__DATABASE_TIMEOUT__!${__DATABASE_TIMEOUT__}!g" mempool-config.json
+sed -i "s!__DATABASE_PID_DIR__!${__DATABASE_PID_DIR__}!g" mempool-config.json
sed -i "s!__SYSLOG_ENABLED__!${__SYSLOG_ENABLED__}!g" mempool-config.json
sed -i "s!__SYSLOG_HOST__!${__SYSLOG_HOST__}!g" mempool-config.json
From 0808640ec0d346a427cf87a07a8dc8317bfff0c1 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Sun, 1 Oct 2023 16:38:45 +0100
Subject: [PATCH 125/128] Check database enabled before releasing PID lock file
---
backend/src/index.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/backend/src/index.ts b/backend/src/index.ts
index a8af35d1c..e7e1afa3d 100644
--- a/backend/src/index.ts
+++ b/backend/src/index.ts
@@ -315,7 +315,9 @@ class Server {
}
onExit(exitEvent): void {
- DB.releasePidLock();
+ if (config.DATABASE.ENABLED) {
+ DB.releasePidLock();
+ }
process.exit(0);
}
}
From 75c50416f5b0b6fd603cecbfebf6d84bfd99d0bf Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Sun, 1 Oct 2023 16:43:21 +0100
Subject: [PATCH 126/128] Fix PID docker config
---
backend/src/__fixtures__/mempool-config.template.json | 1 +
docker/backend/mempool-config.json | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/backend/src/__fixtures__/mempool-config.template.json b/backend/src/__fixtures__/mempool-config.template.json
index 1b6c8d411..652536d7a 100644
--- a/backend/src/__fixtures__/mempool-config.template.json
+++ b/backend/src/__fixtures__/mempool-config.template.json
@@ -69,6 +69,7 @@
"DATABASE": "__DATABASE_DATABASE__",
"USERNAME": "__DATABASE_USERNAME__",
"PASSWORD": "__DATABASE_PASSWORD__",
+ "PID_DIR": "__DATABASE_PID_FILE__",
"TIMEOUT": 3000
},
"SYSLOG": {
diff --git a/docker/backend/mempool-config.json b/docker/backend/mempool-config.json
index 5642b36d3..457eccd4a 100644
--- a/docker/backend/mempool-config.json
+++ b/docker/backend/mempool-config.json
@@ -70,7 +70,7 @@
"USERNAME": "__DATABASE_USERNAME__",
"PASSWORD": "__DATABASE_PASSWORD__",
"TIMEOUT": __DATABASE_TIMEOUT__,
- "PID_DIR": "__PID_DIR__",
+ "PID_DIR": "__DATABASE_PID_DIR__",
},
"SYSLOG": {
"ENABLED": __SYSLOG_ENABLED__,
From 5b357eb6b5f37c093becad29b5834b0b7da57ad4 Mon Sep 17 00:00:00 2001
From: fubz
Date: Fri, 6 Oct 2023 12:48:46 -0400
Subject: [PATCH 127/128] fix: configure crontab for electrs single script
---
contributors/fubz.txt | 3 +++
production/install | 6 +++---
2 files changed, 6 insertions(+), 3 deletions(-)
create mode 100644 contributors/fubz.txt
diff --git a/contributors/fubz.txt b/contributors/fubz.txt
new file mode 100644
index 000000000..e799d641d
--- /dev/null
+++ b/contributors/fubz.txt
@@ -0,0 +1,3 @@
+I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of January 25, 2022.
+
+Signed: fubz
diff --git a/production/install b/production/install
index 0e11ab31a..b4f6d53c5 100755
--- a/production/install
+++ b/production/install
@@ -1660,15 +1660,15 @@ case $OS in
crontab_bitcoin=()
if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then
echo "[*] Installing Electrs Mainnet Cronjob"
- crontab_bitcoin+="@reboot sleep 30 ; screen -dmS mainnet /bitcoin/electrs/electrs-start-mainnet\n"
+ crontab_bitcoin+="@reboot sleep 30 ; screen -dmS mainnet /bitcoin/electrs/start mainnet\n"
fi
if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then
echo "[*] Installing Electrs Testnet Cronjob"
- crontab_bitcoin+="@reboot sleep 70 ; screen -dmS testnet /bitcoin/electrs/electrs-start-testnet\n"
+ crontab_bitcoin+="@reboot sleep 70 ; screen -dmS testnet /bitcoin/electrs/start testnet\n"
fi
if [ "${BITCOIN_SIGNET_ENABLE}" = ON ];then
echo "[*] Installing Electrs Signet Cronjob"
- crontab_bitcoin+="@reboot sleep 90 ; screen -dmS signet /bitcoin/electrs/electrs-start-signet\n"
+ crontab_bitcoin+="@reboot sleep 90 ; screen -dmS signet /bitcoin/electrs/start signet\n"
fi
if [ "${BITCOIN_MAINNET_ENABLE}" = ON -o "${BITCOIN_TESTNET_ENABLE}" = ON -o "${BITCOIN_SIGNET_ENABLE}" = ON ];then
echo "${crontab_bitcoin}" | crontab -u "${BITCOIN_USER}" -
From 76621464f12e272edbc364ee41f2f5a97eb28caf Mon Sep 17 00:00:00 2001
From: Peter
Date: Wed, 11 Oct 2023 08:09:06 -0400
Subject: [PATCH 128/128] ma vbytes
---
.../incoming-transactions-graph.component.ts | 144 +++++++++++++-----
1 file changed, 108 insertions(+), 36 deletions(-)
diff --git a/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts b/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts
index 219811e9c..3b93cb686 100644
--- a/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts
+++ b/frontend/src/app/components/incoming-transactions-graph/incoming-transactions-graph.component.ts
@@ -37,6 +37,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On
};
windowPreference: string;
chartInstance: any = undefined;
+ MA: number[][] = [];
weightMode: boolean = false;
rateUnitSub: Subscription;
@@ -62,6 +63,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On
return;
}
this.windowPreference = this.windowPreferenceOverride ? this.windowPreferenceOverride : this.storageService.getValue('graphWindowPreference');
+ this.MA = this.calculateMA(this.data.series[0]);
this.mountChart();
}
@@ -72,7 +74,101 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On
this.isLoading = false;
}
+ /// calculate the moving average of maData
+ calculateMA(maData): number[][] {
+ //update const variables that are not changed
+ const ma: number[][] = [];
+ let sum = 0;
+ let i = 0;
+ const len = maData.length;
+
+ //Adjust window length based on the length of the data
+ //5% appeared as a good amount from tests
+ //TODO: make this a text box in the UI
+ const maWindowLen = Math.ceil(len * 0.05);
+
+ //calculate the center of the moving average window
+ const center = Math.floor(maWindowLen / 2);
+
+ //calculate the centered moving average
+ for (i = center; i < len - center; i++) {
+ sum = 0;
+ //build out ma as we loop through the data
+ ma[i] = [];
+ ma[i].push(maData[i][0]);
+ for (let j = i - center; j <= i + center; j++) {
+ sum += maData[j][1];
+ }
+
+ ma[i].push(sum / maWindowLen);
+ }
+
+ //return the moving average array
+ return ma;
+ }
+
mountChart(): void {
+ //create an array for the echart series
+ //similar to how it is done in mempool-graph.component.ts
+ const seriesGraph = [];
+ seriesGraph.push({
+ zlevel: 0,
+ name: 'data',
+ data: this.data.series[0],
+ type: 'line',
+ smooth: false,
+ showSymbol: false,
+ symbol: 'none',
+ lineStyle: {
+ width: 3,
+ },
+ markLine: {
+ silent: true,
+ symbol: 'none',
+ lineStyle: {
+ color: '#fff',
+ opacity: 1,
+ width: 2,
+ },
+ data: [{
+ yAxis: 1667,
+ label: {
+ show: false,
+ color: '#ffffff',
+ }
+ }],
+ }
+ },
+ {
+ zlevel: 0,
+ name: 'MA',
+ data: this.MA,
+ type: 'line',
+ smooth: false,
+ showSymbol: false,
+ symbol: 'none',
+ lineStyle: {
+ width: 1,
+ color: "white",
+ },
+ markLine: {
+ silent: true,
+ symbol: 'none',
+ lineStyle: {
+ color: '#fff',
+ opacity: 1,
+ width: 2,
+ },
+ data: [{
+ yAxis: 1667,
+ label: {
+ show: false,
+ color: '#ffffff',
+ }
+ }],
+ }
+ });
+
this.mempoolStatsChartOption = {
grid: {
height: this.height,
@@ -122,16 +218,20 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On
type: 'line',
},
formatter: (params: any) => {
- const axisValueLabel: string = formatterXAxis(this.locale, this.windowPreference, params[0].axisValue);
+ const axisValueLabel: string = formatterXAxis(this.locale, this.windowPreference, params[0].axisValue);
const colorSpan = (color: string) => ``;
let itemFormatted = '' + axisValueLabel + ' ';
params.map((item: any, index: number) => {
- if (index < 26) {
- itemFormatted += `
- ${colorSpan(item.color)}
-
- ${formatNumber(this.weightMode ? item.value[1] * 4 : item.value[1], this.locale, '1.0-0')} ${this.weightMode ? 'WU' : 'vB'}/s
- `;
+
+ //Do no include MA in tooltip legend!
+ if (item.seriesName !== 'MA') {
+ if (index < 26) {
+ itemFormatted += `
+ ${colorSpan(item.color)}
+
+ ${formatNumber(item.value[1], this.locale, '1.0-0')}vB/s
+ `;
+ }
}
});
return `${itemFormatted} `;
@@ -171,35 +271,7 @@ export class IncomingTransactionsGraphComponent implements OnInit, OnChanges, On
}
}
},
- series: [
- {
- zlevel: 0,
- data: this.data.series[0],
- type: 'line',
- smooth: false,
- showSymbol: false,
- symbol: 'none',
- lineStyle: {
- width: 3,
- },
- markLine: {
- silent: true,
- symbol: 'none',
- lineStyle: {
- color: '#fff',
- opacity: 1,
- width: 2,
- },
- data: [{
- yAxis: 1667,
- label: {
- show: false,
- color: '#ffffff',
- }
- }],
- }
- },
- ],
+ series: seriesGraph,
visualMap: {
show: false,
top: 50,
|