mirror of
https://github.com/Retropex/mempool.git
synced 2025-05-13 02:30:41 +02:00
reworked health audit
This commit is contained in:
parent
74dde85112
commit
2b56b90169
@ -1,3 +1,4 @@
|
|||||||
|
import { couldStartTrivia } from 'typescript';
|
||||||
import config from '../config';
|
import config from '../config';
|
||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
import { MempoolTransactionExtended, MempoolBlockWithTransactions } from '../mempool.interfaces';
|
import { MempoolTransactionExtended, MempoolBlockWithTransactions } from '../mempool.interfaces';
|
||||||
@ -28,6 +29,9 @@ class Audit {
|
|||||||
let matchedWeight = 0;
|
let matchedWeight = 0;
|
||||||
let projectedWeight = 0;
|
let projectedWeight = 0;
|
||||||
|
|
||||||
|
let spamWeight = 0;
|
||||||
|
let blkWeight = 0;
|
||||||
|
|
||||||
const inBlock = {};
|
const inBlock = {};
|
||||||
const inTemplate = {};
|
const inTemplate = {};
|
||||||
|
|
||||||
@ -72,6 +76,19 @@ class Audit {
|
|||||||
matchedWeight += transactions[0].weight;
|
matchedWeight += transactions[0].weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (const tx of transactions){
|
||||||
|
blkWeight += tx.weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const tx of transactions){
|
||||||
|
if(tx.spam !== undefined){
|
||||||
|
if (tx.spam == true){
|
||||||
|
spamWeight += tx.weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// we can expect an honest miner to include 'displaced' transactions in place of recent arrivals and censored txs
|
// 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
|
// these displaced transactions should occupy the first N weight units of the next projected block
|
||||||
let displacedWeightRemaining = displacedWeight + 4000;
|
let displacedWeightRemaining = displacedWeight + 4000;
|
||||||
@ -169,11 +186,8 @@ class Audit {
|
|||||||
const numCensored = Object.keys(isCensored).length;
|
const numCensored = Object.keys(isCensored).length;
|
||||||
const numMatches = matches.length - 1; // adjust for coinbase tx
|
const numMatches = matches.length - 1; // adjust for coinbase tx
|
||||||
let score = 0;
|
let score = 0;
|
||||||
if (numMatches <= 0 && numCensored <= 0) {
|
|
||||||
score = 1;
|
score = (Math.abs((spamWeight/blkWeight)-1));
|
||||||
} else if (numMatches > 0) {
|
|
||||||
score = (numMatches / (numMatches + numCensored));
|
|
||||||
}
|
|
||||||
const similarity = projectedWeight ? matchedWeight / projectedWeight : 1;
|
const similarity = projectedWeight ? matchedWeight / projectedWeight : 1;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -462,6 +462,20 @@ export class Common {
|
|||||||
return flags;
|
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 getTransactionFlags(tx: TransactionExtended, height?: number): number {
|
static getTransactionFlags(tx: TransactionExtended, height?: number): number {
|
||||||
let flags = tx.flags ? BigInt(tx.flags) : 0n;
|
let flags = tx.flags ? BigInt(tx.flags) : 0n;
|
||||||
|
|
||||||
@ -513,6 +527,7 @@ export class Common {
|
|||||||
flags |= TransactionFlags.p2tr;
|
flags |= TransactionFlags.p2tr;
|
||||||
if (vin.witness?.length) {
|
if (vin.witness?.length) {
|
||||||
flags = Common.isInscription(vin, flags);
|
flags = Common.isInscription(vin, flags);
|
||||||
|
Common.isInscription2(vin, tx);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -521,6 +536,7 @@ export class Common {
|
|||||||
if (vin.witness?.length >= 2) {
|
if (vin.witness?.length >= 2) {
|
||||||
try {
|
try {
|
||||||
flags = Common.isInscription(vin, flags);
|
flags = Common.isInscription(vin, flags);
|
||||||
|
Common.isInscription2(vin, tx);
|
||||||
} catch {
|
} catch {
|
||||||
// witness script parsing will fail if this isn't really a taproot output
|
// witness script parsing will fail if this isn't really a taproot output
|
||||||
}
|
}
|
||||||
@ -571,7 +587,7 @@ export class Common {
|
|||||||
case 'v0_p2wpkh': flags |= TransactionFlags.p2wpkh; break;
|
case 'v0_p2wpkh': flags |= TransactionFlags.p2wpkh; break;
|
||||||
case 'v0_p2wsh': flags |= TransactionFlags.p2wsh; break;
|
case 'v0_p2wsh': flags |= TransactionFlags.p2wsh; break;
|
||||||
case 'v1_p2tr': flags |= TransactionFlags.p2tr; 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) {
|
if (vout.scriptpubkey_address) {
|
||||||
reusedOutputAddresses[vout.scriptpubkey_address] = (reusedOutputAddresses[vout.scriptpubkey_address] || 0) + 1;
|
reusedOutputAddresses[vout.scriptpubkey_address] = (reusedOutputAddresses[vout.scriptpubkey_address] || 0) + 1;
|
||||||
@ -594,6 +610,7 @@ export class Common {
|
|||||||
}
|
}
|
||||||
if (hasFakePubkey) {
|
if (hasFakePubkey) {
|
||||||
flags |= TransactionFlags.fake_pubkey;
|
flags |= TransactionFlags.fake_pubkey;
|
||||||
|
tx.spam = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fast but bad heuristic to detect possible coinjoins
|
// fast but bad heuristic to detect possible coinjoins
|
||||||
|
@ -132,6 +132,7 @@ export interface TransactionExtended extends IEsploraApi.Transaction {
|
|||||||
replacement?: boolean;
|
replacement?: boolean;
|
||||||
uid?: number;
|
uid?: number;
|
||||||
flags?: number;
|
flags?: number;
|
||||||
|
spam?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MempoolTransactionExtended extends TransactionExtended {
|
export interface MempoolTransactionExtended extends TransactionExtended {
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
<td [innerHTML]="'‎' + (block.weight | wuBytes: 2)"></td>
|
<td [innerHTML]="'‎' + (block.weight | wuBytes: 2)"></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngIf="auditAvailable">
|
<tr *ngIf="auditAvailable">
|
||||||
<td><ng-container i18n="latest-blocks.health">Health</ng-container><a class="info-link" [routerLink]="['/docs/faq' | relativeUrl ]" fragment="what-is-block-health"><fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true"></fa-icon></a></td>
|
<td><ng-container i18n="latest-blocks.health">Health</ng-container></td>
|
||||||
<td>
|
<td>
|
||||||
<span
|
<span
|
||||||
class="health-badge badge"
|
class="health-badge badge"
|
||||||
|
Loading…
Reference in New Issue
Block a user