From 15bb5a966b85900088a7218d07fdd35e5f6da55e Mon Sep 17 00:00:00 2001 From: softsimon Date: Mon, 5 Oct 2020 11:42:54 +0700 Subject: [PATCH] Improved empty mempool as well as medium and low fee estimations. refs #65 --- backend/src/api/fee-api.ts | 24 ++++++++++---- .../components/fees-box/fees-box.component.ts | 32 ++++++++++++------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/backend/src/api/fee-api.ts b/backend/src/api/fee-api.ts index 1fc497465..325a12ea1 100644 --- a/backend/src/api/fee-api.ts +++ b/backend/src/api/fee-api.ts @@ -1,4 +1,5 @@ const config = require('../../mempool-config.json'); +import { MempoolBlock } from '../interfaces'; import projectedBlocks from './mempool-blocks'; class FeeApi { @@ -8,6 +9,7 @@ class FeeApi { public getRecommendedFee() { const pBlocks = projectedBlocks.getMempoolBlocks(); + if (!pBlocks.length) { return { 'fastestFee': this.defaultFee, @@ -15,14 +17,10 @@ class FeeApi { 'hourFee': this.defaultFee, }; } - let firstMedianFee = Math.ceil(pBlocks[0].medianFee); - if (pBlocks.length === 1 && pBlocks[0].blockVSize <= 500000) { - firstMedianFee = this.defaultFee; - } - - const secondMedianFee = pBlocks[1] ? Math.ceil(pBlocks[1].medianFee) : this.defaultFee; - const thirdMedianFee = pBlocks[2] ? Math.ceil(pBlocks[2].medianFee) : this.defaultFee; + const firstMedianFee = this.optimizeMedianFee(pBlocks[0]); + const secondMedianFee = pBlocks[1] ? this.optimizeMedianFee(pBlocks[1], firstMedianFee) : this.defaultFee; + const thirdMedianFee = pBlocks[2] ? this.optimizeMedianFee(pBlocks[2], secondMedianFee) : this.defaultFee; return { 'fastestFee': firstMedianFee, @@ -30,6 +28,18 @@ class FeeApi { 'hourFee': thirdMedianFee, }; } + + private optimizeMedianFee(pBlock: MempoolBlock, previousFee?: number): number { + const useFee = previousFee ? (pBlock.medianFee + previousFee / 2) : pBlock.medianFee; + if (pBlock.blockVSize <= 500000) { + return this.defaultFee; + } + if (pBlock.blockVSize <= 950000) { + const multiplier = (pBlock.blockVSize - 500000) / 500000; + return Math.max(Math.round(useFee * multiplier), this.defaultFee); + } + return Math.round(useFee); + } } export default new FeeApi(); diff --git a/frontend/src/app/components/fees-box/fees-box.component.ts b/frontend/src/app/components/fees-box/fees-box.component.ts index 9e7a53136..71e0519ef 100644 --- a/frontend/src/app/components/fees-box/fees-box.component.ts +++ b/frontend/src/app/components/fees-box/fees-box.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; import { StateService } from 'src/app/services/state.service'; import { map, filter } from 'rxjs/operators'; import { merge, Observable } from 'rxjs'; +import { MempoolBlock } from 'src/app/interfaces/websocket.interface'; interface FeeEstimations { fastestFee: number; @@ -18,13 +19,14 @@ interface FeeEstimations { export class FeesBoxComponent implements OnInit { feeEstimations$: Observable; isLoadingWebSocket$: Observable; + defaultFee: number; constructor( private stateService: StateService, ) { } ngOnInit(): void { - const defaultFee = this.stateService.network === 'liquid' ? 0.1 : 1; + this.defaultFee = this.stateService.network === 'liquid' ? 0.1 : 1; this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$; this.feeEstimations$ = this.stateService.mempoolBlocks$ @@ -32,19 +34,15 @@ export class FeesBoxComponent implements OnInit { map((pBlocks) => { if (!pBlocks.length) { return { - 'fastestFee': defaultFee, - 'halfHourFee': defaultFee, - 'hourFee': defaultFee, + 'fastestFee': this.defaultFee, + 'halfHourFee': this.defaultFee, + 'hourFee': this.defaultFee, }; } - let firstMedianFee = Math.ceil(pBlocks[0].medianFee); - if (pBlocks.length === 1 && pBlocks[0].blockVSize <= 500000) { - firstMedianFee = defaultFee; - } - - const secondMedianFee = pBlocks[1] ? Math.ceil(pBlocks[1].medianFee) : defaultFee; - const thirdMedianFee = pBlocks[2] ? Math.ceil(pBlocks[2].medianFee) : defaultFee; + const firstMedianFee = this.optimizeMedianFee(pBlocks[0]); + const secondMedianFee = pBlocks[1] ? this.optimizeMedianFee(pBlocks[1], firstMedianFee) : this.defaultFee; + const thirdMedianFee = pBlocks[2] ? this.optimizeMedianFee(pBlocks[2], secondMedianFee) : this.defaultFee; return { 'fastestFee': firstMedianFee, @@ -55,4 +53,16 @@ export class FeesBoxComponent implements OnInit { ); } + optimizeMedianFee(pBlock: MempoolBlock, previousFee?: number): number { + const useFee = previousFee ? (pBlock.medianFee + previousFee / 2) : pBlock.medianFee; + if (pBlock.blockVSize <= 500000) { + return this.defaultFee; + } + if (pBlock.blockVSize <= 950000) { + const multiplier = (pBlock.blockVSize - 500000) / 500000; + return Math.max(Math.round(useFee * multiplier), this.defaultFee); + } + return Math.round(useFee); + } + }