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, | ||||
|             }; | ||||
|           } | ||||
| 
 | ||||
|           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, | ||||
|           }; | ||||
|         }) | ||||
|       ); | ||||
|     this.recommendedFees$ = this.stateService.recommendedFees$; | ||||
|   } | ||||
| 
 | ||||
|   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