Merge branch 'master' into nymkappa/bugfix/bisq-dump-file
This commit is contained in:
		
						commit
						4c90d8e811
					
				@ -13,6 +13,7 @@ import config from '../config';
 | 
			
		||||
import transactionUtils from './transaction-utils';
 | 
			
		||||
import rbfCache from './rbf-cache';
 | 
			
		||||
import difficultyAdjustment from './difficulty-adjustment';
 | 
			
		||||
import feeApi from './fee-api';
 | 
			
		||||
 | 
			
		||||
class WebsocketHandler {
 | 
			
		||||
  private wss: WebSocket.Server | undefined;
 | 
			
		||||
@ -236,6 +237,7 @@ class WebsocketHandler {
 | 
			
		||||
    const rbfTransactions = Common.findRbfTransactions(newTransactions, deletedTransactions);
 | 
			
		||||
    const da = difficultyAdjustment.getDifficultyAdjustment();
 | 
			
		||||
    memPool.handleRbfTransactions(rbfTransactions);
 | 
			
		||||
    const recommendedFees = feeApi.getRecommendedFee();
 | 
			
		||||
 | 
			
		||||
    this.wss.clients.forEach(async (client: WebSocket) => {
 | 
			
		||||
      if (client.readyState !== WebSocket.OPEN) {
 | 
			
		||||
@ -249,6 +251,7 @@ class WebsocketHandler {
 | 
			
		||||
        response['vBytesPerSecond'] = vBytesPerSecond;
 | 
			
		||||
        response['transactions'] = newTransactions.slice(0, 6).map((tx) => Common.stripTransaction(tx));
 | 
			
		||||
        response['da'] = da;
 | 
			
		||||
        response['fees'] = recommendedFees;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['want-mempool-blocks']) {
 | 
			
		||||
@ -413,6 +416,7 @@ class WebsocketHandler {
 | 
			
		||||
        'block': block,
 | 
			
		||||
        'mempoolInfo': memPool.getMempoolInfo(),
 | 
			
		||||
        'da': difficultyAdjustment.getDifficultyAdjustment(),
 | 
			
		||||
        'fees': feeApi.getRecommendedFee(),
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      if (mBlocks && client['want-mempool-blocks']) {
 | 
			
		||||
 | 
			
		||||
@ -67,7 +67,7 @@ class Server {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async startServer(worker = false) {
 | 
			
		||||
    logger.debug(`Starting Mempool Server${worker ? ' (worker)' : ''}... (${backendInfo.getShortCommitHash()})`);
 | 
			
		||||
    logger.notice(`Starting Mempool Server${worker ? ' (worker)' : ''}... (${backendInfo.getShortCommitHash()})`);
 | 
			
		||||
 | 
			
		||||
    this.app
 | 
			
		||||
      .use((req: Request, res: Response, next: NextFunction) => {
 | 
			
		||||
 | 
			
		||||
@ -1,21 +1,21 @@
 | 
			
		||||
<div class="fee-estimation-wrapper">
 | 
			
		||||
  <div class="fee-estimation-container" *ngIf="(isLoadingWebSocket$ | async) === false && (feeEstimations$ | async) as feeEstimations; else loadingFees">
 | 
			
		||||
  <div class="fee-estimation-container" *ngIf="(isLoadingWebSocket$ | async) === false && (recommendedFees$ | async) as recommendedFees; else loadingFees">
 | 
			
		||||
    <div class="item">
 | 
			
		||||
      <h5 class="card-title" i18n="fees-box.low-priority">Low priority</h5>
 | 
			
		||||
      <div class="card-text" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom">
 | 
			
		||||
        <div class="fee-text">{{ feeEstimations.hourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="feeEstimations.hourFee * 140" ></app-fiat></span>
 | 
			
		||||
        <div class="fee-text">{{ recommendedFees.hourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="recommendedFees.hourFee * 140" ></app-fiat></span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="item">
 | 
			
		||||
      <h5 class="card-title" i18n="fees-box.medium-priority">Medium priority</h5>
 | 
			
		||||
      <div class="card-text" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom">
 | 
			
		||||
        <div class="fee-text">{{ feeEstimations.halfHourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="feeEstimations.halfHourFee * 140" ></app-fiat></span>
 | 
			
		||||
        <div class="fee-text">{{ recommendedFees.halfHourFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="recommendedFees.halfHourFee * 140" ></app-fiat></span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="item">
 | 
			
		||||
      <h5 class="card-title" i18n="fees-box.high-priority">High priority</h5>
 | 
			
		||||
      <div class="card-text" i18n-ngbTooltip="Transaction fee tooltip" ngbTooltip="Based on average native segwit transaction of 140 vBytes" placement="bottom">
 | 
			
		||||
        <div class="fee-text">{{ feeEstimations.fastestFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="feeEstimations.fastestFee * 140" ></app-fiat></span>
 | 
			
		||||
        <div class="fee-text">{{ recommendedFees.fastestFee }} <span i18n="shared.sat-vbyte|sat/vB">sat/vB</span></div> <span class="fiat"><app-fiat [value]="recommendedFees.fastestFee * 140" ></app-fiat></span>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core';
 | 
			
		||||
import { StateService } from 'src/app/services/state.service';
 | 
			
		||||
import { map, filter } from 'rxjs/operators';
 | 
			
		||||
import { map, filter, tap } from 'rxjs/operators';
 | 
			
		||||
import { merge, Observable } from 'rxjs';
 | 
			
		||||
import { MempoolBlock } from 'src/app/interfaces/websocket.interface';
 | 
			
		||||
import { MempoolBlock, Recommendedfees } from 'src/app/interfaces/websocket.interface';
 | 
			
		||||
 | 
			
		||||
interface FeeEstimations {
 | 
			
		||||
  fastestFee: number;
 | 
			
		||||
@ -17,8 +17,8 @@ interface FeeEstimations {
 | 
			
		||||
  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
			
		||||
})
 | 
			
		||||
export class FeesBoxComponent implements OnInit {
 | 
			
		||||
  feeEstimations$: Observable<FeeEstimations>;
 | 
			
		||||
  isLoadingWebSocket$: Observable<boolean>;
 | 
			
		||||
  recommendedFees$: Observable<Recommendedfees>;
 | 
			
		||||
  defaultFee: number;
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
@ -29,40 +29,6 @@ export class FeesBoxComponent implements OnInit {
 | 
			
		||||
    this.defaultFee = this.stateService.network === 'liquid' || this.stateService.network === 'liquidtestnet' ? 0.1 : 1;
 | 
			
		||||
 | 
			
		||||
    this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$;
 | 
			
		||||
    this.feeEstimations$ = this.stateService.mempoolBlocks$
 | 
			
		||||
      .pipe(
 | 
			
		||||
        map((pBlocks) => {
 | 
			
		||||
          if (!pBlocks.length) {
 | 
			
		||||
            return {
 | 
			
		||||
              'fastestFee': this.defaultFee,
 | 
			
		||||
              'halfHourFee': this.defaultFee,
 | 
			
		||||
              'hourFee': this.defaultFee,
 | 
			
		||||
            };
 | 
			
		||||
    this.recommendedFees$ = this.stateService.recommendedFees$;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
          const firstMedianFee = this.optimizeMedianFee(pBlocks[0], pBlocks[1]);
 | 
			
		||||
          const secondMedianFee = pBlocks[1] ? this.optimizeMedianFee(pBlocks[1], pBlocks[2], firstMedianFee) : this.defaultFee;
 | 
			
		||||
          const thirdMedianFee = pBlocks[2] ? this.optimizeMedianFee(pBlocks[2], pBlocks[3], secondMedianFee) : this.defaultFee;
 | 
			
		||||
 | 
			
		||||
          return {
 | 
			
		||||
            'fastestFee': firstMedianFee,
 | 
			
		||||
            'halfHourFee': secondMedianFee,
 | 
			
		||||
            'hourFee': thirdMedianFee,
 | 
			
		||||
          };
 | 
			
		||||
        })
 | 
			
		||||
      );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private optimizeMedianFee(pBlock: MempoolBlock, nextBlock: MempoolBlock | undefined, previousFee?: number): number {
 | 
			
		||||
    const useFee = previousFee ? (pBlock.medianFee + previousFee) / 2 : pBlock.medianFee;
 | 
			
		||||
    if (pBlock.blockVSize <= 500000) {
 | 
			
		||||
      return this.defaultFee;
 | 
			
		||||
    }
 | 
			
		||||
    if (pBlock.blockVSize <= 950000 && !nextBlock) {
 | 
			
		||||
      const multiplier = (pBlock.blockVSize - 500000) / 500000;
 | 
			
		||||
      return Math.max(Math.round(useFee * multiplier), this.defaultFee);
 | 
			
		||||
    }
 | 
			
		||||
    return Math.ceil(useFee);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -66,13 +66,16 @@
 | 
			
		||||
                        </ng-template>
 | 
			
		||||
                      </ng-template>
 | 
			
		||||
                      <ng-template #defaultAddress>
 | 
			
		||||
                        <a [routerLink]="['/address/' | relativeUrl, vin.prevout.scriptpubkey_address]" title="{{ vin.prevout.scriptpubkey_address }}">
 | 
			
		||||
                        <a *ngIf="vin.prevout.scriptpubkey_address; else vinScriptPubkeyType" [routerLink]="['/address/' | relativeUrl, vin.prevout.scriptpubkey_address]" title="{{ vin.prevout.scriptpubkey_address }}">
 | 
			
		||||
                          <span class="d-block d-lg-none">{{ vin.prevout.scriptpubkey_address | shortenString : 16 }}</span>
 | 
			
		||||
                          <span class="d-none d-lg-flex justify-content-start">
 | 
			
		||||
                            <span class="addr-left flex-grow-1" [style]="vin.prevout.scriptpubkey_address.length > 40 ? 'max-width: 235px' : ''">{{ vin.prevout.scriptpubkey_address }}</span>
 | 
			
		||||
                            <span *ngIf="vin.prevout.scriptpubkey_address.length > 40" class="addr-right">{{ vin.prevout.scriptpubkey_address | capAddress: 40: 10 }}</span>
 | 
			
		||||
                          </span>
 | 
			
		||||
                        </a>
 | 
			
		||||
                        <ng-template #vinScriptPubkeyType>
 | 
			
		||||
                          {{ vin.prevout.scriptpubkey_type?.toUpperCase() }}
 | 
			
		||||
                        </ng-template>
 | 
			
		||||
                        <div>
 | 
			
		||||
                          <app-address-labels [vin]="vin"></app-address-labels>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,7 @@ export interface WebsocketResponse {
 | 
			
		||||
  loadingIndicators?: ILoadingIndicators;
 | 
			
		||||
  backendInfo?: IBackendInfo;
 | 
			
		||||
  da?: DifficultyAdjustment;
 | 
			
		||||
  fees?: Recommendedfees;
 | 
			
		||||
  'track-tx'?: string;
 | 
			
		||||
  'track-address'?: string;
 | 
			
		||||
  'track-asset'?: string;
 | 
			
		||||
@ -65,3 +66,11 @@ export interface IBackendInfo {
 | 
			
		||||
  gitCommit: string;
 | 
			
		||||
  version: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface Recommendedfees {
 | 
			
		||||
  fastestFee: number;
 | 
			
		||||
  halfHourFee: number;
 | 
			
		||||
  hourFee: number;
 | 
			
		||||
  minimumFee: number;
 | 
			
		||||
  economyFee: number;
 | 
			
		||||
}
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
 | 
			
		||||
import { ReplaySubject, BehaviorSubject, Subject, fromEvent, Observable } from 'rxjs';
 | 
			
		||||
import { Transaction } from '../interfaces/electrs.interface';
 | 
			
		||||
import { IBackendInfo, MempoolBlock, MempoolInfo, ReplacedTransaction, TransactionStripped } from '../interfaces/websocket.interface';
 | 
			
		||||
import { IBackendInfo, MempoolBlock, MempoolInfo, Recommendedfees, ReplacedTransaction, TransactionStripped } from '../interfaces/websocket.interface';
 | 
			
		||||
import { BlockExtended, DifficultyAdjustment, OptimizedMempoolStats } from '../interfaces/node-api.interface';
 | 
			
		||||
import { Router, NavigationStart } from '@angular/router';
 | 
			
		||||
import { isPlatformBrowser } from '@angular/common';
 | 
			
		||||
@ -90,6 +90,7 @@ export class StateService {
 | 
			
		||||
  previousRetarget$ = new ReplaySubject<number>(1);
 | 
			
		||||
  backendInfo$ = new ReplaySubject<IBackendInfo>(1);
 | 
			
		||||
  loadingIndicators$ = new ReplaySubject<ILoadingIndicators>(1);
 | 
			
		||||
  recommendedFees$ = new ReplaySubject<Recommendedfees>(1);
 | 
			
		||||
 | 
			
		||||
  live2Chart$ = new Subject<OptimizedMempoolStats>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -263,6 +263,10 @@ export class WebsocketService {
 | 
			
		||||
      this.stateService.difficultyAdjustment$.next(response.da);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (response.fees) {
 | 
			
		||||
     this.stateService.recommendedFees$.next(response.fees); 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (response.backendInfo) {
 | 
			
		||||
      this.stateService.backendInfo$.next(response.backendInfo);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user