animate mempool blocks conditional on mined block similarity

This commit is contained in:
Mononaut 2023-03-14 10:19:32 +09:00
parent 64ab14f995
commit c24724dcdf
No known key found for this signature in database
GPG Key ID: A3F058E41374C04E
5 changed files with 18 additions and 6 deletions

View File

@ -5,9 +5,9 @@ const PROPAGATION_MARGIN = 180; // in seconds, time since a transaction is first
class Audit {
auditBlock(transactions: TransactionExtended[], projectedBlocks: MempoolBlockWithTransactions[], mempool: { [txId: string]: TransactionExtended })
: { censored: string[], added: string[], fresh: string[], score: number } {
: { censored: string[], added: string[], fresh: string[], score: number, similarity: number } {
if (!projectedBlocks?.[0]?.transactionIds || !mempool) {
return { censored: [], added: [], fresh: [], score: 0 };
return { censored: [], added: [], fresh: [], score: 0, similarity: 1 };
}
const matches: string[] = []; // present in both mined block and template
@ -16,6 +16,8 @@ class Audit {
const isCensored = {}; // missing, without excuse
const isDisplaced = {};
let displacedWeight = 0;
let matchedWeight = 0;
let projectedWeight = 0;
const inBlock = {};
const inTemplate = {};
@ -38,11 +40,16 @@ class Audit {
isCensored[txid] = true;
}
displacedWeight += mempool[txid].weight;
} else {
matchedWeight += mempool[txid].weight;
}
projectedWeight += mempool[txid].weight;
inTemplate[txid] = true;
}
displacedWeight += (4000 - transactions[0].weight);
projectedWeight += transactions[0].weight;
matchedWeight += transactions[0].weight;
// 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
@ -121,12 +128,14 @@ class Audit {
const numCensored = Object.keys(isCensored).length;
const numMatches = matches.length - 1; // adjust for coinbase tx
const score = numMatches > 0 ? (numMatches / (numMatches + numCensored)) : 0;
const similarity = projectedWeight ? matchedWeight / projectedWeight : 1;
return {
censored: Object.keys(isCensored),
added,
fresh,
score
score,
similarity,
};
}
}

View File

@ -432,7 +432,7 @@ class WebsocketHandler {
}
if (Common.indexingEnabled() && memPool.isInSync()) {
const { censored, added, fresh, score } = Audit.auditBlock(transactions, projectedBlocks, auditMempool);
const { censored, added, fresh, score, similarity } = Audit.auditBlock(transactions, projectedBlocks, auditMempool);
const matchRate = Math.round(score * 100 * 100) / 100;
const stripped = projectedBlocks[0]?.transactions ? projectedBlocks[0].transactions.map((tx) => {
@ -464,6 +464,7 @@ class WebsocketHandler {
if (block.extras) {
block.extras.matchRate = matchRate;
block.extras.similarity = similarity;
}
}
}

View File

@ -153,6 +153,7 @@ export interface BlockExtension {
feeRange: number[]; // fee rate percentiles
reward: number;
matchRate: number | null;
similarity?: number;
pool: {
id: number; // Note - This is the `unique_id`, not to mix with the auto increment `id`
name: string;

View File

@ -174,7 +174,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
}
this.chainTip = this.stateService.latestBlockHeight;
if (block?.extras?.matchRate >= 66 && !this.tabHidden) {
if ((block?.extras?.similarity == null || block?.extras?.similarity > 0.5) && !this.tabHidden) {
this.blockIndex++;
}
});
@ -225,7 +225,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
}
trackByFn(index: number, block: MempoolBlock) {
return (block.isStack) ? 'stack' : block.height;
return (block.isStack) ? 'stack' : block.index;
}
reduceMempoolBlocksToFitScreen(blocks: MempoolBlock[]): MempoolBlock[] {

View File

@ -118,6 +118,7 @@ export interface BlockExtension {
reward?: number;
coinbaseRaw?: string;
matchRate?: number;
similarity?: number;
pool?: {
id: number;
name: string;