mirror of
https://github.com/mempool/mempool.git
synced 2026-08-13 12:33:11 +02:00
Merge pull request #6442 from mempool/mononaut/shill-accelerator
Some checks failed
Backend Integration Tests with MariaDB / Backend Integration Tests - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Backend (dev) - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Backend (prod) - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Cache assets for builds (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Frontend (dev) - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Frontend (prod) - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / E2E tests for liquid (push) Has been cancelled
CI Pipeline for the Backend and Frontend / E2E tests for mempool (push) Has been cancelled
CI Pipeline for the Backend and Frontend / E2E tests for testnet4 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Validate generated backend Docker JSON (push) Has been cancelled
Supply Chain Audit / Backend install-script audit (push) Has been cancelled
Supply Chain Audit / Frontend install-script audit (push) Has been cancelled
Some checks failed
Backend Integration Tests with MariaDB / Backend Integration Tests - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Backend (dev) - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Backend (prod) - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Cache assets for builds (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Frontend (dev) - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Frontend (prod) - node 24.13.0 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / E2E tests for liquid (push) Has been cancelled
CI Pipeline for the Backend and Frontend / E2E tests for mempool (push) Has been cancelled
CI Pipeline for the Backend and Frontend / E2E tests for testnet4 (push) Has been cancelled
CI Pipeline for the Backend and Frontend / Validate generated backend Docker JSON (push) Has been cancelled
Supply Chain Audit / Backend install-script audit (push) Has been cancelled
Supply Chain Audit / Frontend install-script audit (push) Has been cancelled
This commit is contained in:
commit
7d1bfca75b
2 changed files with 65 additions and 6 deletions
|
|
@ -46,6 +46,11 @@
|
|||
<ng-template #detailsRight>
|
||||
<ng-container *ngTemplateOutlet="feeRow"></ng-container>
|
||||
<ng-container *ngTemplateOutlet="feeRateRow"></ng-container>
|
||||
@if (showAcceleratorSavingsMsg) {
|
||||
<tr>
|
||||
<td colspan="2" style="--bs-table-bg-type: var(--tertiary); white-space: normal; text-align: center;">Could have saved <app-fiat [blockConversion]="tx.price" [value]="acceleratorSavingsSats"></app-fiat> using <a href="https://mempool.space/enterprise#accelerator-pro" target="_blank" rel="noopener">Mempool Accelerator® Pro</a></td>
|
||||
</tr>
|
||||
}
|
||||
@if (!isLoadingTx && !tx?.status?.confirmed && isAcceleration) {
|
||||
<ng-container *ngTemplateOutlet="acceleratingRow"></ng-container>
|
||||
} @else {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import { Component, OnInit, Input, ChangeDetectionStrategy, Output, EventEmitter } from '@angular/core';
|
||||
import { Component, OnChanges, SimpleChanges, Input, ChangeDetectionStrategy, ChangeDetectorRef, Output, EventEmitter } from '@angular/core';
|
||||
import { Transaction } from '@interfaces/electrs.interface';
|
||||
import { Acceleration, CpfpInfo } from '@interfaces/node-api.interface';
|
||||
import { Acceleration, BlockExtended, CpfpInfo } from '@interfaces/node-api.interface';
|
||||
import { Pool, TxAuditStatus } from '@components/transaction/transaction.component';
|
||||
import { Observable } from 'rxjs';
|
||||
import { first, timeout } from 'rxjs/operators';
|
||||
import { ETA } from '@app/services/eta.service';
|
||||
import { MiningStats } from '@app/services/mining.service';
|
||||
import { Filter } from '@app/shared/filters.utils';
|
||||
import { Filter, TransactionFlags } from '@app/shared/filters.utils';
|
||||
import { StateService } from '@app/services/state.service';
|
||||
import { CacheService } from '@app/services/cache.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-transaction-details',
|
||||
|
|
@ -14,7 +17,7 @@ import { Filter } from '@app/shared/filters.utils';
|
|||
standalone: false,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class TransactionDetailsComponent implements OnInit {
|
||||
export class TransactionDetailsComponent implements OnChanges {
|
||||
@Input() network: string;
|
||||
@Input() tx: Transaction;
|
||||
@Input() isLoadingTx: boolean;
|
||||
|
|
@ -45,9 +48,60 @@ export class TransactionDetailsComponent implements OnInit {
|
|||
@Output() accelerateClicked = new EventEmitter<boolean>();
|
||||
@Output() toggleCpfp$ = new EventEmitter<void>();
|
||||
|
||||
constructor() {}
|
||||
acceleratorSavingsSats = 0;
|
||||
officialMempoolSpace: boolean;
|
||||
|
||||
ngOnInit(): void {}
|
||||
constructor(
|
||||
private stateService: StateService,
|
||||
private cacheService: CacheService,
|
||||
private cd: ChangeDetectorRef,
|
||||
) {
|
||||
this.officialMempoolSpace = this.stateService.env.OFFICIAL_MEMPOOL_SPACE;
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (!changes.tx) {
|
||||
return;
|
||||
}
|
||||
this.acceleratorSavingsSats = 0;
|
||||
const hasIneligibleFlags = ((this.tx?.flags ?? 0n) & (TransactionFlags.inscription | TransactionFlags.sighash_none | TransactionFlags.sighash_single | TransactionFlags.sighash_acp)) > 0n;
|
||||
if (this.officialMempoolSpace
|
||||
&& this.tx?.status?.confirmed
|
||||
&& !this.tx.acceleration && !this.accelerationInfo
|
||||
&& this.tx.weight <= 4000
|
||||
&& !hasIneligibleFlags
|
||||
&& Math.min(...this.tx.vout.map(o => o.value)) <= 1000000
|
||||
) {
|
||||
const block = this.cacheService.getCachedBlock(this.tx.status.block_height);
|
||||
if (block) {
|
||||
this.calculateAcceleratorSavings(block);
|
||||
} else {
|
||||
const txid = this.tx.txid;
|
||||
this.cacheService.loadBlock(this.tx.status.block_height);
|
||||
this.cacheService.loadedBlocks$.pipe(
|
||||
first(b => b.height === this.tx.status.block_height),
|
||||
timeout({ each: 30000, with: () => [] }),
|
||||
).subscribe((block) => {
|
||||
if (this.tx?.txid === txid) {
|
||||
this.calculateAcceleratorSavings(block);
|
||||
this.cd.markForCheck();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
calculateAcceleratorSavings(block: BlockExtended): void {
|
||||
const minBlockRate = block?.extras?.feeRange?.[0];
|
||||
if (minBlockRate !== undefined) {
|
||||
const vsize = this.tx.weight / 4;
|
||||
this.acceleratorSavingsSats = Math.max(0, this.tx.fee - Math.ceil(minBlockRate * vsize) - 75000);
|
||||
}
|
||||
}
|
||||
|
||||
get showAcceleratorSavingsMsg(): boolean {
|
||||
return this.acceleratorSavingsSats > 0 && this.cpfpInfo !== null && this.cpfpInfo !== undefined && !this.hasCpfp;
|
||||
}
|
||||
|
||||
onAccelerateClicked(): void {
|
||||
this.accelerateClicked.emit(true);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue