Effective fee rate
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index e548fdc46..60051634d 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -86,6 +86,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
segwitEnabled: boolean;
rbfEnabled: boolean;
taprootEnabled: boolean;
+ hasEffectiveFeeRate: boolean;
@ViewChild('graphContainer')
graphContainer: ElementRef;
@@ -157,6 +158,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
.subscribe((cpfpInfo) => {
if (!cpfpInfo || !this.tx) {
this.cpfpInfo = null;
+ this.hasEffectiveFeeRate = false;
return;
}
// merge ancestors/descendants
@@ -164,7 +166,8 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
if (cpfpInfo.bestDescendant && !cpfpInfo.descendants?.length) {
relatives.push(cpfpInfo.bestDescendant);
}
- if (!cpfpInfo.effectiveFeePerVsize) {
+ const hasRelatives = !!relatives.length;
+ if (!cpfpInfo.effectiveFeePerVsize && hasRelatives) {
let totalWeight =
this.tx.weight +
relatives.reduce((prev, val) => prev + val.weight, 0);
@@ -177,6 +180,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
}
this.cpfpInfo = cpfpInfo;
+ this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01));
});
this.fetchRbfSubscription = this.fetchRbfHistory$
@@ -362,6 +366,8 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
ancestors: tx.ancestors,
bestDescendant: tx.bestDescendant,
};
+ const hasRelatives = !!(tx.ancestors.length || tx.bestDescendant);
+ this.hasEffectiveFeeRate = hasRelatives || (tx.effectiveFeePerVsize && (Math.abs(tx.effectiveFeePerVsize - tx.feePerVsize) > 0.01));
} else {
this.fetchCpfp$.next(this.tx.txid);
}
@@ -503,6 +509,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.replaced = false;
this.transactionTime = -1;
this.cpfpInfo = null;
+ this.hasEffectiveFeeRate = false;
this.rbfInfo = null;
this.rbfReplaces = [];
this.showCpfpDetails = false;
From c558c85f36bb70eb3fc422e12e2b36060a08ea79 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Wed, 31 May 2023 09:48:44 -0700
Subject: [PATCH 13/24] fix possible backend crash
---
backend/src/repositories/BlocksRepository.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/backend/src/repositories/BlocksRepository.ts b/backend/src/repositories/BlocksRepository.ts
index a014e317e..5848fe331 100644
--- a/backend/src/repositories/BlocksRepository.ts
+++ b/backend/src/repositories/BlocksRepository.ts
@@ -928,7 +928,7 @@ class BlocksRepository {
return blocks;
} catch (e) {
logger.err(`Cannot get blocks with missing coinstatsindex. Reason: ` + (e instanceof Error ? e.message : e));
- throw e;
+ return [];
}
}
From 0b74cf1d8941ceb340ad20cb013dbea579b7c2bf Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Wed, 31 May 2023 09:58:29 -0700
Subject: [PATCH 14/24] fix possible backend crash x2, remove dead code,
improve log
---
backend/src/api/mining/mining.ts | 10 ++++++++--
backend/src/repositories/BlocksRepository.ts | 18 ++----------------
2 files changed, 10 insertions(+), 18 deletions(-)
diff --git a/backend/src/api/mining/mining.ts b/backend/src/api/mining/mining.ts
index 20da92de3..39a4423f2 100644
--- a/backend/src/api/mining/mining.ts
+++ b/backend/src/api/mining/mining.ts
@@ -472,11 +472,11 @@ class Mining {
}
this.blocksPriceIndexingRunning = true;
+ let totalInserted = 0;
try {
const prices: any[] = await PricesRepository.$getPricesTimesAndId();
const blocksWithoutPrices: any[] = await BlocksRepository.$getBlocksWithoutPrice();
- let totalInserted = 0;
const blocksPrices: BlockPrice[] = [];
for (const block of blocksWithoutPrices) {
@@ -521,7 +521,13 @@ class Mining {
}
} catch (e) {
this.blocksPriceIndexingRunning = false;
- throw e;
+ logger.err(`Cannot index block prices. ${e}`);
+ }
+
+ if (totalInserted > 0) {
+ logger.info(`Indexing blocks prices completed. Indexed ${totalInserted}`, logger.tags.mining);
+ } else {
+ logger.debug(`Indexing blocks prices completed. Indexed 0.`, logger.tags.mining);
}
this.blocksPriceIndexingRunning = false;
diff --git a/backend/src/repositories/BlocksRepository.ts b/backend/src/repositories/BlocksRepository.ts
index 5848fe331..90cebf7e9 100644
--- a/backend/src/repositories/BlocksRepository.ts
+++ b/backend/src/repositories/BlocksRepository.ts
@@ -577,19 +577,6 @@ class BlocksRepository {
}
}
- /**
- * Return blocks height
- */
- public async $getBlocksHeightsAndTimestamp(): Promise
{
- try {
- const [rows]: any[] = await DB.query(`SELECT height, blockTimestamp as timestamp FROM blocks`);
- return rows;
- } catch (e) {
- logger.err('Cannot get blocks height and timestamp from the db. Reason: ' + (e instanceof Error ? e.message : e));
- throw e;
- }
- }
-
/**
* Get general block stats
*/
@@ -877,7 +864,7 @@ class BlocksRepository {
/**
* Get all blocks which have not be linked to a price yet
*/
- public async $getBlocksWithoutPrice(): Promise {
+ public async $getBlocksWithoutPrice(): Promise {
try {
const [rows]: any[] = await DB.query(`
SELECT UNIX_TIMESTAMP(blocks.blockTimestamp) as timestamp, blocks.height
@@ -889,7 +876,7 @@ class BlocksRepository {
return rows;
} catch (e) {
logger.err('Cannot get blocks height and timestamp from the db. Reason: ' + (e instanceof Error ? e.message : e));
- throw e;
+ return [];
}
}
@@ -909,7 +896,6 @@ class BlocksRepository {
logger.debug(`Cannot save blocks prices for blocks [${blockPrices[0].height} to ${blockPrices[blockPrices.length - 1].height}] because it has already been indexed, ignoring`);
} else {
logger.err(`Cannot save blocks prices for blocks [${blockPrices[0].height} to ${blockPrices[blockPrices.length - 1].height}] into db. Reason: ` + (e instanceof Error ? e.message : e));
- throw e;
}
}
}
From b171ed6dd00a859506eee677cc4654c134a09709 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Thu, 25 May 2023 17:39:45 -0400
Subject: [PATCH 15/24] Break block templates into their own db table
---
backend/src/api/database-migration.ts | 14 +++++++++++++-
backend/src/repositories/BlocksAuditsRepository.ts | 1 +
.../src/repositories/BlocksSummariesRepository.ts | 6 +++---
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts
index 21c87f9e2..e777d8adb 100644
--- a/backend/src/api/database-migration.ts
+++ b/backend/src/api/database-migration.ts
@@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository';
import { RowDataPacket } from 'mysql2';
class DatabaseMigration {
- private static currentVersion = 60;
+ private static currentVersion = 61;
private queryTimeout = 3600_000;
private statisticsAddedIndexed = false;
private uniqueLogs: string[] = [];
@@ -521,6 +521,18 @@ class DatabaseMigration {
await this.$executeQuery('ALTER TABLE `blocks_audits` ADD sigop_txs JSON DEFAULT "[]"');
await this.updateToSchemaVersion(60);
}
+
+ if (databaseSchemaVersion < 61 && isBitcoin === true) {
+ // Break block templates into their own table
+ if (! await this.$checkIfTableExists('blocks_templates')) {
+ await this.$executeQuery('CREATE TABLE blocks_templates AS SELECT id, template FROM blocks_summaries WHERE template != "[]"');
+ }
+ await this.$executeQuery('ALTER TABLE blocks_templates MODIFY template JSON DEFAULT "[]"');
+ await this.$executeQuery('ALTER TABLE blocks_templates ADD PRIMARY KEY (id)');
+ await this.$executeQuery('ALTER TABLE blocks_summaries DROP COLUMN template');
+ await this.updateToSchemaVersion(61);
+ }
+
}
/**
diff --git a/backend/src/repositories/BlocksAuditsRepository.ts b/backend/src/repositories/BlocksAuditsRepository.ts
index 33075f43c..656340743 100644
--- a/backend/src/repositories/BlocksAuditsRepository.ts
+++ b/backend/src/repositories/BlocksAuditsRepository.ts
@@ -55,6 +55,7 @@ class BlocksAuditRepositories {
transactions, template, missing_txs as missingTxs, added_txs as addedTxs, fresh_txs as freshTxs, sigop_txs as sigopTxs, match_rate as matchRate
FROM blocks_audits
JOIN blocks ON blocks.hash = blocks_audits.hash
+ JOIN blocks_templates ON blocks_templates.id = blocks_audits.hash
JOIN blocks_summaries ON blocks_summaries.id = blocks_audits.hash
WHERE blocks_audits.hash = "${hash}"
`);
diff --git a/backend/src/repositories/BlocksSummariesRepository.ts b/backend/src/repositories/BlocksSummariesRepository.ts
index f2560fbe7..87d2617e6 100644
--- a/backend/src/repositories/BlocksSummariesRepository.ts
+++ b/backend/src/repositories/BlocksSummariesRepository.ts
@@ -36,11 +36,11 @@ class BlocksSummariesRepository {
try {
const transactions = JSON.stringify(params.template?.transactions || []);
await DB.query(`
- INSERT INTO blocks_summaries (height, id, transactions, template)
- VALUE (?, ?, ?, ?)
+ INSERT INTO blocks_templates (id, template)
+ VALUE (?, ?)
ON DUPLICATE KEY UPDATE
template = ?
- `, [params.height, blockId, '[]', transactions, transactions]);
+ `, [blockId, transactions, transactions]);
} catch (e: any) {
if (e.errno === 1062) { // ER_DUP_ENTRY - This scenario is possible upon node backend restart
logger.debug(`Cannot save block template for ${blockId} because it has already been indexed, ignoring`);
From c49626aefce41849f4ea65537b583d0a4fbd6c58 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Tue, 30 May 2023 16:36:49 -0400
Subject: [PATCH 16/24] Confirmation badge component, fix negative
confirmations
---
backend/src/api/websocket-handler.ts | 4 +--
.../bisq-transaction.component.html | 8 +++---
.../bisq-transfers.component.html | 6 +----
.../transaction/transaction.component.html | 14 +----------
.../transaction/transaction.component.ts | 2 +-
.../transactions-list.component.html | 9 +------
.../src/app/interfaces/websocket.interface.ts | 2 +-
frontend/src/app/services/state.service.ts | 2 +-
.../src/app/services/websocket.service.ts | 2 +-
.../confirmations.component.html | 13 ++++++++++
.../confirmations.component.scss | 0
.../confirmations/confirmations.component.ts | 25 +++++++++++++++++++
frontend/src/app/shared/shared.module.ts | 3 +++
13 files changed, 53 insertions(+), 37 deletions(-)
create mode 100644 frontend/src/app/shared/components/confirmations/confirmations.component.html
create mode 100644 frontend/src/app/shared/components/confirmations/confirmations.component.scss
create mode 100644 frontend/src/app/shared/components/confirmations/confirmations.component.ts
diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts
index 89b819b08..557d751e4 100644
--- a/backend/src/api/websocket-handler.ts
+++ b/backend/src/api/websocket-handler.ts
@@ -657,8 +657,8 @@ class WebsocketHandler {
if (client['track-tx']) {
const trackTxid = client['track-tx'];
- if (txIds.indexOf(trackTxid) > -1) {
- response['txConfirmed'] = 'true';
+ if (trackTxid && txIds.indexOf(trackTxid) > -1) {
+ response['txConfirmed'] = JSON.stringify(trackTxid);
} else {
const mempoolTx = _memPool[trackTxid];
if (mempoolTx && mempoolTx.position) {
diff --git a/frontend/src/app/bisq/bisq-transaction/bisq-transaction.component.html b/frontend/src/app/bisq/bisq-transaction/bisq-transaction.component.html
index 3a23688e6..44f7b840e 100644
--- a/frontend/src/app/bisq/bisq-transaction/bisq-transaction.component.html
+++ b/frontend/src/app/bisq/bisq-transaction/bisq-transaction.component.html
@@ -15,11 +15,9 @@
diff --git a/frontend/src/app/bisq/bisq-transfers/bisq-transfers.component.html b/frontend/src/app/bisq/bisq-transfers/bisq-transfers.component.html
index 0388ea418..dc4993e90 100644
--- a/frontend/src/app/bisq/bisq-transfers/bisq-transfers.component.html
+++ b/frontend/src/app/bisq/bisq-transfers/bisq-transfers.component.html
@@ -70,11 +70,7 @@
-
-
- {{ i }} confirmation
- {{ i }} confirmations
-
+
diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html
index 4e301790b..64eeeaecd 100644
--- a/frontend/src/app/components/transaction/transaction.component.html
+++ b/frontend/src/app/components/transaction/transaction.component.html
@@ -18,19 +18,7 @@
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index 60051634d..dd32b05e8 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -391,7 +391,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.blocksSubscription = this.stateService.blocks$.subscribe(([block, txConfirmed]) => {
this.latestBlock = block;
- if (txConfirmed && this.tx && !this.tx.status.confirmed) {
+ if (txConfirmed && this.tx && !this.tx.status.confirmed && txConfirmed === this.tx.txid) {
this.tx.status = {
confirmed: true,
block_height: block.height,
diff --git a/frontend/src/app/components/transactions-list/transactions-list.component.html b/frontend/src/app/components/transactions-list/transactions-list.component.html
index 0d195f2ff..c509a799d 100644
--- a/frontend/src/app/components/transactions-list/transactions-list.component.html
+++ b/frontend/src/app/components/transactions-list/transactions-list.component.html
@@ -298,14 +298,7 @@
-
-
- {{ i }} confirmation
- {{ i }} confirmations
-
-
- Unconfirmed
-
+
Confidential
diff --git a/frontend/src/app/interfaces/websocket.interface.ts b/frontend/src/app/interfaces/websocket.interface.ts
index eaf937a5f..20d1cbeed 100644
--- a/frontend/src/app/interfaces/websocket.interface.ts
+++ b/frontend/src/app/interfaces/websocket.interface.ts
@@ -6,7 +6,7 @@ export interface WebsocketResponse {
block?: BlockExtended;
blocks?: BlockExtended[];
conversions?: any;
- txConfirmed?: boolean;
+ txConfirmed?: string | boolean;
historicalDate?: string;
mempoolInfo?: MempoolInfo;
vBytesPerSecond?: number;
diff --git a/frontend/src/app/services/state.service.ts b/frontend/src/app/services/state.service.ts
index 1997a1d53..d6e39ddc9 100644
--- a/frontend/src/app/services/state.service.ts
+++ b/frontend/src/app/services/state.service.ts
@@ -92,7 +92,7 @@ export class StateService {
networkChanged$ = new ReplaySubject(1);
lightningChanged$ = new ReplaySubject(1);
- blocks$: ReplaySubject<[BlockExtended, boolean]>;
+ blocks$: ReplaySubject<[BlockExtended, string | boolean]>;
transactions$ = new ReplaySubject(6);
conversions$ = new ReplaySubject(1);
bsqPrice$ = new ReplaySubject(1);
diff --git a/frontend/src/app/services/websocket.service.ts b/frontend/src/app/services/websocket.service.ts
index c5da17cef..7a84aadd7 100644
--- a/frontend/src/app/services/websocket.service.ts
+++ b/frontend/src/app/services/websocket.service.ts
@@ -258,7 +258,7 @@ export class WebsocketService {
if (response.block) {
if (response.block.height > this.stateService.latestBlockHeight) {
this.stateService.updateChainTip(response.block.height);
- this.stateService.blocks$.next([response.block, !!response.txConfirmed]);
+ this.stateService.blocks$.next([response.block, response.txConfirmed]);
}
if (response.txConfirmed) {
diff --git a/frontend/src/app/shared/components/confirmations/confirmations.component.html b/frontend/src/app/shared/components/confirmations/confirmations.component.html
new file mode 100644
index 000000000..1d7138c7c
--- /dev/null
+++ b/frontend/src/app/shared/components/confirmations/confirmations.component.html
@@ -0,0 +1,13 @@
+
+
+
+ {{ i }} confirmation
+ {{ i }} confirmations
+
+
+
+ Replaced
+
+
+ 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
new file mode 100644
index 000000000..e69de29bb
diff --git a/frontend/src/app/shared/components/confirmations/confirmations.component.ts b/frontend/src/app/shared/components/confirmations/confirmations.component.ts
new file mode 100644
index 000000000..dc66673ed
--- /dev/null
+++ b/frontend/src/app/shared/components/confirmations/confirmations.component.ts
@@ -0,0 +1,25 @@
+import { Component, Input, OnChanges } from '@angular/core';
+
+
+@Component({
+ selector: 'app-confirmations',
+ templateUrl: './confirmations.component.html',
+ styleUrls: ['./confirmations.component.scss'],
+})
+export class ConfirmationsComponent implements OnChanges {
+ @Input() chainTip: number;
+ @Input() height: number;
+ @Input() replaced: boolean = false;
+ @Input() hideUnconfirmed: boolean = false;
+ @Input() buttonClass: string = '';
+
+ confirmations: number = 0;
+
+ ngOnChanges(): void {
+ if (this.chainTip != null && this.height != null) {
+ this.confirmations = Math.max(1, this.chainTip - this.height + 1);
+ } else {
+ this.confirmations = 0;
+ }
+ }
+}
diff --git a/frontend/src/app/shared/shared.module.ts b/frontend/src/app/shared/shared.module.ts
index 6e8d8d0f2..d24f5356e 100644
--- a/frontend/src/app/shared/shared.module.ts
+++ b/frontend/src/app/shared/shared.module.ts
@@ -85,6 +85,7 @@ import { SatsComponent } from './components/sats/sats.component';
import { TruncateComponent } from './components/truncate/truncate.component';
import { SearchResultsComponent } from '../components/search-form/search-results/search-results.component';
import { TimestampComponent } from './components/timestamp/timestamp.component';
+import { ConfirmationsComponent } from './components/confirmations/confirmations.component';
import { ToggleComponent } from './components/toggle/toggle.component';
import { GeolocationComponent } from '../shared/components/geolocation/geolocation.component';
import { TestnetAlertComponent } from './components/testnet-alert/testnet-alert.component';
@@ -175,6 +176,7 @@ import { ClockMempoolComponent } from '../components/clock/clock-mempool.compone
TruncateComponent,
SearchResultsComponent,
TimestampComponent,
+ ConfirmationsComponent,
ToggleComponent,
GeolocationComponent,
TestnetAlertComponent,
@@ -289,6 +291,7 @@ import { ClockMempoolComponent } from '../components/clock/clock-mempool.compone
TruncateComponent,
SearchResultsComponent,
TimestampComponent,
+ ConfirmationsComponent,
ToggleComponent,
GeolocationComponent,
PreviewTitleComponent,
From 9d4b58604b43706bcf5a369ec1231ad7a95af724 Mon Sep 17 00:00:00 2001
From: softsimon
Date: Sun, 4 Jun 2023 10:32:24 +0400
Subject: [PATCH 17/24] Optimize change detection
---
.../shared/components/confirmations/confirmations.component.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/frontend/src/app/shared/components/confirmations/confirmations.component.ts b/frontend/src/app/shared/components/confirmations/confirmations.component.ts
index dc66673ed..8d14128e5 100644
--- a/frontend/src/app/shared/components/confirmations/confirmations.component.ts
+++ b/frontend/src/app/shared/components/confirmations/confirmations.component.ts
@@ -1,10 +1,11 @@
-import { Component, Input, OnChanges } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core';
@Component({
selector: 'app-confirmations',
templateUrl: './confirmations.component.html',
styleUrls: ['./confirmations.component.scss'],
+ changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ConfirmationsComponent implements OnChanges {
@Input() chainTip: number;
From 8b1dff6d15697d21b3853c3c3c3793a73d9127b7 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Sun, 4 Jun 2023 11:44:40 -0400
Subject: [PATCH 18/24] fix txConfirmed type
---
frontend/src/app/interfaces/websocket.interface.ts | 2 +-
frontend/src/app/services/state.service.ts | 4 ++--
frontend/src/app/services/websocket.service.ts | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/frontend/src/app/interfaces/websocket.interface.ts b/frontend/src/app/interfaces/websocket.interface.ts
index 20d1cbeed..83a0c636e 100644
--- a/frontend/src/app/interfaces/websocket.interface.ts
+++ b/frontend/src/app/interfaces/websocket.interface.ts
@@ -6,7 +6,7 @@ export interface WebsocketResponse {
block?: BlockExtended;
blocks?: BlockExtended[];
conversions?: any;
- txConfirmed?: string | boolean;
+ txConfirmed?: string;
historicalDate?: string;
mempoolInfo?: MempoolInfo;
vBytesPerSecond?: number;
diff --git a/frontend/src/app/services/state.service.ts b/frontend/src/app/services/state.service.ts
index d6e39ddc9..55f349cc1 100644
--- a/frontend/src/app/services/state.service.ts
+++ b/frontend/src/app/services/state.service.ts
@@ -92,7 +92,7 @@ export class StateService {
networkChanged$ = new ReplaySubject(1);
lightningChanged$ = new ReplaySubject(1);
- blocks$: ReplaySubject<[BlockExtended, string | boolean]>;
+ blocks$: ReplaySubject<[BlockExtended, string]>;
transactions$ = new ReplaySubject(6);
conversions$ = new ReplaySubject(1);
bsqPrice$ = new ReplaySubject(1);
@@ -163,7 +163,7 @@ export class StateService {
}
});
- this.blocks$ = new ReplaySubject<[BlockExtended, boolean]>(this.env.KEEP_BLOCKS_AMOUNT);
+ this.blocks$ = new ReplaySubject<[BlockExtended, string]>(this.env.KEEP_BLOCKS_AMOUNT);
if (this.env.BASE_MODULE === 'bisq') {
this.network = this.env.BASE_MODULE;
diff --git a/frontend/src/app/services/websocket.service.ts b/frontend/src/app/services/websocket.service.ts
index 7a84aadd7..af7a465f8 100644
--- a/frontend/src/app/services/websocket.service.ts
+++ b/frontend/src/app/services/websocket.service.ts
@@ -241,7 +241,7 @@ export class WebsocketService {
blocks.forEach((block: BlockExtended) => {
if (block.height > this.stateService.latestBlockHeight) {
maxHeight = Math.max(maxHeight, block.height);
- this.stateService.blocks$.next([block, false]);
+ this.stateService.blocks$.next([block, '']);
}
});
this.stateService.updateChainTip(maxHeight);
@@ -258,7 +258,7 @@ export class WebsocketService {
if (response.block) {
if (response.block.height > this.stateService.latestBlockHeight) {
this.stateService.updateChainTip(response.block.height);
- this.stateService.blocks$.next([response.block, response.txConfirmed]);
+ this.stateService.blocks$.next([response.block, response.txConfirmed || '']);
}
if (response.txConfirmed) {
From 37dd95a4a01094e0947261cc55026d81147563f5 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Sun, 4 Jun 2023 12:36:27 -0400
Subject: [PATCH 19/24] fix firstSeen reset bug
---
backend/src/api/transaction-utils.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/backend/src/api/transaction-utils.ts b/backend/src/api/transaction-utils.ts
index 2d1f0f955..8523a938e 100644
--- a/backend/src/api/transaction-utils.ts
+++ b/backend/src/api/transaction-utils.ts
@@ -59,8 +59,8 @@ class TransactionUtils {
feePerVsize: feePerVbytes,
effectiveFeePerVsize: feePerVbytes,
}, transaction);
- if (!transaction?.status?.confirmed) {
- transactionExtended.firstSeen = Math.round((new Date().getTime() / 1000));
+ if (!transaction?.status?.confirmed && !transactionExtended.firstSeen) {
+ transactionExtended.firstSeen = Math.round((Date.now() / 1000));
}
return transactionExtended;
}
@@ -83,8 +83,8 @@ class TransactionUtils {
adjustedFeePerVsize: adjustedFeePerVsize,
effectiveFeePerVsize: adjustedFeePerVsize,
});
- if (!transaction?.status?.confirmed) {
- transactionExtended.firstSeen = Math.round((new Date().getTime() / 1000));
+ if (!transactionExtended?.status?.confirmed && !transactionExtended.firstSeen) {
+ transactionExtended.firstSeen = Math.round((Date.now() / 1000));
}
return transactionExtended;
}
From 9e1de656c1d05a288a0d66a43f491b107ae63fdf Mon Sep 17 00:00:00 2001
From: junderw
Date: Mon, 5 Jun 2023 07:21:55 -0700
Subject: [PATCH 20/24] Fix: Annex parsing for p2tr on bitcoind/romanz backends
---
backend/src/api/bitcoin/bitcoin-api.ts | 32 +++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/backend/src/api/bitcoin/bitcoin-api.ts b/backend/src/api/bitcoin/bitcoin-api.ts
index e20fe9e34..307736737 100644
--- a/backend/src/api/bitcoin/bitcoin-api.ts
+++ b/backend/src/api/bitcoin/bitcoin-api.ts
@@ -415,12 +415,38 @@ class BitcoinApi implements AbstractBitcoinApi {
vin.inner_witnessscript_asm = this.convertScriptSigAsm(witnessScript);
}
- if (vin.prevout.scriptpubkey_type === 'v1_p2tr' && vin.witness && vin.witness.length > 1) {
- const witnessScript = vin.witness[vin.witness.length - 2];
- vin.inner_witnessscript_asm = this.convertScriptSigAsm(witnessScript);
+ if (vin.prevout.scriptpubkey_type === 'v1_p2tr' && vin.witness) {
+ const witnessScript = this.witnessToP2TRScript(vin.witness);
+ if (witnessScript !== null) {
+ vin.inner_witnessscript_asm = this.convertScriptSigAsm(witnessScript);
+ }
}
}
+ /**
+ * This function must only be called when we know the witness we are parsing
+ * is a taproot witness.
+ * @param witness An array of hex strings that represents the witness stack of
+ * the input.
+ * @returns null if the witness is not a script spend, and the hex string of
+ * the script item if it is a script spend.
+ */
+ private witnessToP2TRScript(witness: string[]): string | null {
+ if (witness.length < 2) return null;
+ // Note: see BIP341 for parsing details of witness stack
+
+ // If there are at least two witness elements, and the first byte of the
+ // last element is 0x50, this last element is called annex a and
+ // is removed from the witness stack.
+ const hasAnnex = witness[witness.length - 1].substring(0, 2) === '50';
+ // If there are at least two witness elements left, script path spending is used.
+ // Call the second-to-last stack element s, the script.
+ // (Note: this phrasing from BIP341 assumes we've *removed* the annex from the stack)
+ if (hasAnnex && witness.length < 3) return null;
+ const positionOfScript = hasAnnex ? witness.length - 3 : witness.length - 2;
+ return witness[positionOfScript];
+ }
+
}
export default BitcoinApi;
From 689319437a24c1499b389b07321497d176c3c805 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Mon, 5 Jun 2023 14:23:37 -0400
Subject: [PATCH 21/24] fix graph filter dropdown colors
---
frontend/src/app/components/statistics/statistics.component.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/src/app/components/statistics/statistics.component.ts b/frontend/src/app/components/statistics/statistics.component.ts
index 5e638af31..35137bff1 100644
--- a/frontend/src/app/components/statistics/statistics.component.ts
+++ b/frontend/src/app/components/statistics/statistics.component.ts
@@ -196,7 +196,7 @@ export class StatisticsComponent implements OnInit {
this.feeLevelDropdownData.push({
fee: fee,
range,
- color: _chartColors[i - 1],
+ color: _chartColors[i],
});
}
});
From 386037d1db872fecca10b00ed46ea4c29fbc3094 Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Fri, 26 May 2023 19:12:12 -0400
Subject: [PATCH 22/24] Fix missing fees in $updateBlocks without esplora
---
backend/src/api/blocks.ts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts
index fc12b5998..9e56db027 100644
--- a/backend/src/api/blocks.ts
+++ b/backend/src/api/blocks.ts
@@ -600,6 +600,14 @@ class Blocks {
const block = BitcoinApi.convertBlock(verboseBlock);
const txIds: string[] = await bitcoinApi.$getTxIdsForBlock(blockHash);
const transactions = await this.$getTransactionsExtended(blockHash, block.height, false, false, true);
+ if (config.MEMPOOL.BACKEND !== 'esplora') {
+ // fill in missing transaction fee data from verboseBlock
+ for (let i = 0; i < transactions.length; i++) {
+ if (!transactions[i].fee && transactions[i].txid === verboseBlock.tx[i].txid) {
+ transactions[i].fee = verboseBlock.tx[i].fee * 100_000_000;
+ }
+ }
+ }
const cpfpSummary: CpfpSummary = Common.calculateCpfp(block.height, transactions);
const blockExtended: BlockExtended = await this.$getBlockExtended(block, cpfpSummary.transactions);
const blockSummary: BlockSummary = this.summarizeBlock(verboseBlock);
From fd30bff9c6e4f6b707d58e5dcea5039de8ed3126 Mon Sep 17 00:00:00 2001
From: nymkappa <1612910616@pm.me>
Date: Wed, 7 Jun 2023 18:04:21 +0200
Subject: [PATCH 23/24] don't throw when BlocksAuditRepositories.$saveAudit
fails
---
backend/src/repositories/BlocksAuditsRepository.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/backend/src/repositories/BlocksAuditsRepository.ts b/backend/src/repositories/BlocksAuditsRepository.ts
index c6156334b..1149b8a93 100644
--- a/backend/src/repositories/BlocksAuditsRepository.ts
+++ b/backend/src/repositories/BlocksAuditsRepository.ts
@@ -14,7 +14,6 @@ class BlocksAuditRepositories {
logger.debug(`Cannot save block audit for block ${audit.hash} because it has already been indexed, ignoring`);
} else {
logger.err(`Cannot save block audit into db. Reason: ` + (e instanceof Error ? e.message : e));
- throw e;
}
}
}
From 57ac1486a009ef2bc599aa7ae57688d6752523bb Mon Sep 17 00:00:00 2001
From: Mononaut
Date: Fri, 9 Jun 2023 19:03:47 -0400
Subject: [PATCH 24/24] Reset blockchain scroll on logo click
---
.../app/components/master-page/master-page.component.html | 2 +-
.../app/components/master-page/master-page.component.ts | 4 ++++
frontend/src/app/components/start/start.component.ts | 8 ++++++++
frontend/src/app/services/state.service.ts | 1 +
4 files changed, 14 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 9e4cd1513..48028ab47 100644
--- a/frontend/src/app/components/master-page/master-page.component.html
+++ b/frontend/src/app/components/master-page/master-page.component.html
@@ -1,7 +1,7 @@
-
+
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 7ae5019e0..4ec60c920 100644
--- a/frontend/src/app/components/master-page/master-page.component.ts
+++ b/frontend/src/app/components/master-page/master-page.component.ts
@@ -53,4 +53,8 @@ export class MasterPageComponent implements OnInit {
onResize(): void {
this.isMobile = window.innerWidth <= 767.98;
}
+
+ brandClick(e): void {
+ this.stateService.resetScroll$.next(true);
+ }
}
diff --git a/frontend/src/app/components/start/start.component.ts b/frontend/src/app/components/start/start.component.ts
index 7e83fb516..1e028d27a 100644
--- a/frontend/src/app/components/start/start.component.ts
+++ b/frontend/src/app/components/start/start.component.ts
@@ -25,6 +25,7 @@ export class StartComponent implements OnInit, OnDestroy {
markBlockSubscription: Subscription;
blockCounterSubscription: Subscription;
@ViewChild('blockchainContainer') blockchainContainer: ElementRef;
+ resetScrollSubscription: Subscription;
isMobile: boolean = false;
isiOS: boolean = false;
@@ -106,6 +107,12 @@ export class StartComponent implements OnInit, OnDestroy {
}, 60 * 60 * 1000);
}
});
+ this.resetScrollSubscription = this.stateService.resetScroll$.subscribe(reset => {
+ if (reset) {
+ this.resetScroll();
+ this.stateService.resetScroll$.next(false);
+ }
+ });
}
@HostListener('window:resize', ['$event'])
@@ -385,5 +392,6 @@ export class StartComponent implements OnInit, OnDestroy {
this.chainTipSubscription.unsubscribe();
this.markBlockSubscription.unsubscribe();
this.blockCounterSubscription.unsubscribe();
+ this.resetScrollSubscription.unsubscribe();
}
}
diff --git a/frontend/src/app/services/state.service.ts b/frontend/src/app/services/state.service.ts
index 55f349cc1..31f5f3aab 100644
--- a/frontend/src/app/services/state.service.ts
+++ b/frontend/src/app/services/state.service.ts
@@ -126,6 +126,7 @@ export class StateService {
keyNavigation$ = new Subject
();
blockScrolling$: Subject = new Subject();
+ resetScroll$: Subject = new Subject();
timeLtr: BehaviorSubject;
hideFlow: BehaviorSubject;
hideAudit: BehaviorSubject;