Merge branch 'master' into mononaut/utxo-chart-colors
This commit is contained in:
		
						commit
						92de208414
					
				@ -369,7 +369,7 @@ class MempoolBlocks {
 | 
				
			|||||||
    const lastBlockIndex = blocks.length - 1;
 | 
					    const lastBlockIndex = blocks.length - 1;
 | 
				
			||||||
    let hasBlockStack = blocks.length >= 8;
 | 
					    let hasBlockStack = blocks.length >= 8;
 | 
				
			||||||
    let stackWeight;
 | 
					    let stackWeight;
 | 
				
			||||||
    let feeStatsCalculator: OnlineFeeStatsCalculator | void;
 | 
					    let feeStatsCalculator: OnlineFeeStatsCalculator | null = null;
 | 
				
			||||||
    if (hasBlockStack) {
 | 
					    if (hasBlockStack) {
 | 
				
			||||||
      if (blockWeights && blockWeights[7] !== null) {
 | 
					      if (blockWeights && blockWeights[7] !== null) {
 | 
				
			||||||
        stackWeight = blockWeights[7];
 | 
					        stackWeight = blockWeights[7];
 | 
				
			||||||
@ -380,28 +380,36 @@ class MempoolBlocks {
 | 
				
			|||||||
      feeStatsCalculator = new OnlineFeeStatsCalculator(stackWeight, 0.5, [10, 20, 30, 40, 50, 60, 70, 80, 90]);
 | 
					      feeStatsCalculator = new OnlineFeeStatsCalculator(stackWeight, 0.5, [10, 20, 30, 40, 50, 60, 70, 80, 90]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const ancestors: Ancestor[] = [];
 | 
				
			||||||
 | 
					    const descendants: Ancestor[] = [];
 | 
				
			||||||
 | 
					    let ancestor: MempoolTransactionExtended
 | 
				
			||||||
    for (const cluster of clusters) {
 | 
					    for (const cluster of clusters) {
 | 
				
			||||||
      for (const memberTxid of cluster) {
 | 
					      for (const memberTxid of cluster) {
 | 
				
			||||||
        const mempoolTx = mempool[memberTxid];
 | 
					        const mempoolTx = mempool[memberTxid];
 | 
				
			||||||
        if (mempoolTx) {
 | 
					        if (mempoolTx) {
 | 
				
			||||||
          const ancestors: Ancestor[] = [];
 | 
					          // ugly micro-optimization to avoid allocating new arrays
 | 
				
			||||||
          const descendants: Ancestor[] = [];
 | 
					          ancestors.length = 0;
 | 
				
			||||||
 | 
					          descendants.length = 0;
 | 
				
			||||||
          let matched = false;
 | 
					          let matched = false;
 | 
				
			||||||
          cluster.forEach(txid => {
 | 
					          cluster.forEach(txid => {
 | 
				
			||||||
 | 
					            ancestor = mempool[txid];
 | 
				
			||||||
            if (txid === memberTxid) {
 | 
					            if (txid === memberTxid) {
 | 
				
			||||||
              matched = true;
 | 
					              matched = true;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
              if (!mempool[txid]) {
 | 
					              if (!ancestor) {
 | 
				
			||||||
                console.log('txid missing from mempool! ', txid, candidates?.txs[txid]);
 | 
					                console.log('txid missing from mempool! ', txid, candidates?.txs[txid]);
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              const relative = {
 | 
					              const relative = {
 | 
				
			||||||
                txid: txid,
 | 
					                txid: txid,
 | 
				
			||||||
                fee: mempool[txid].fee,
 | 
					                fee: ancestor.fee,
 | 
				
			||||||
                weight: (mempool[txid].adjustedVsize * 4),
 | 
					                weight: (ancestor.adjustedVsize * 4),
 | 
				
			||||||
              };
 | 
					              };
 | 
				
			||||||
              if (matched) {
 | 
					              if (matched) {
 | 
				
			||||||
                descendants.push(relative);
 | 
					                descendants.push(relative);
 | 
				
			||||||
                mempoolTx.lastBoosted = Math.max(mempoolTx.lastBoosted || 0, mempool[txid].firstSeen || 0);
 | 
					                if (!mempoolTx.lastBoosted || (ancestor.firstSeen && ancestor.firstSeen > mempoolTx.lastBoosted)) {
 | 
				
			||||||
 | 
					                  mempoolTx.lastBoosted = ancestor.firstSeen;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
              } else {
 | 
					              } else {
 | 
				
			||||||
                ancestors.push(relative);
 | 
					                ancestors.push(relative);
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
@ -410,7 +418,20 @@ class MempoolBlocks {
 | 
				
			|||||||
          if (mempoolTx.ancestors?.length !== ancestors.length || mempoolTx.descendants?.length !== descendants.length) {
 | 
					          if (mempoolTx.ancestors?.length !== ancestors.length || mempoolTx.descendants?.length !== descendants.length) {
 | 
				
			||||||
            mempoolTx.cpfpDirty = true;
 | 
					            mempoolTx.cpfpDirty = true;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
          Object.assign(mempoolTx, {ancestors, descendants, bestDescendant: null, cpfpChecked: true});
 | 
					          // ugly micro-optimization to avoid allocating new arrays or objects
 | 
				
			||||||
 | 
					          if (mempoolTx.ancestors) {
 | 
				
			||||||
 | 
					            mempoolTx.ancestors.length = 0;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            mempoolTx.ancestors = [];
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (mempoolTx.descendants) {
 | 
				
			||||||
 | 
					            mempoolTx.descendants.length = 0;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            mempoolTx.descendants = [];
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          mempoolTx.ancestors.push(...ancestors);
 | 
				
			||||||
 | 
					          mempoolTx.descendants.push(...descendants);
 | 
				
			||||||
 | 
					          mempoolTx.cpfpChecked = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -420,7 +441,10 @@ class MempoolBlocks {
 | 
				
			|||||||
    const sizeLimit = (config.MEMPOOL.BLOCK_WEIGHT_UNITS / 4) * 1.2;
 | 
					    const sizeLimit = (config.MEMPOOL.BLOCK_WEIGHT_UNITS / 4) * 1.2;
 | 
				
			||||||
    // update this thread's mempool with the results
 | 
					    // update this thread's mempool with the results
 | 
				
			||||||
    let mempoolTx: MempoolTransactionExtended;
 | 
					    let mempoolTx: MempoolTransactionExtended;
 | 
				
			||||||
    const mempoolBlocks: MempoolBlockWithTransactions[] = blocks.map((block, blockIndex) => {
 | 
					    let acceleration: Acceleration;
 | 
				
			||||||
 | 
					    const mempoolBlocks: MempoolBlockWithTransactions[] = [];
 | 
				
			||||||
 | 
					    for (let blockIndex = 0; blockIndex < blocks.length; blockIndex++) {
 | 
				
			||||||
 | 
					      const block = blocks[blockIndex];
 | 
				
			||||||
      let totalSize = 0;
 | 
					      let totalSize = 0;
 | 
				
			||||||
      let totalVsize = 0;
 | 
					      let totalVsize = 0;
 | 
				
			||||||
      let totalWeight = 0;
 | 
					      let totalWeight = 0;
 | 
				
			||||||
@ -436,7 +460,8 @@ class MempoolBlocks {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      for (const txid of block) {
 | 
					      for (let i = 0; i < block.length; i++) {
 | 
				
			||||||
 | 
					        const txid = block[i];
 | 
				
			||||||
        if (txid) {
 | 
					        if (txid) {
 | 
				
			||||||
          mempoolTx = mempool[txid];
 | 
					          mempoolTx = mempool[txid];
 | 
				
			||||||
          // save position in projected blocks
 | 
					          // save position in projected blocks
 | 
				
			||||||
@ -445,30 +470,37 @@ class MempoolBlocks {
 | 
				
			|||||||
            vsize: totalVsize + (mempoolTx.vsize / 2),
 | 
					            vsize: totalVsize + (mempoolTx.vsize / 2),
 | 
				
			||||||
          };
 | 
					          };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          const acceleration = accelerations[txid];
 | 
					          if (txid in accelerations) {
 | 
				
			||||||
          if (isAcceleratedBy[txid] || (acceleration && (!accelerationPool || acceleration.pools.includes(accelerationPool)))) {
 | 
					            acceleration = accelerations[txid];
 | 
				
			||||||
            if (!mempoolTx.acceleration) {
 | 
					            if (isAcceleratedBy[txid] || (acceleration && (!accelerationPool || acceleration.pools.includes(accelerationPool)))) {
 | 
				
			||||||
              mempoolTx.cpfpDirty = true;
 | 
					              if (!mempoolTx.acceleration) {
 | 
				
			||||||
            }
 | 
					                mempoolTx.cpfpDirty = true;
 | 
				
			||||||
            mempoolTx.acceleration = true;
 | 
					              }
 | 
				
			||||||
            mempoolTx.acceleratedBy = isAcceleratedBy[txid] || acceleration?.pools;
 | 
					              mempoolTx.acceleration = true;
 | 
				
			||||||
            mempoolTx.acceleratedAt = acceleration?.added;
 | 
					              mempoolTx.acceleratedBy = isAcceleratedBy[txid] || acceleration?.pools;
 | 
				
			||||||
            mempoolTx.feeDelta = acceleration?.feeDelta;
 | 
					              mempoolTx.acceleratedAt = acceleration?.added;
 | 
				
			||||||
            for (const ancestor of mempoolTx.ancestors || []) {
 | 
					              mempoolTx.feeDelta = acceleration?.feeDelta;
 | 
				
			||||||
              if (!mempool[ancestor.txid].acceleration) {
 | 
					              for (const ancestor of mempoolTx.ancestors || []) {
 | 
				
			||||||
                mempool[ancestor.txid].cpfpDirty = true;
 | 
					                if (!mempool[ancestor.txid].acceleration) {
 | 
				
			||||||
 | 
					                  mempool[ancestor.txid].cpfpDirty = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                mempool[ancestor.txid].acceleration = true;
 | 
				
			||||||
 | 
					                mempool[ancestor.txid].acceleratedBy = mempoolTx.acceleratedBy;
 | 
				
			||||||
 | 
					                mempool[ancestor.txid].acceleratedAt = mempoolTx.acceleratedAt;
 | 
				
			||||||
 | 
					                mempool[ancestor.txid].feeDelta = mempoolTx.feeDelta;
 | 
				
			||||||
 | 
					                isAcceleratedBy[ancestor.txid] = mempoolTx.acceleratedBy;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              if (mempoolTx.acceleration) {
 | 
				
			||||||
 | 
					                mempoolTx.cpfpDirty = true;
 | 
				
			||||||
 | 
					                delete mempoolTx.acceleration;
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              mempool[ancestor.txid].acceleration = true;
 | 
					 | 
				
			||||||
              mempool[ancestor.txid].acceleratedBy = mempoolTx.acceleratedBy;
 | 
					 | 
				
			||||||
              mempool[ancestor.txid].acceleratedAt = mempoolTx.acceleratedAt;
 | 
					 | 
				
			||||||
              mempool[ancestor.txid].feeDelta = mempoolTx.feeDelta;
 | 
					 | 
				
			||||||
              isAcceleratedBy[ancestor.txid] = mempoolTx.acceleratedBy;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
            if (mempoolTx.acceleration) {
 | 
					            if (mempoolTx.acceleration) {
 | 
				
			||||||
              mempoolTx.cpfpDirty = true;
 | 
					              mempoolTx.cpfpDirty = true;
 | 
				
			||||||
 | 
					              delete mempoolTx.acceleration;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            delete mempoolTx.acceleration;
 | 
					 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          // online calculation of stack-of-blocks fee stats
 | 
					          // online calculation of stack-of-blocks fee stats
 | 
				
			||||||
@ -486,7 +518,7 @@ class MempoolBlocks {
 | 
				
			|||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      return this.dataToMempoolBlocks(
 | 
					      mempoolBlocks[blockIndex] = this.dataToMempoolBlocks(
 | 
				
			||||||
        block,
 | 
					        block,
 | 
				
			||||||
        transactions,
 | 
					        transactions,
 | 
				
			||||||
        totalSize,
 | 
					        totalSize,
 | 
				
			||||||
@ -494,7 +526,7 @@ class MempoolBlocks {
 | 
				
			|||||||
        totalFees,
 | 
					        totalFees,
 | 
				
			||||||
        (hasBlockStack && blockIndex === lastBlockIndex && feeStatsCalculator) ? feeStatsCalculator.getRawFeeStats() : undefined,
 | 
					        (hasBlockStack && blockIndex === lastBlockIndex && feeStatsCalculator) ? feeStatsCalculator.getRawFeeStats() : undefined,
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (saveResults) {
 | 
					    if (saveResults) {
 | 
				
			||||||
      const deltas = this.calculateMempoolDeltas(this.mempoolBlocks, mempoolBlocks);
 | 
					      const deltas = this.calculateMempoolDeltas(this.mempoolBlocks, mempoolBlocks);
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@
 | 
				
			|||||||
          </p>
 | 
					          </p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="spacer"></div>
 | 
					        <div class="spacer"></div>
 | 
				
			||||||
        <span class="fee">{{ bar.class === 'tx' ? '' : '+' }}{{ bar.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></span>
 | 
					        <span class="fee">{{ bar.class === 'tx' ? '' : '+' }}{{ bar.fee | number }} <span class="symbol" i18n="shared.sats">sats</span></span>
 | 
				
			||||||
        <div class="spacer"></div>
 | 
					        <div class="spacer"></div>
 | 
				
			||||||
        <div class="spacer"></div>
 | 
					        <div class="spacer"></div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -21,14 +21,14 @@
 | 
				
			|||||||
      </tr>
 | 
					      </tr>
 | 
				
			||||||
      <tr *ngIf="accelerationInfo.fee">
 | 
					      <tr *ngIf="accelerationInfo.fee">
 | 
				
			||||||
        <td class="label" i18n="transaction.fee|Transaction fee">Fee</td>
 | 
					        <td class="label" i18n="transaction.fee|Transaction fee">Fee</td>
 | 
				
			||||||
        <td class="value">{{ accelerationInfo.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></td>
 | 
					        <td class="value">{{ accelerationInfo.fee | number }} <span class="symbol" i18n="shared.sats">sats</span></td>
 | 
				
			||||||
      </tr>
 | 
					      </tr>
 | 
				
			||||||
      <tr *ngIf="accelerationInfo.bidBoost >= 0 || accelerationInfo.feeDelta">
 | 
					      <tr *ngIf="accelerationInfo.bidBoost >= 0 || accelerationInfo.feeDelta">
 | 
				
			||||||
        <td class="label" i18n="transaction.out-of-band-fees">Out-of-band fees</td>
 | 
					        <td class="label" i18n="transaction.out-of-band-fees">Out-of-band fees</td>
 | 
				
			||||||
        @if (accelerationInfo.status === 'accelerated') {
 | 
					        @if (accelerationInfo.status === 'accelerated') {
 | 
				
			||||||
          <td class="value oobFees">{{ accelerationInfo.feeDelta | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></td>
 | 
					          <td class="value oobFees">{{ accelerationInfo.feeDelta | number }} <span class="symbol" i18n="shared.sats">sats</span></td>
 | 
				
			||||||
        } @else {
 | 
					        } @else {
 | 
				
			||||||
          <td class="value oobFees">{{ accelerationInfo.bidBoost | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></td>
 | 
					          <td class="value oobFees">{{ accelerationInfo.bidBoost | number }} <span class="symbol" i18n="shared.sats">sats</span></td>
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      </tr>
 | 
					      </tr>
 | 
				
			||||||
      <tr *ngIf="accelerationInfo.fee && accelerationInfo.weight">
 | 
					      <tr *ngIf="accelerationInfo.fee && accelerationInfo.weight">
 | 
				
			||||||
 | 
				
			|||||||
@ -264,7 +264,7 @@ export class AccelerationFeesGraphComponent implements OnInit, OnChanges, OnDest
 | 
				
			|||||||
          type: 'bar',
 | 
					          type: 'bar',
 | 
				
			||||||
          barWidth: '90%',
 | 
					          barWidth: '90%',
 | 
				
			||||||
          large: true,
 | 
					          large: true,
 | 
				
			||||||
          barMinHeight: 1,
 | 
					          barMinHeight: 3,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
      dataZoom: (this.widget || data.length === 0 )? undefined : [{
 | 
					      dataZoom: (this.widget || data.length === 0 )? undefined : [{
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@
 | 
				
			|||||||
              <app-fee-rate [fee]="acceleration.effectiveFee" [weight]="acceleration.effectiveVsize * 4"></app-fee-rate>
 | 
					              <app-fee-rate [fee]="acceleration.effectiveFee" [weight]="acceleration.effectiveVsize * 4"></app-fee-rate>
 | 
				
			||||||
            </td>
 | 
					            </td>
 | 
				
			||||||
            <td class="bid text-right">
 | 
					            <td class="bid text-right">
 | 
				
			||||||
              {{ (acceleration.feeDelta) | number }} <span class="symbol" i18n="shared.sat|sat">sat</span>
 | 
					              {{ (acceleration.feeDelta) | number }} <span class="symbol" i18n="shared.sats">sats</span>
 | 
				
			||||||
            </td>
 | 
					            </td>
 | 
				
			||||||
            <td class="time text-right">
 | 
					            <td class="time text-right">
 | 
				
			||||||
              <app-time kind="since" [time]="acceleration.added" [fastRender]="true" [showTooltip]="true"></app-time>
 | 
					              <app-time kind="since" [time]="acceleration.added" [fastRender]="true" [showTooltip]="true"></app-time>
 | 
				
			||||||
@ -41,7 +41,7 @@
 | 
				
			|||||||
          </ng-container>
 | 
					          </ng-container>
 | 
				
			||||||
          <ng-container *ngIf="!pending">
 | 
					          <ng-container *ngIf="!pending">
 | 
				
			||||||
            <td *ngIf="acceleration.boost != null" class="fee text-right">
 | 
					            <td *ngIf="acceleration.boost != null" class="fee text-right">
 | 
				
			||||||
              {{ acceleration.boost | number }} <span class="symbol" i18n="shared.sat|sat">sat</span>
 | 
					              {{ acceleration.boost | number }} <span class="symbol" i18n="shared.sats">sats</span>
 | 
				
			||||||
            </td>
 | 
					            </td>
 | 
				
			||||||
            <td *ngIf="acceleration.boost == null" class="fee text-right">
 | 
					            <td *ngIf="acceleration.boost == null" class="fee text-right">
 | 
				
			||||||
              ~
 | 
					              ~
 | 
				
			||||||
 | 
				
			|||||||
@ -10,10 +10,10 @@
 | 
				
			|||||||
      </td>
 | 
					      </td>
 | 
				
			||||||
      <td class="field-value" [class]="chartPositionLeft ? 'chart-left' : ''">
 | 
					      <td class="field-value" [class]="chartPositionLeft ? 'chart-left' : ''">
 | 
				
			||||||
        <div class="effective-fee-container">
 | 
					        <div class="effective-fee-container">
 | 
				
			||||||
          @if (accelerationInfo?.acceleratedFeeRate && (!tx.effectiveFeePerVsize || accelerationInfo.acceleratedFeeRate >= tx.effectiveFeePerVsize)) {
 | 
					          @if (accelerationInfo?.acceleratedFeeRate && (!effectiveFeeRate || accelerationInfo.acceleratedFeeRate >= effectiveFeeRate)) {
 | 
				
			||||||
            <app-fee-rate class="oobFees" [fee]="accelerationInfo.acceleratedFeeRate"></app-fee-rate>
 | 
					            <app-fee-rate class="oobFees" [fee]="accelerationInfo.acceleratedFeeRate"></app-fee-rate>
 | 
				
			||||||
          } @else {
 | 
					          } @else {
 | 
				
			||||||
            <app-fee-rate class="oobFees" [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
 | 
					            <app-fee-rate class="oobFees" [fee]="effectiveFeeRate"></app-fee-rate>
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </td>
 | 
					      </td>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import { Component, ChangeDetectionStrategy, Input, Output, OnChanges, SimpleChanges, EventEmitter } from '@angular/core';
 | 
					import { Component, ChangeDetectionStrategy, Input, Output, OnChanges, SimpleChanges, EventEmitter, ChangeDetectorRef } from '@angular/core';
 | 
				
			||||||
import { Transaction } from '../../../interfaces/electrs.interface';
 | 
					import { Transaction } from '../../../interfaces/electrs.interface';
 | 
				
			||||||
import { Acceleration, SinglePoolStats } from '../../../interfaces/node-api.interface';
 | 
					import { Acceleration, SinglePoolStats } from '../../../interfaces/node-api.interface';
 | 
				
			||||||
import { EChartsOption, PieSeriesOption } from '../../../graphs/echarts';
 | 
					import { EChartsOption, PieSeriesOption } from '../../../graphs/echarts';
 | 
				
			||||||
@ -23,7 +23,8 @@ function toRGB({r,g,b}): string {
 | 
				
			|||||||
  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
					  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
export class ActiveAccelerationBox implements OnChanges {
 | 
					export class ActiveAccelerationBox implements OnChanges {
 | 
				
			||||||
  @Input() tx: Transaction;
 | 
					  @Input() acceleratedBy?: number[];
 | 
				
			||||||
 | 
					  @Input() effectiveFeeRate?: number;
 | 
				
			||||||
  @Input() accelerationInfo: Acceleration;
 | 
					  @Input() accelerationInfo: Acceleration;
 | 
				
			||||||
  @Input() miningStats: MiningStats;
 | 
					  @Input() miningStats: MiningStats;
 | 
				
			||||||
  @Input() pools: number[];
 | 
					  @Input() pools: number[];
 | 
				
			||||||
@ -41,10 +42,12 @@ export class ActiveAccelerationBox implements OnChanges {
 | 
				
			|||||||
  timespan = '';
 | 
					  timespan = '';
 | 
				
			||||||
  chartInstance: any = undefined;
 | 
					  chartInstance: any = undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor() {}
 | 
					  constructor(
 | 
				
			||||||
 | 
					    private cd: ChangeDetectorRef,
 | 
				
			||||||
 | 
					  ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ngOnChanges(changes: SimpleChanges): void {
 | 
					  ngOnChanges(changes: SimpleChanges): void {
 | 
				
			||||||
    const pools = this.pools || this.accelerationInfo?.pools || this.tx.acceleratedBy;
 | 
					    const pools = this.pools || this.accelerationInfo?.pools || this.acceleratedBy;
 | 
				
			||||||
    if (pools && this.miningStats) {
 | 
					    if (pools && this.miningStats) {
 | 
				
			||||||
      this.prepareChartOptions(pools);
 | 
					      this.prepareChartOptions(pools);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -132,6 +135,7 @@ export class ActiveAccelerationBox implements OnChanges {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      ]
 | 
					      ]
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					    this.cd.markForCheck();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onChartInit(ec) {
 | 
					  onChartInit(ec) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
<div [formGroup]="amountForm" class="text-small text-center">
 | 
					<div [formGroup]="amountForm" class="text-small text-center">
 | 
				
			||||||
    <select formControlName="mode" class="custom-select custom-select-sm form-control-secondary form-control mx-auto" style="width: 70px;" (change)="changeMode()">
 | 
					    <select formControlName="mode" class="custom-select custom-select-sm form-control-secondary form-control mx-auto" style="width: 70px;" (change)="changeMode()">
 | 
				
			||||||
        <option value="btc" i18n="shared.btc|BTC">BTC</option>
 | 
					        <option value="btc" i18n="shared.btc|BTC">BTC</option>
 | 
				
			||||||
        <option value="sats" i18n="shared.sat|sat">sat</option>
 | 
					        <option value="sats" i18n="shared.sats">sats</option>
 | 
				
			||||||
        <option value="fiat" i18n="shared.fiat|Fiat">Fiat</option>
 | 
					        <option value="fiat" i18n="shared.fiat|Fiat">Fiat</option>
 | 
				
			||||||
    </select>
 | 
					    </select>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
				
			|||||||
@ -40,7 +40,7 @@
 | 
				
			|||||||
      </tr>
 | 
					      </tr>
 | 
				
			||||||
      <tr>
 | 
					      <tr>
 | 
				
			||||||
        <td class="label" i18n="transaction.fee|Transaction fee">Fee</td>
 | 
					        <td class="label" i18n="transaction.fee|Transaction fee">Fee</td>
 | 
				
			||||||
        <td class="value">{{ fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span>   <span class="fiat"><app-fiat [blockConversion]="blockConversion" [value]="fee"></app-fiat></span>
 | 
					        <td class="value">{{ fee | number }} <span class="symbol" i18n="shared.sats">sats</span>   <span class="fiat"><app-fiat [blockConversion]="blockConversion" [value]="fee"></app-fiat></span>
 | 
				
			||||||
      </tr>
 | 
					      </tr>
 | 
				
			||||||
      <tr>
 | 
					      <tr>
 | 
				
			||||||
        <td class="label" i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td>
 | 
					        <td class="label" i18n="transaction.fee-rate|Transaction fee rate">Fee rate</td>
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,7 @@
 | 
				
			|||||||
      </tr>
 | 
					      </tr>
 | 
				
			||||||
      <tr>
 | 
					      <tr>
 | 
				
			||||||
        <td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
 | 
					        <td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
 | 
				
			||||||
        <td>{{ rbfInfo.tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></td>
 | 
					        <td>{{ rbfInfo.tx.fee | number }} <span class="symbol" i18n="shared.sats">sats</span></td>
 | 
				
			||||||
      </tr>
 | 
					      </tr>
 | 
				
			||||||
      <tr *only-vsize>
 | 
					      <tr *only-vsize>
 | 
				
			||||||
        <td class="td-width" i18n="transaction.vsize|Transaction Virtual Size">Virtual size</td>
 | 
					        <td class="td-width" i18n="transaction.vsize|Transaction Virtual Size">Virtual size</td>
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@
 | 
				
			|||||||
      </ng-template>
 | 
					      </ng-template>
 | 
				
			||||||
    </span>
 | 
					    </span>
 | 
				
			||||||
    <span class="field col-sm-4 text-center"><ng-container *ngIf="transactionTime > 0">‎{{ transactionTime * 1000 | date:'yyyy-MM-dd HH:mm' }}</ng-container></span>
 | 
					    <span class="field col-sm-4 text-center"><ng-container *ngIf="transactionTime > 0">‎{{ transactionTime * 1000 | date:'yyyy-MM-dd HH:mm' }}</ng-container></span>
 | 
				
			||||||
    <span class="field col-sm-4 text-right"><span class="label" i18n="transaction.fee|Transaction fee">Fee</span> {{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></span>
 | 
					    <span class="field col-sm-4 text-right"><span class="label" i18n="transaction.fee|Transaction fee">Fee</span> {{ tx.fee | number }} <span class="symbol" i18n="shared.sats">sats</span></span>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -606,9 +606,9 @@
 | 
				
			|||||||
  @if (!isLoadingTx) {
 | 
					  @if (!isLoadingTx) {
 | 
				
			||||||
    <tr>
 | 
					    <tr>
 | 
				
			||||||
      <td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
 | 
					      <td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
 | 
				
			||||||
      <td class="text-wrap">{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span>
 | 
					      <td class="text-wrap">{{ tx.fee | number }} <span class="symbol" i18n="shared.sats">sats</span>
 | 
				
			||||||
        @if (accelerationInfo?.bidBoost ?? tx.feeDelta > 0) {
 | 
					        @if (accelerationInfo?.bidBoost ?? tx.feeDelta > 0) {
 | 
				
			||||||
          <span class="oobFees" i18n-ngbTooltip="Acceleration Fees" ngbTooltip="Acceleration fees paid out-of-band"> +{{ accelerationInfo?.bidBoost ?? tx.feeDelta | number }} </span><span class="symbol" i18n="shared.sat|sat">sat</span>
 | 
					          <span class="oobFees" i18n-ngbTooltip="Acceleration Fees" ngbTooltip="Acceleration fees paid out-of-band"> +{{ accelerationInfo?.bidBoost ?? tx.feeDelta | number }} </span><span class="symbol" i18n="shared.sats">sats</span>
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee + ((accelerationInfo?.bidBoost ?? tx.feeDelta) || 0)"></app-fiat></span>
 | 
					        <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee + ((accelerationInfo?.bidBoost ?? tx.feeDelta) || 0)"></app-fiat></span>
 | 
				
			||||||
      </td>
 | 
					      </td>
 | 
				
			||||||
@ -670,7 +670,7 @@
 | 
				
			|||||||
<ng-template #acceleratingRow>
 | 
					<ng-template #acceleratingRow>
 | 
				
			||||||
  <tr>
 | 
					  <tr>
 | 
				
			||||||
    <td rowspan="2" colspan="2" style="padding: 0;">
 | 
					    <td rowspan="2" colspan="2" style="padding: 0;">
 | 
				
			||||||
      <app-active-acceleration-box [tx]="tx" [accelerationInfo]="accelerationInfo" [miningStats]="miningStats" [hasCpfp]="hasCpfp" (toggleCpfp)="showCpfpDetails = !showCpfpDetails" [chartPositionLeft]="isMobile"></app-active-acceleration-box>
 | 
					      <app-active-acceleration-box [acceleratedBy]="tx.acceleratedBy" [effectiveFeeRate]="tx.effectiveFeePerVsize" [accelerationInfo]="accelerationInfo" [miningStats]="miningStats" [hasCpfp]="hasCpfp" (toggleCpfp)="showCpfpDetails = !showCpfpDetails" [chartPositionLeft]="isMobile"></app-active-acceleration-box>
 | 
				
			||||||
    </td>
 | 
					    </td>
 | 
				
			||||||
  </tr>
 | 
					  </tr>
 | 
				
			||||||
  <tr></tr>
 | 
					  <tr></tr>
 | 
				
			||||||
 | 
				
			|||||||
@ -321,7 +321,7 @@
 | 
				
			|||||||
      <div class="float-left mt-2-5" *ngIf="!transactionPage && !tx.vin[0].is_coinbase && tx.fee !== -1">
 | 
					      <div class="float-left mt-2-5" *ngIf="!transactionPage && !tx.vin[0].is_coinbase && tx.fee !== -1">
 | 
				
			||||||
        <app-fee-rate [fee]="tx.fee" [weight]="tx.weight"></app-fee-rate>
 | 
					        <app-fee-rate [fee]="tx.fee" [weight]="tx.weight"></app-fee-rate>
 | 
				
			||||||
        <span class="d-none d-sm-inline-block"> – {{ tx.fee | number }} <span class="symbol"
 | 
					        <span class="d-none d-sm-inline-block"> – {{ tx.fee | number }} <span class="symbol"
 | 
				
			||||||
            i18n="shared.sat|sat">sat</span> <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee"></app-fiat></span></span>
 | 
					            i18n="shared.sats">sats</span> <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee"></app-fiat></span></span>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="float-left mt-2-5 grey-info-text" *ngIf="tx.fee === -1" i18n="transactions-list.load-to-reveal-fee-info">Show more inputs to reveal fee data</div>
 | 
					      <div class="float-left mt-2-5 grey-info-text" *ngIf="tx.fee === -1" i18n="transactions-list.load-to-reveal-fee-info">Show more inputs to reveal fee data</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user