From 7007f85079e6181b56e4037bd915a6d8e33f46f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Haf?= Date: Wed, 5 Feb 2025 12:45:41 +0100 Subject: [PATCH 01/44] reworked health audit --- backend/src/api/audit.ts | 28 +++++++++++++++---- backend/src/api/common.ts | 21 +++++++++++++- backend/src/mempool.interfaces.ts | 1 + .../app/components/block/block.component.html | 2 +- 4 files changed, 45 insertions(+), 7 deletions(-) diff --git a/backend/src/api/audit.ts b/backend/src/api/audit.ts index 7b90c516ec..d65a6e5f3b 100644 --- a/backend/src/api/audit.ts +++ b/backend/src/api/audit.ts @@ -1,3 +1,4 @@ +import { couldStartTrivia } from 'typescript'; import config from '../config'; import logger from '../logger'; import { MempoolTransactionExtended, MempoolBlockWithTransactions } from '../mempool.interfaces'; @@ -28,6 +29,10 @@ class Audit { let matchedWeight = 0; let projectedWeight = 0; + let countCb = 0; + let spamWeight = 0; + let blkWeight = 0; + const inBlock = {}; const inTemplate = {}; @@ -72,6 +77,22 @@ class Audit { matchedWeight += transactions[0].weight; } + + for (const tx of transactions){ + blkWeight += tx.weight; + } + + for (const tx of transactions){ + if (countCb !== 0){ + if(tx.spam !== undefined){ + if (tx.spam == true){ + spamWeight += tx.weight; + } + } + } + countCb += 1; + } + // we can expect an honest miner to include 'displaced' transactions in place of recent arrivals and censored txs // these displaced transactions should occupy the first N weight units of the next projected block let displacedWeightRemaining = displacedWeight + 4000; @@ -169,11 +190,8 @@ class Audit { const numCensored = Object.keys(isCensored).length; const numMatches = matches.length - 1; // adjust for coinbase tx let score = 0; - if (numMatches <= 0 && numCensored <= 0) { - score = 1; - } else if (numMatches > 0) { - score = (numMatches / (numMatches + numCensored)); - } + + score = (Math.abs((spamWeight/blkWeight)-1)); const similarity = projectedWeight ? matchedWeight / projectedWeight : 1; return { diff --git a/backend/src/api/common.ts b/backend/src/api/common.ts index 8fcd2b27bb..d8f2df5673 100644 --- a/backend/src/api/common.ts +++ b/backend/src/api/common.ts @@ -607,6 +607,20 @@ export class Common { return isTaproot || !isNotTaproot; } + static isInscription2(vin, tx): void { + // in taproot, if the last witness item begins with 0x50, it's an annex + const hasAnnex = vin.witness?.[vin.witness.length - 1].startsWith('50'); + // script spends have more than one witness item, not counting the annex (if present) + if (vin.witness.length > (hasAnnex ? 2 : 1)) { + // the script itself is the second-to-last witness item, not counting the annex + const asm = vin.inner_witnessscript_asm || transactionUtils.convertScriptSigAsm(vin.witness[vin.witness.length - (hasAnnex ? 3 : 2)]); + // inscriptions smuggle data within an 'OP_0 OP_IF ... OP_ENDIF' envelope + if (asm?.includes('OP_0 OP_IF')) { + tx.spam = true; + } + } + } + static getTransactionFlags(tx: TransactionExtended, height?: number): number { let flags = tx.flags ? BigInt(tx.flags) : 0n; @@ -658,9 +672,11 @@ export class Common { flags |= TransactionFlags.p2tr; if (vin.witness?.length) { flags = Common.isInscription(vin, flags); + Common.isInscription2(vin, tx); const hasAnnex = vin.witness.length > 1 && vin.witness[vin.witness.length - 1].startsWith('50'); if (hasAnnex) { flags |= TransactionFlags.annex; + tx.spam = true; } } } break; @@ -671,6 +687,7 @@ export class Common { // try to parse the witness as a taproot inscription try { flags = Common.isInscription(vin, flags); + Common.isInscription2(vin, tx); } catch { // witness script parsing will fail if this isn't really a taproot output } @@ -721,7 +738,7 @@ export class Common { case 'v0_p2wpkh': flags |= TransactionFlags.p2wpkh; break; case 'v0_p2wsh': flags |= TransactionFlags.p2wsh; break; case 'v1_p2tr': flags |= TransactionFlags.p2tr; break; - case 'op_return': flags |= TransactionFlags.op_return; break; + case 'op_return': flags |= TransactionFlags.op_return; tx.spam = true; break; } if (vout.scriptpubkey_address) { reusedOutputAddresses[vout.scriptpubkey_address] = (reusedOutputAddresses[vout.scriptpubkey_address] || 0) + 1; @@ -735,6 +752,7 @@ export class Common { const nullBytes = (P2WSHCount * 32) - olgaSize - 2; if (vout.scriptpubkey.endsWith(''.padEnd(nullBytes * 2, '0'))) { flags |= TransactionFlags.fake_scripthash; + tx.spam = true; } } } else { @@ -744,6 +762,7 @@ export class Common { } if (hasFakePubkey) { flags |= TransactionFlags.fake_pubkey; + tx.spam = true; } // fast but bad heuristic to detect possible coinjoins diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index a0888bb506..f6ead9ea6c 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -132,6 +132,7 @@ export interface TransactionExtended extends IEsploraApi.Transaction { replacement?: boolean; uid?: number; flags?: number; + spam?: boolean; } export interface MempoolTransactionExtended extends TransactionExtended { diff --git a/frontend/src/app/components/block/block.component.html b/frontend/src/app/components/block/block.component.html index 0c78081edb..ed823ccbfd 100644 --- a/frontend/src/app/components/block/block.component.html +++ b/frontend/src/app/components/block/block.component.html @@ -63,7 +63,7 @@

- Health + Health Date: Wed, 5 Feb 2025 12:59:18 +0100 Subject: [PATCH 02/44] remove trade mark --- backend/src/api/common.ts | 28 +++++++++---------- .../app/components/about/about.component.html | 3 +- .../master-page/master-page.component.html | 10 ------- .../search-form/search-form.component.html | 2 +- .../app/dashboard/dashboard.component.html | 2 +- .../global-footer.component.html | 18 ++++-------- frontend/src/index.mempool.html | 16 +++++------ 7 files changed, 30 insertions(+), 49 deletions(-) diff --git a/backend/src/api/common.ts b/backend/src/api/common.ts index d8f2df5673..53f79157e6 100644 --- a/backend/src/api/common.ts +++ b/backend/src/api/common.ts @@ -562,6 +562,20 @@ export class Common { return flags; } + static isInscription2(vin, tx): void { + // in taproot, if the last witness item begins with 0x50, it's an annex + const hasAnnex = vin.witness?.[vin.witness.length - 1].startsWith('50'); + // script spends have more than one witness item, not counting the annex (if present) + if (vin.witness.length > (hasAnnex ? 2 : 1)) { + // the script itself is the second-to-last witness item, not counting the annex + const asm = vin.inner_witnessscript_asm || transactionUtils.convertScriptSigAsm(vin.witness[vin.witness.length - (hasAnnex ? 3 : 2)]); + // inscriptions smuggle data within an 'OP_0 OP_IF ... OP_ENDIF' envelope + if (asm?.includes('OP_0 OP_IF')) { + tx.spam = true; + } + } + } + static inputIsMaybeInscription(vin: IEsploraApi.Vin): boolean { // check if this is actually a taproot input let isTaproot = false; @@ -607,20 +621,6 @@ export class Common { return isTaproot || !isNotTaproot; } - static isInscription2(vin, tx): void { - // in taproot, if the last witness item begins with 0x50, it's an annex - const hasAnnex = vin.witness?.[vin.witness.length - 1].startsWith('50'); - // script spends have more than one witness item, not counting the annex (if present) - if (vin.witness.length > (hasAnnex ? 2 : 1)) { - // the script itself is the second-to-last witness item, not counting the annex - const asm = vin.inner_witnessscript_asm || transactionUtils.convertScriptSigAsm(vin.witness[vin.witness.length - (hasAnnex ? 3 : 2)]); - // inscriptions smuggle data within an 'OP_0 OP_IF ... OP_ENDIF' envelope - if (asm?.includes('OP_0 OP_IF')) { - tx.spam = true; - } - } - } - static getTransactionFlags(tx: TransactionExtended, height?: number): number { let flags = tx.flags ? BigInt(tx.flags) : 0n; diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html index e52cb5f63b..e76832828e 100644 --- a/frontend/src/app/components/about/about.component.html +++ b/frontend/src/app/components/about/about.component.html @@ -2,7 +2,6 @@
® -
v{{ packetJsonVersion }} [{{ frontendGitCommitHash }}] [{{ stateService.env.GIT_COMMIT_HASH_MEMPOOL_SPACE }}] @@ -12,7 +11,7 @@
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.

-
Be your own explorer
+
Explore Bitcoin
diff --git a/frontend/src/app/components/search-form/search-form.component.html b/frontend/src/app/components/search-form/search-form.component.html index 73e9d05014..963446dac8 100644 --- a/frontend/src/app/components/search-form/search-form.component.html +++ b/frontend/src/app/components/search-form/search-form.component.html @@ -1,7 +1,7 @@
- +
diff --git a/frontend/src/app/dashboard/dashboard.component.html b/frontend/src/app/dashboard/dashboard.component.html index 6b6cdf2614..79166ca5ab 100644 --- a/frontend/src/app/dashboard/dashboard.component.html +++ b/frontend/src/app/dashboard/dashboard.component.html @@ -18,7 +18,7 @@
-
Mempool Goggles™ : {{ goggleCycle[goggleIndex].name }}
+
mempool glass™ : {{ goggleCycle[goggleIndex].name }}
 
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 026c0ab47d..76a5b278f6 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 @@ -8,7 +8,6 @@ } @else { - }
@if (!enterpriseInfo?.footer_img) { @@ -17,8 +16,7 @@ Explore the full Bitcoin ecosystem ® } @else { - Be your own explorer - + Explore Bitcoin }

} @@ -61,8 +59,7 @@ Explore the full Bitcoin ecosystem ® } @else { - Be your own explorer - + Explore Bitcoin }

} @@ -86,7 +83,7 @@

What is a block explorer?

What is a mempool explorer?

Why isn't my transaction confirming?

-

Be your own explorer

+

Explore Bitcoin

More FAQs »

Research

@@ -119,13 +116,8 @@
diff --git a/frontend/src/index.mempool.html b/frontend/src/index.mempool.html index cde210665c..80e723166a 100644 --- a/frontend/src/index.mempool.html +++ b/frontend/src/index.mempool.html @@ -17,18 +17,18 @@ - - - + + + - + - - - + + + @@ -38,7 +38,7 @@ - + From 7ed770488fcfc25892edbc580324575f19455e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Haf?= Date: Wed, 5 Feb 2025 12:59:57 +0100 Subject: [PATCH 03/44] rename data to spam --- frontend/src/app/dashboard/dashboard.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/dashboard/dashboard.component.ts b/frontend/src/app/dashboard/dashboard.component.ts index 18bcf9cf0b..66ea0e8597 100644 --- a/frontend/src/app/dashboard/dashboard.component.ts +++ b/frontend/src/app/dashboard/dashboard.component.ts @@ -79,7 +79,7 @@ export class DashboardComponent implements OnInit, OnDestroy, AfterViewInit { { index: 0, name: $localize`:@@dfc3c34e182ea73c5d784ff7c8135f087992dac1:All`, mode: 'and', filters: [], gradient: 'age' }, { index: 1, name: $localize`Consolidation`, mode: 'and', filters: ['consolidation'], gradient: 'fee' }, { index: 2, name: $localize`Coinjoin`, mode: 'and', filters: ['coinjoin'], gradient: 'fee' }, - { index: 3, name: $localize`Data`, mode: 'or', filters: ['inscription', 'fake_pubkey', 'fake_scripthash', 'op_return'], gradient: 'fee' }, + { index: 3, name: $localize`Spam`, mode: 'or', filters: ['inscription', 'fake_pubkey', 'fake_scripthash', 'op_return'], gradient: 'fee' }, ]; goggleFlags = 0n; goggleMode: FilterMode = 'and'; From f596ff7eaf372bd0a76e04d3aa1e018fe3aa5621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Haf?= Date: Wed, 5 Feb 2025 13:04:45 +0100 Subject: [PATCH 04/44] remove shitcoin explorer --- .../transactions-list.component.html | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) 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 56ba6c2b15..3c56df37b7 100644 --- a/frontend/src/app/components/transactions-list/transactions-list.component.html +++ b/frontend/src/app/components/transactions-list/transactions-list.component.html @@ -357,26 +357,7 @@ OP_RETURN  - @if (vout.isRunestone) { - - } @else { - - @if ((vout.scriptpubkey_asm | hex2ascii).length > 200) { - {{ vout.scriptpubkey_asm | hex2ascii | slice:0:200 }} - - @if ((vout.scriptpubkey_asm | hex2ascii).length > 200) { - @if (!showFullOpReturnPreview[vindex]) { - Show more - } @else { - Show less - } - } - - } @else { - {{ vout.scriptpubkey_asm | hex2ascii }} - } - - } + {{ vout.scriptpubkey_asm | hex2ascii }} {{ vout.scriptpubkey_type | scriptpubkeyType }} From d27f936539a86e0829ddc447294685930a06c744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Haf?= Date: Sat, 19 Apr 2025 11:51:29 +0200 Subject: [PATCH 05/44] update docker --- docker/docker-compose.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index ea18199d89..dcbe62855a 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -5,7 +5,8 @@ services: environment: FRONTEND_HTTP_PORT: "8080" BACKEND_MAINNET_HTTP_HOST: "api" - image: mempool/frontend:latest + AUDIT: "true" + image: ghcr.io/retropex/mempoolfrontend:v3.2.0 user: "1000:1000" restart: on-failure stop_grace_period: 1m @@ -31,7 +32,10 @@ services: DATABASE_USERNAME: "mempool" DATABASE_PASSWORD: "mempool" STATISTICS_ENABLED: "true" - image: mempool/backend:latest + MEMPOOL_BLOCKS_SUMMARIES_INDEXING: "true" + MEMPOOL_GOGGLES_INDEXING: "true" + MEMPOOL_AUDIT: "true" + image: ghcr.io/retropex/mempoolbackend:v3.2.0 user: "1000:1000" restart: on-failure stop_grace_period: 1m From 11f183c44eb599433898ef98c7049c1494bdad64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Haf?= Date: Sun, 20 Apr 2025 22:44:29 +0200 Subject: [PATCH 06/44] remove doc --- .../app/components/master-page/master-page.component.html | 5 ----- 1 file changed, 5 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 1966981158..4f20483318 100644 --- a/frontend/src/app/components/master-page/master-page.component.html +++ b/frontend/src/app/components/master-page/master-page.component.html @@ -110,11 +110,6 @@
-
From 698a3b93a597851d186ad83f4aedbee85939dfde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=CC=81o=20Haf?= Date: Tue, 15 Jul 2025 18:55:30 +0200 Subject: [PATCH 07/44] remove privacy and tos --- .../components/global-footer/global-footer.component.html | 7 ------- 1 file changed, 7 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 76a5b278f6..da90c6d790 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 @@ -106,13 +106,6 @@

Calculator

-