Merge branch 'master' into nymkappa/api-key-rest
This commit is contained in:
		
						commit
						4fc5a6197a
					
				@ -1,6 +1,6 @@
 | 
				
			|||||||
import { GbtGenerator, GbtResult, ThreadTransaction as RustThreadTransaction, ThreadAcceleration as RustThreadAcceleration } from 'rust-gbt';
 | 
					import { GbtGenerator, GbtResult, ThreadTransaction as RustThreadTransaction, ThreadAcceleration as RustThreadAcceleration } from 'rust-gbt';
 | 
				
			||||||
import logger from '../logger';
 | 
					import logger from '../logger';
 | 
				
			||||||
import { MempoolBlock, MempoolTransactionExtended, MempoolBlockWithTransactions, MempoolBlockDelta, Ancestor, CompactThreadTransaction, EffectiveFeeStats, PoolTag, TransactionClassified } from '../mempool.interfaces';
 | 
					import { MempoolBlock, MempoolTransactionExtended, MempoolBlockWithTransactions, MempoolBlockDelta, Ancestor, CompactThreadTransaction, EffectiveFeeStats, PoolTag, TransactionClassified, TransactionCompressed, MempoolDeltaChange } from '../mempool.interfaces';
 | 
				
			||||||
import { Common, OnlineFeeStatsCalculator } from './common';
 | 
					import { Common, OnlineFeeStatsCalculator } from './common';
 | 
				
			||||||
import config from '../config';
 | 
					import config from '../config';
 | 
				
			||||||
import { Worker } from 'worker_threads';
 | 
					import { Worker } from 'worker_threads';
 | 
				
			||||||
@ -171,7 +171,7 @@ class MempoolBlocks {
 | 
				
			|||||||
    for (let i = 0; i < Math.max(mempoolBlocks.length, prevBlocks.length); i++) {
 | 
					    for (let i = 0; i < Math.max(mempoolBlocks.length, prevBlocks.length); i++) {
 | 
				
			||||||
      let added: TransactionClassified[] = [];
 | 
					      let added: TransactionClassified[] = [];
 | 
				
			||||||
      let removed: string[] = [];
 | 
					      let removed: string[] = [];
 | 
				
			||||||
      const changed: { txid: string, rate: number | undefined, acc: boolean | undefined }[] = [];
 | 
					      const changed: TransactionClassified[] = [];
 | 
				
			||||||
      if (mempoolBlocks[i] && !prevBlocks[i]) {
 | 
					      if (mempoolBlocks[i] && !prevBlocks[i]) {
 | 
				
			||||||
        added = mempoolBlocks[i].transactions;
 | 
					        added = mempoolBlocks[i].transactions;
 | 
				
			||||||
      } else if (!mempoolBlocks[i] && prevBlocks[i]) {
 | 
					      } else if (!mempoolBlocks[i] && prevBlocks[i]) {
 | 
				
			||||||
@ -194,14 +194,14 @@ class MempoolBlocks {
 | 
				
			|||||||
          if (!prevIds[tx.txid]) {
 | 
					          if (!prevIds[tx.txid]) {
 | 
				
			||||||
            added.push(tx);
 | 
					            added.push(tx);
 | 
				
			||||||
          } else if (tx.rate !== prevIds[tx.txid].rate || tx.acc !== prevIds[tx.txid].acc) {
 | 
					          } else if (tx.rate !== prevIds[tx.txid].rate || tx.acc !== prevIds[tx.txid].acc) {
 | 
				
			||||||
            changed.push({ txid: tx.txid, rate: tx.rate, acc: tx.acc });
 | 
					            changed.push(tx);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      mempoolBlockDeltas.push({
 | 
					      mempoolBlockDeltas.push({
 | 
				
			||||||
        added,
 | 
					        added: added.map(this.compressTx),
 | 
				
			||||||
        removed,
 | 
					        removed,
 | 
				
			||||||
        changed,
 | 
					        changed: changed.map(this.compressDeltaChange),
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return mempoolBlockDeltas;
 | 
					    return mempoolBlockDeltas;
 | 
				
			||||||
@ -691,6 +691,38 @@ class MempoolBlocks {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
    return { blocks: convertedBlocks, blockWeights, rates: convertedRates, clusters: convertedClusters, overflow: convertedOverflow };
 | 
					    return { blocks: convertedBlocks, blockWeights, rates: convertedRates, clusters: convertedClusters, overflow: convertedOverflow };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public compressTx(tx: TransactionClassified): TransactionCompressed {
 | 
				
			||||||
 | 
					    if (tx.acc) {
 | 
				
			||||||
 | 
					      return [
 | 
				
			||||||
 | 
					        tx.txid,
 | 
				
			||||||
 | 
					        tx.fee,
 | 
				
			||||||
 | 
					        tx.vsize,
 | 
				
			||||||
 | 
					        tx.value,
 | 
				
			||||||
 | 
					        Math.round((tx.rate || (tx.fee / tx.vsize)) * 100) / 100,
 | 
				
			||||||
 | 
					        tx.flags,
 | 
				
			||||||
 | 
					        1
 | 
				
			||||||
 | 
					      ];
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return [
 | 
				
			||||||
 | 
					        tx.txid,
 | 
				
			||||||
 | 
					        tx.fee,
 | 
				
			||||||
 | 
					        tx.vsize,
 | 
				
			||||||
 | 
					        tx.value,
 | 
				
			||||||
 | 
					        Math.round((tx.rate || (tx.fee / tx.vsize)) * 100) / 100,
 | 
				
			||||||
 | 
					        tx.flags,
 | 
				
			||||||
 | 
					      ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public compressDeltaChange(tx: TransactionClassified): MempoolDeltaChange {
 | 
				
			||||||
 | 
					    return [
 | 
				
			||||||
 | 
					      tx.txid,
 | 
				
			||||||
 | 
					      Math.round((tx.rate || (tx.fee / tx.vsize)) * 100) / 100,
 | 
				
			||||||
 | 
					      tx.flags,
 | 
				
			||||||
 | 
					      tx.acc ? 1 : 0,
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default new MempoolBlocks();
 | 
					export default new MempoolBlocks();
 | 
				
			||||||
 | 
				
			|||||||
@ -259,7 +259,7 @@ class WebsocketHandler {
 | 
				
			|||||||
              const mBlocksWithTransactions = mempoolBlocks.getMempoolBlocksWithTransactions();
 | 
					              const mBlocksWithTransactions = mempoolBlocks.getMempoolBlocksWithTransactions();
 | 
				
			||||||
              response['projected-block-transactions'] = JSON.stringify({
 | 
					              response['projected-block-transactions'] = JSON.stringify({
 | 
				
			||||||
                index: index,
 | 
					                index: index,
 | 
				
			||||||
                blockTransactions: mBlocksWithTransactions[index]?.transactions || [],
 | 
					                blockTransactions: (mBlocksWithTransactions[index]?.transactions || []).map(mempoolBlocks.compressTx),
 | 
				
			||||||
              });
 | 
					              });
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
              client['track-mempool-block'] = null;
 | 
					              client['track-mempool-block'] = null;
 | 
				
			||||||
@ -999,7 +999,7 @@ class WebsocketHandler {
 | 
				
			|||||||
          if (mBlockDeltas[index].added.length > (mBlocksWithTransactions[index]?.transactions.length / 2)) {
 | 
					          if (mBlockDeltas[index].added.length > (mBlocksWithTransactions[index]?.transactions.length / 2)) {
 | 
				
			||||||
            response['projected-block-transactions'] = getCachedResponse(`projected-block-transactions-full-${index}`, {
 | 
					            response['projected-block-transactions'] = getCachedResponse(`projected-block-transactions-full-${index}`, {
 | 
				
			||||||
              index: index,
 | 
					              index: index,
 | 
				
			||||||
              blockTransactions: mBlocksWithTransactions[index].transactions,
 | 
					              blockTransactions: mBlocksWithTransactions[index].transactions.map(mempoolBlocks.compressTx),
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
            response['projected-block-transactions'] = getCachedResponse(`projected-block-transactions-delta-${index}`, {
 | 
					            response['projected-block-transactions'] = getCachedResponse(`projected-block-transactions-delta-${index}`, {
 | 
				
			||||||
 | 
				
			|||||||
@ -65,9 +65,9 @@ export interface MempoolBlockWithTransactions extends MempoolBlock {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface MempoolBlockDelta {
 | 
					export interface MempoolBlockDelta {
 | 
				
			||||||
  added: TransactionClassified[];
 | 
					  added: TransactionCompressed[];
 | 
				
			||||||
  removed: string[];
 | 
					  removed: string[];
 | 
				
			||||||
  changed: { txid: string, rate: number | undefined, flags?: number }[];
 | 
					  changed: MempoolDeltaChange[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface VinStrippedToScriptsig {
 | 
					interface VinStrippedToScriptsig {
 | 
				
			||||||
@ -196,6 +196,11 @@ export interface TransactionClassified extends TransactionStripped {
 | 
				
			|||||||
  flags: number;
 | 
					  flags: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// [txid, fee, vsize, value, rate, flags, acceleration?]
 | 
				
			||||||
 | 
					export type TransactionCompressed = [string, number, number, number, number, number, 1?];
 | 
				
			||||||
 | 
					// [txid, rate, flags, acceleration?]
 | 
				
			||||||
 | 
					export type MempoolDeltaChange = [string, number, number, (1|0)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// binary flags for transaction classification
 | 
					// binary flags for transaction classification
 | 
				
			||||||
export const TransactionFlags = {
 | 
					export const TransactionFlags = {
 | 
				
			||||||
  // features
 | 
					  // features
 | 
				
			||||||
 | 
				
			|||||||
@ -100,7 +100,7 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
 | 
				
			|||||||
          const inOldBlock = {};
 | 
					          const inOldBlock = {};
 | 
				
			||||||
          const inNewBlock = {};
 | 
					          const inNewBlock = {};
 | 
				
			||||||
          const added: TransactionStripped[] = [];
 | 
					          const added: TransactionStripped[] = [];
 | 
				
			||||||
          const changed: { txid: string, rate: number | undefined, acc: boolean | undefined }[] = [];
 | 
					          const changed: { txid: string, rate: number | undefined, flags: number, acc: boolean | undefined }[] = [];
 | 
				
			||||||
          const removed: string[] = [];
 | 
					          const removed: string[] = [];
 | 
				
			||||||
          for (const tx of transactionsStripped) {
 | 
					          for (const tx of transactionsStripped) {
 | 
				
			||||||
            inNewBlock[tx.txid] = true;
 | 
					            inNewBlock[tx.txid] = true;
 | 
				
			||||||
@ -118,6 +118,7 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
 | 
				
			|||||||
              changed.push({
 | 
					              changed.push({
 | 
				
			||||||
                txid: tx.txid,
 | 
					                txid: tx.txid,
 | 
				
			||||||
                rate: tx.rate,
 | 
					                rate: tx.rate,
 | 
				
			||||||
 | 
					                flags: tx.flags,
 | 
				
			||||||
                acc: tx.acc
 | 
					                acc: tx.acc
 | 
				
			||||||
              });
 | 
					              });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -70,9 +70,15 @@ export interface MempoolBlockWithTransactions extends MempoolBlock {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface MempoolBlockDelta {
 | 
					export interface MempoolBlockDelta {
 | 
				
			||||||
  added: TransactionStripped[],
 | 
					  added: TransactionStripped[];
 | 
				
			||||||
  removed: string[],
 | 
					  removed: string[];
 | 
				
			||||||
  changed?: { txid: string, rate: number | undefined, acc: boolean | undefined }[];
 | 
					  changed: { txid: string, rate: number, flags: number, acc: boolean }[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface MempoolBlockDeltaCompressed {
 | 
				
			||||||
 | 
					  added: TransactionCompressed[];
 | 
				
			||||||
 | 
					  removed: string[];
 | 
				
			||||||
 | 
					  changed: MempoolDeltaChange[];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface MempoolInfo {
 | 
					export interface MempoolInfo {
 | 
				
			||||||
@ -97,6 +103,11 @@ export interface TransactionStripped {
 | 
				
			|||||||
  context?: 'projected' | 'actual';
 | 
					  context?: 'projected' | 'actual';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// [txid, fee, vsize, value, rate, flags, acceleration?]
 | 
				
			||||||
 | 
					export type TransactionCompressed = [string, number, number, number, number, number, 1?];
 | 
				
			||||||
 | 
					// [txid, rate, flags, acceleration?]
 | 
				
			||||||
 | 
					export type MempoolDeltaChange = [string, number, number, (1|0)];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IBackendInfo {
 | 
					export interface IBackendInfo {
 | 
				
			||||||
  hostname?: string;
 | 
					  hostname?: string;
 | 
				
			||||||
  gitCommit: string;
 | 
					  gitCommit: string;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import { Inject, Injectable, PLATFORM_ID, LOCALE_ID } from '@angular/core';
 | 
					import { Inject, Injectable, PLATFORM_ID, LOCALE_ID } from '@angular/core';
 | 
				
			||||||
import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable, merge } from 'rxjs';
 | 
					import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable, merge } from 'rxjs';
 | 
				
			||||||
import { Transaction } from '../interfaces/electrs.interface';
 | 
					import { Transaction } from '../interfaces/electrs.interface';
 | 
				
			||||||
import { IBackendInfo, MempoolBlock, MempoolBlockDelta, MempoolInfo, Recommendedfees, ReplacedTransaction, ReplacementInfo, TransactionStripped } from '../interfaces/websocket.interface';
 | 
					import { IBackendInfo, MempoolBlock, MempoolBlockDelta, MempoolInfo, Recommendedfees, ReplacedTransaction, ReplacementInfo, TransactionCompressed, TransactionStripped } from '../interfaces/websocket.interface';
 | 
				
			||||||
import { BlockExtended, CpfpInfo, DifficultyAdjustment, MempoolPosition, OptimizedMempoolStats, RbfTree } from '../interfaces/node-api.interface';
 | 
					import { BlockExtended, CpfpInfo, DifficultyAdjustment, MempoolPosition, OptimizedMempoolStats, RbfTree } from '../interfaces/node-api.interface';
 | 
				
			||||||
import { Router, NavigationStart } from '@angular/router';
 | 
					import { Router, NavigationStart } from '@angular/router';
 | 
				
			||||||
import { isPlatformBrowser } from '@angular/common';
 | 
					import { isPlatformBrowser } from '@angular/common';
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@ import { ApiService } from './api.service';
 | 
				
			|||||||
import { take } from 'rxjs/operators';
 | 
					import { take } from 'rxjs/operators';
 | 
				
			||||||
import { TransferState, makeStateKey } from '@angular/platform-browser';
 | 
					import { TransferState, makeStateKey } from '@angular/platform-browser';
 | 
				
			||||||
import { CacheService } from './cache.service';
 | 
					import { CacheService } from './cache.service';
 | 
				
			||||||
 | 
					import { uncompressDeltaChange, uncompressTx } from '../shared/common.utils';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const OFFLINE_RETRY_AFTER_MS = 2000;
 | 
					const OFFLINE_RETRY_AFTER_MS = 2000;
 | 
				
			||||||
const OFFLINE_PING_CHECK_AFTER_MS = 30000;
 | 
					const OFFLINE_PING_CHECK_AFTER_MS = 30000;
 | 
				
			||||||
@ -382,9 +383,9 @@ export class WebsocketService {
 | 
				
			|||||||
    if (response['projected-block-transactions']) {
 | 
					    if (response['projected-block-transactions']) {
 | 
				
			||||||
      if (response['projected-block-transactions'].index == this.trackingMempoolBlock) {
 | 
					      if (response['projected-block-transactions'].index == this.trackingMempoolBlock) {
 | 
				
			||||||
        if (response['projected-block-transactions'].blockTransactions) {
 | 
					        if (response['projected-block-transactions'].blockTransactions) {
 | 
				
			||||||
          this.stateService.mempoolBlockTransactions$.next(response['projected-block-transactions'].blockTransactions);
 | 
					          this.stateService.mempoolBlockTransactions$.next(response['projected-block-transactions'].blockTransactions.map(uncompressTx));
 | 
				
			||||||
        } else if (response['projected-block-transactions'].delta) {
 | 
					        } else if (response['projected-block-transactions'].delta) {
 | 
				
			||||||
          this.stateService.mempoolBlockDelta$.next(response['projected-block-transactions'].delta);
 | 
					          this.stateService.mempoolBlockDelta$.next(uncompressDeltaChange(response['projected-block-transactions'].delta));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					import { MempoolBlockDelta, MempoolBlockDeltaCompressed, MempoolDeltaChange, TransactionCompressed, TransactionStripped } from "../interfaces/websocket.interface";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function isMobile(): boolean {
 | 
					export function isMobile(): boolean {
 | 
				
			||||||
  return (window.innerWidth <= 767.98);
 | 
					  return (window.innerWidth <= 767.98);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -152,4 +154,29 @@ export function seoDescriptionNetwork(network: string): string {
 | 
				
			|||||||
    return ' ' + network.charAt(0).toUpperCase() + network.slice(1);
 | 
					    return ' ' + network.charAt(0).toUpperCase() + network.slice(1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return '';
 | 
					  return '';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function uncompressTx(tx: TransactionCompressed): TransactionStripped {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    txid: tx[0],
 | 
				
			||||||
 | 
					    fee: tx[1],
 | 
				
			||||||
 | 
					    vsize: tx[2],
 | 
				
			||||||
 | 
					    value: tx[3],
 | 
				
			||||||
 | 
					    rate: tx[4],
 | 
				
			||||||
 | 
					    flags: tx[5],
 | 
				
			||||||
 | 
					    acc: !!tx[6],
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function uncompressDeltaChange(delta: MempoolBlockDeltaCompressed): MempoolBlockDelta {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    added: delta.added.map(uncompressTx),
 | 
				
			||||||
 | 
					    removed: delta.removed,
 | 
				
			||||||
 | 
					    changed: delta.changed.map(tx => ({
 | 
				
			||||||
 | 
					      txid: tx[0],
 | 
				
			||||||
 | 
					      rate: tx[1],
 | 
				
			||||||
 | 
					      flags: tx[2],
 | 
				
			||||||
 | 
					      acc: !!tx[3],
 | 
				
			||||||
 | 
					    }))
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user