diff --git a/backend/mempool-config.sample.json b/backend/mempool-config.sample.json index 1f64214ce..f8417f0e7 100644 --- a/backend/mempool-config.sample.json +++ b/backend/mempool-config.sample.json @@ -25,6 +25,7 @@ "AUTOMATIC_BLOCK_REINDEXING": false, "POOLS_JSON_URL": "https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json", "POOLS_JSON_TREE_URL": "https://api.github.com/repos/mempool/mining-pools/git/trees/master", + "AUDIT": false, "ADVANCED_GBT_AUDIT": false, "ADVANCED_GBT_MEMPOOL": false, "CPFP_INDEXING": false diff --git a/backend/src/__fixtures__/mempool-config.template.json b/backend/src/__fixtures__/mempool-config.template.json index e699c9458..f15d9c328 100644 --- a/backend/src/__fixtures__/mempool-config.template.json +++ b/backend/src/__fixtures__/mempool-config.template.json @@ -26,6 +26,7 @@ "INDEXING_BLOCKS_AMOUNT": 14, "POOLS_JSON_TREE_URL": "__POOLS_JSON_TREE_URL__", "POOLS_JSON_URL": "__POOLS_JSON_URL__", + "AUDIT": "__MEMPOOL_AUDIT__", "ADVANCED_GBT_AUDIT": "__MEMPOOL_ADVANCED_GBT_AUDIT__", "ADVANCED_GBT_MEMPOOL": "__MEMPOOL_ADVANCED_GBT_MEMPOOL__", "CPFP_INDEXING": "__MEMPOOL_CPFP_INDEXING__" diff --git a/backend/src/__tests__/config.test.ts b/backend/src/__tests__/config.test.ts index 4158d3df1..88083f479 100644 --- a/backend/src/__tests__/config.test.ts +++ b/backend/src/__tests__/config.test.ts @@ -38,6 +38,7 @@ describe('Mempool Backend Config', () => { STDOUT_LOG_MIN_PRIORITY: 'debug', POOLS_JSON_TREE_URL: 'https://api.github.com/repos/mempool/mining-pools/git/trees/master', POOLS_JSON_URL: 'https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json', + AUDIT: false, ADVANCED_GBT_AUDIT: false, ADVANCED_GBT_MEMPOOL: false, CPFP_INDEXING: false, diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index 83de897ca..0f9e6b7f6 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -212,9 +212,11 @@ class Blocks { }; } - const auditScore = await BlocksAuditsRepository.$getBlockAuditScore(block.id); - if (auditScore != null) { - blockExtended.extras.matchRate = auditScore.matchRate; + if (config.MEMPOOL.AUDIT) { + const auditScore = await BlocksAuditsRepository.$getBlockAuditScore(block.id); + if (auditScore != null) { + blockExtended.extras.matchRate = auditScore.matchRate; + } } } diff --git a/backend/src/api/websocket-handler.ts b/backend/src/api/websocket-handler.ts index 599c068a6..9334f3717 100644 --- a/backend/src/api/websocket-handler.ts +++ b/backend/src/api/websocket-handler.ts @@ -419,49 +419,51 @@ class WebsocketHandler { const _memPool = memPool.getMempool(); - let projectedBlocks; - // template calculation functions have mempool side effects, so calculate audits using - // a cloned copy of the mempool if we're running a different algorithm for mempool updates - const auditMempool = (config.MEMPOOL.ADVANCED_GBT_AUDIT === config.MEMPOOL.ADVANCED_GBT_MEMPOOL) ? _memPool : deepClone(_memPool); - if (config.MEMPOOL.ADVANCED_GBT_AUDIT) { - projectedBlocks = await mempoolBlocks.makeBlockTemplates(auditMempool, false); - } else { - projectedBlocks = mempoolBlocks.updateMempoolBlocks(auditMempool, false); - } + if (config.MEMPOOL.AUDIT) { + let projectedBlocks; + // template calculation functions have mempool side effects, so calculate audits using + // a cloned copy of the mempool if we're running a different algorithm for mempool updates + const auditMempool = (config.MEMPOOL.ADVANCED_GBT_AUDIT === config.MEMPOOL.ADVANCED_GBT_MEMPOOL) ? _memPool : deepClone(_memPool); + if (config.MEMPOOL.ADVANCED_GBT_AUDIT) { + projectedBlocks = await mempoolBlocks.makeBlockTemplates(auditMempool, false); + } else { + projectedBlocks = mempoolBlocks.updateMempoolBlocks(auditMempool, false); + } - if (Common.indexingEnabled() && memPool.isInSync()) { - const { censored, added, fresh, score } = Audit.auditBlock(transactions, projectedBlocks, auditMempool); - const matchRate = Math.round(score * 100 * 100) / 100; + if (Common.indexingEnabled() && memPool.isInSync()) { + const { censored, added, fresh, score } = Audit.auditBlock(transactions, projectedBlocks, auditMempool); + const matchRate = Math.round(score * 100 * 100) / 100; - const stripped = projectedBlocks[0]?.transactions ? projectedBlocks[0].transactions.map((tx) => { - return { - txid: tx.txid, - vsize: tx.vsize, - fee: tx.fee ? Math.round(tx.fee) : 0, - value: tx.value, - }; - }) : []; + const stripped = projectedBlocks[0]?.transactions ? projectedBlocks[0].transactions.map((tx) => { + return { + txid: tx.txid, + vsize: tx.vsize, + fee: tx.fee ? Math.round(tx.fee) : 0, + value: tx.value, + }; + }) : []; - BlocksSummariesRepository.$saveTemplate({ - height: block.height, - template: { - id: block.id, - transactions: stripped + BlocksSummariesRepository.$saveTemplate({ + height: block.height, + template: { + id: block.id, + transactions: stripped + } + }); + + BlocksAuditsRepository.$saveAudit({ + time: block.timestamp, + height: block.height, + hash: block.id, + addedTxs: added, + missingTxs: censored, + freshTxs: fresh, + matchRate: matchRate, + }); + + if (block.extras) { + block.extras.matchRate = matchRate; } - }); - - BlocksAuditsRepository.$saveAudit({ - time: block.timestamp, - height: block.height, - hash: block.id, - addedTxs: added, - missingTxs: censored, - freshTxs: fresh, - matchRate: matchRate, - }); - - if (block.extras) { - block.extras.matchRate = matchRate; } } diff --git a/backend/src/config.ts b/backend/src/config.ts index fb06c84fb..a5736996f 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -29,6 +29,7 @@ interface IConfig { AUTOMATIC_BLOCK_REINDEXING: boolean; POOLS_JSON_URL: string, POOLS_JSON_TREE_URL: string, + AUDIT: boolean; ADVANCED_GBT_AUDIT: boolean; ADVANCED_GBT_MEMPOOL: boolean; CPFP_INDEXING: boolean; @@ -150,6 +151,7 @@ const defaults: IConfig = { 'AUTOMATIC_BLOCK_REINDEXING': false, 'POOLS_JSON_URL': 'https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json', 'POOLS_JSON_TREE_URL': 'https://api.github.com/repos/mempool/mining-pools/git/trees/master', + 'AUDIT': false, 'ADVANCED_GBT_AUDIT': false, 'ADVANCED_GBT_MEMPOOL': false, 'CPFP_INDEXING': false, diff --git a/docker/backend/mempool-config.json b/docker/backend/mempool-config.json index 2e3826f1d..17901acc4 100644 --- a/docker/backend/mempool-config.json +++ b/docker/backend/mempool-config.json @@ -23,6 +23,7 @@ "INDEXING_BLOCKS_AMOUNT": __MEMPOOL_INDEXING_BLOCKS_AMOUNT__, "BLOCKS_SUMMARIES_INDEXING": __MEMPOOL_BLOCKS_SUMMARIES_INDEXING__, "AUTOMATIC_BLOCK_REINDEXING": __MEMPOOL_AUTOMATIC_BLOCK_REINDEXING__, + "AUDIT": __MEMPOOL_AUDIT__, "ADVANCED_GBT_AUDIT": __MEMPOOL_ADVANCED_GBT_AUDIT__, "ADVANCED_GBT_MEMPOOL": __MEMPOOL_ADVANCED_GBT_MEMPOOL__, "CPFP_INDEXING": __MEMPOOL_CPFP_INDEXING__ diff --git a/docker/backend/start.sh b/docker/backend/start.sh index 5f33df107..e02706bce 100755 --- a/docker/backend/start.sh +++ b/docker/backend/start.sh @@ -27,6 +27,7 @@ __MEMPOOL_INDEXING_BLOCKS_AMOUNT__=${MEMPOOL_INDEXING_BLOCKS_AMOUNT:=false} __MEMPOOL_AUTOMATIC_BLOCK_REINDEXING__=${MEMPOOL_AUTOMATIC_BLOCK_REINDEXING:=false} __MEMPOOL_POOLS_JSON_URL__=${MEMPOOL_POOLS_JSON_URL:=https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json} __MEMPOOL_POOLS_JSON_TREE_URL__=${MEMPOOL_POOLS_JSON_TREE_URL:=https://api.github.com/repos/mempool/mining-pools/git/trees/master} +__MEMPOOL_AUDIT__=${MEMPOOL_AUDIT:=false} __MEMPOOL_ADVANCED_GBT_AUDIT__=${MEMPOOL_ADVANCED_GBT_AUDIT:=false} __MEMPOOL_ADVANCED_GBT_MEMPOOL__=${MEMPOOL_ADVANCED_GBT_MEMPOOL:=false} __MEMPOOL_CPFP_INDEXING__=${MEMPOOL_CPFP_INDEXING:=false} @@ -139,6 +140,7 @@ sed -i "s/__MEMPOOL_INDEXING_BLOCKS_AMOUNT__/${__MEMPOOL_INDEXING_BLOCKS_AMOUNT_ sed -i "s/__MEMPOOL_AUTOMATIC_BLOCK_REINDEXING__/${__MEMPOOL_AUTOMATIC_BLOCK_REINDEXING__}/g" mempool-config.json sed -i "s!__MEMPOOL_POOLS_JSON_URL__!${__MEMPOOL_POOLS_JSON_URL__}!g" mempool-config.json sed -i "s!__MEMPOOL_POOLS_JSON_TREE_URL__!${__MEMPOOL_POOLS_JSON_TREE_URL__}!g" mempool-config.json +sed -i "s!__MEMPOOL_AUDIT__!${__MEMPOOL_AUDIT__}!g" mempool-config.json sed -i "s!__MEMPOOL_ADVANCED_GBT_MEMPOOL__!${__MEMPOOL_ADVANCED_GBT_MEMPOOL__}!g" mempool-config.json sed -i "s!__MEMPOOL_ADVANCED_GBT_AUDIT__!${__MEMPOOL_ADVANCED_GBT_AUDIT__}!g" mempool-config.json sed -i "s!__MEMPOOL_CPFP_INDEXING__!${__MEMPOOL_CPFP_INDEXING__}!g" mempool-config.json diff --git a/docker/frontend/entrypoint.sh b/docker/frontend/entrypoint.sh index 3e2210360..18cb782e9 100644 --- a/docker/frontend/entrypoint.sh +++ b/docker/frontend/entrypoint.sh @@ -31,6 +31,7 @@ __LIQUID_WEBSITE_URL__=${LIQUID_WEBSITE_URL:=https://liquid.network} __BISQ_WEBSITE_URL__=${BISQ_WEBSITE_URL:=https://bisq.markets} __MINING_DASHBOARD__=${MINING_DASHBOARD:=true} __LIGHTNING__=${LIGHTNING:=false} +__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} @@ -55,6 +56,7 @@ export __LIQUID_WEBSITE_URL__ export __BISQ_WEBSITE_URL__ export __MINING_DASHBOARD__ export __LIGHTNING__ +export __AUDIT__ export __MAINNET_BLOCK_AUDIT_START_HEIGHT__ export __TESTNET_BLOCK_AUDIT_START_HEIGHT__ export __SIGNET_BLOCK_AUDIT_START_HEIGHT__ diff --git a/frontend/mempool-frontend-config.sample.json b/frontend/mempool-frontend-config.sample.json index 5c0f92acf..9035315a4 100644 --- a/frontend/mempool-frontend-config.sample.json +++ b/frontend/mempool-frontend-config.sample.json @@ -17,6 +17,7 @@ "LIQUID_WEBSITE_URL": "https://liquid.network", "BISQ_WEBSITE_URL": "https://bisq.markets", "MINING_DASHBOARD": true, + "AUDIT": false, "MAINNET_BLOCK_AUDIT_START_HEIGHT": 0, "TESTNET_BLOCK_AUDIT_START_HEIGHT": 0, "SIGNET_BLOCK_AUDIT_START_HEIGHT": 0, diff --git a/frontend/src/app/components/block/block.component.ts b/frontend/src/app/components/block/block.component.ts index f1ebfed6a..ba5dd8cf7 100644 --- a/frontend/src/app/components/block/block.component.ts +++ b/frontend/src/app/components/block/block.component.ts @@ -57,7 +57,7 @@ export class BlockComponent implements OnInit, OnDestroy { transactionsError: any = null; overviewError: any = null; webGlEnabled = true; - indexingAvailable = false; + auditSupported: boolean = this.stateService.env.AUDIT && this.stateService.env.BASE_MODULE === 'mempool' && this.stateService.env.MINING_DASHBOARD === true; auditModeEnabled: boolean = !this.stateService.hideAudit.value; auditAvailable = true; showAudit: boolean; @@ -109,13 +109,14 @@ export class BlockComponent implements OnInit, OnDestroy { this.timeLtr = !!ltr; }); - this.indexingAvailable = (this.stateService.env.BASE_MODULE === 'mempool' && this.stateService.env.MINING_DASHBOARD === true); - this.setAuditAvailable(this.indexingAvailable); + this.setAuditAvailable(this.auditSupported); - this.auditPrefSubscription = this.stateService.hideAudit.subscribe((hide) => { - this.auditModeEnabled = !hide; - this.showAudit = this.auditAvailable && this.auditModeEnabled; - }); + if (this.auditSupported) { + this.auditPrefSubscription = this.stateService.hideAudit.subscribe((hide) => { + this.auditModeEnabled = !hide; + this.showAudit = this.auditAvailable && this.auditModeEnabled; + }); + } this.txsLoadingStatus$ = this.route.paramMap .pipe( @@ -221,7 +222,9 @@ export class BlockComponent implements OnInit, OnDestroy { setTimeout(() => { this.nextBlockSubscription = this.apiService.getBlock$(block.previousblockhash).subscribe(); this.nextBlockTxListSubscription = this.electrsApiService.getBlockTransactions$(block.previousblockhash).subscribe(); - this.apiService.getBlockAudit$(block.previousblockhash); + if (this.auditSupported) { + this.apiService.getBlockAudit$(block.previousblockhash); + } }, 100); } this.updateAuditAvailableFromBlockHeight(block.height); @@ -269,7 +272,7 @@ export class BlockComponent implements OnInit, OnDestroy { this.isLoadingOverview = false; }); - if (!this.indexingAvailable) { + if (!this.auditSupported) { this.overviewSubscription = block$.pipe( startWith(null), pairwise(), @@ -300,7 +303,7 @@ export class BlockComponent implements OnInit, OnDestroy { }); } - if (this.indexingAvailable) { + if (this.auditSupported) { this.auditSubscription = block$.pipe( startWith(null), pairwise(), @@ -605,7 +608,7 @@ export class BlockComponent implements OnInit, OnDestroy { setAuditAvailable(available: boolean): void { this.auditAvailable = available; - this.showAudit = this.auditAvailable && this.auditModeEnabled; + this.showAudit = this.auditAvailable && this.auditModeEnabled && this.auditSupported; } toggleAuditMode(): void { @@ -613,6 +616,9 @@ export class BlockComponent implements OnInit, OnDestroy { } updateAuditAvailableFromBlockHeight(blockHeight: number): void { + if (!this.auditSupported) { + this.setAuditAvailable(false); + } switch (this.stateService.network) { case 'testnet': if (blockHeight < this.stateService.env.TESTNET_BLOCK_AUDIT_START_HEIGHT) { diff --git a/frontend/src/app/components/blocks-list/blocks-list.component.html b/frontend/src/app/components/blocks-list/blocks-list.component.html index 424ea2ec4..ffb5f5f88 100644 --- a/frontend/src/app/components/blocks-list/blocks-list.component.html +++ b/frontend/src/app/components/blocks-list/blocks-list.component.html @@ -14,7 +14,7 @@ i18n-ngbTooltip="mining.pool-name" ngbTooltip="Pool" placement="bottom" #miningpool [disableTooltip]="!isEllipsisActive(miningpool)">Pool
-1 )">{{ item.title }}
- -1 ) && ( !item.hasOwnProperty('options') || ( item.hasOwnProperty('options') && item.options.hasOwnProperty('officialOnly') && item.options.officialOnly && officialMempoolInstance ) )" [routerLink]="['./']" fragment="{{ item.fragment }}" (click)="navLinkClick($event)">{{ item.title }} + -1 ) && ( !item.hasOwnProperty('options') || ( item.hasOwnProperty('options') && item.options.hasOwnProperty('auditOnly') && item.options.auditOnly && auditEnabled ) )" [routerLink]="['./']" fragment="{{ item.fragment }}" (click)="navLinkClick($event)">{{ item.title }}{{ item.title }} | {{ item.category }} |