Track and display purged transaction status
This commit is contained in:
parent
5826f8fa1e
commit
2e6a0c0967
@ -16,6 +16,7 @@ class Mempool {
|
||||
private inSync: boolean = false;
|
||||
private mempoolCacheDelta: number = -1;
|
||||
private mempoolCache: { [txId: string]: TransactionExtended } = {};
|
||||
private minFeeMempool: { [txId: string]: boolean } = {};
|
||||
private mempoolInfo: IBitcoinApi.MempoolInfo = { loaded: false, size: 0, bytes: 0, usage: 0, total_fee: 0,
|
||||
maxmempool: 300000000, mempoolminfee: 0.00001000, minrelaytxfee: 0.00001000 };
|
||||
private mempoolChangedCallback: ((newMempool: {[txId: string]: TransactionExtended; }, newTransactions: TransactionExtended[],
|
||||
@ -124,6 +125,7 @@ class Mempool {
|
||||
let hasChange: boolean = false;
|
||||
const currentMempoolSize = Object.keys(this.mempoolCache).length;
|
||||
const transactions = await bitcoinApi.$getRawMempool();
|
||||
await this.updateMinFeeMempool();
|
||||
const diff = transactions.length - currentMempoolSize;
|
||||
const newTransactions: TransactionExtended[] = [];
|
||||
|
||||
@ -232,6 +234,34 @@ class Mempool {
|
||||
logger.debug(`Mempool updated in ${time / 1000} seconds. New size: ${Object.keys(this.mempoolCache).length} (${diff > 0 ? '+' + diff : diff})`);
|
||||
}
|
||||
|
||||
public isTxPurged(txid: string): boolean {
|
||||
return !this.minFeeMempool[txid];
|
||||
}
|
||||
|
||||
private async updateMinFeeMempool() {
|
||||
const minFeeTransactions = await bitcoinSecondClient.getRawMemPool();
|
||||
const minFeeTxMap = {};
|
||||
for (const txid of minFeeTransactions) {
|
||||
minFeeTxMap[txid] = true;
|
||||
}
|
||||
const removed: string[] = [];
|
||||
const added: string[] = [];
|
||||
for (const txid of Object.keys(this.minFeeMempool)) {
|
||||
if (!minFeeTxMap[txid]) {
|
||||
removed.push(txid);
|
||||
}
|
||||
}
|
||||
for (const txid of minFeeTransactions) {
|
||||
if (!this.minFeeMempool[txid]) {
|
||||
added.push(txid);
|
||||
this.minFeeMempool[txid] = true;
|
||||
}
|
||||
}
|
||||
for (const txid of removed) {
|
||||
delete this.minFeeMempool[txid];
|
||||
}
|
||||
}
|
||||
|
||||
public handleRbfTransactions(rbfTransactions: { [txid: string]: TransactionExtended; }) {
|
||||
for (const rbfTransaction in rbfTransactions) {
|
||||
if (this.mempoolCache[rbfTransaction]) {
|
||||
|
@ -19,6 +19,7 @@ import BlocksAuditsRepository from '../repositories/BlocksAuditsRepository';
|
||||
import BlocksSummariesRepository from '../repositories/BlocksSummariesRepository';
|
||||
import Audit from './audit';
|
||||
import { deepClone } from '../utils/clone';
|
||||
import mempool from './mempool';
|
||||
import priceUpdater from '../tasks/price-updater';
|
||||
import { ApiPrice } from '../repositories/PricesRepository';
|
||||
|
||||
@ -92,6 +93,9 @@ class WebsocketHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (config.MEMPOOL.USE_SECOND_NODE_FOR_MINFEE && memPool.getMempool()[client['track-tx']]) {
|
||||
response['txPurged'] = memPool.isTxPurged(client['track-tx']);
|
||||
}
|
||||
} else {
|
||||
client['track-tx'] = null;
|
||||
}
|
||||
@ -395,6 +399,11 @@ class WebsocketHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update purge status of unconfirmed tracked txs
|
||||
if (config.MEMPOOL.USE_SECOND_NODE_FOR_MINFEE && newMempool[client['track-tx']]) {
|
||||
response['txPurged'] = memPool.isTxPurged(client['track-tx']);
|
||||
}
|
||||
}
|
||||
|
||||
if (client['track-mempool-block'] >= 0) {
|
||||
|
@ -1,6 +1,10 @@
|
||||
<div class="container-xl">
|
||||
|
||||
<div class="title-block">
|
||||
<div *ngIf="isPurged" class="alert alert-mempool" role="alert">
|
||||
<span i18n="transaction.purged|Purged from mempool">This transaction has been purged from our default sized 300MB mempool</span>
|
||||
</div>
|
||||
|
||||
<div *ngIf="rbfTransaction" class="alert alert-mempool" role="alert">
|
||||
<span i18n="transaction.rbf.replacement|RBF replacement">This transaction has been replaced by:</span>
|
||||
<app-truncate [text]="rbfTransaction.txid" [lastChars]="12" [link]="['/tx/' | relativeUrl, rbfTransaction.txid]"></app-truncate>
|
||||
|
@ -46,6 +46,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
fetchRbfSubscription: Subscription;
|
||||
fetchCachedTxSubscription: Subscription;
|
||||
txReplacedSubscription: Subscription;
|
||||
txPurgedSubscription: Subscription;
|
||||
blocksSubscription: Subscription;
|
||||
queryParamsSubscription: Subscription;
|
||||
urlFragmentSubscription: Subscription;
|
||||
@ -59,6 +60,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
fetchRbfHistory$ = new Subject<string>();
|
||||
fetchCachedTx$ = new Subject<string>();
|
||||
isCached: boolean = false;
|
||||
isPurged: boolean = false;
|
||||
now = new Date().getTime();
|
||||
timeAvg$: Observable<number>;
|
||||
liquidUnblinding = new LiquidUnblinding();
|
||||
@ -380,6 +382,10 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
}
|
||||
});
|
||||
|
||||
this.txPurgedSubscription = this.stateService.txPurged$.subscribe((isPurged) => {
|
||||
this.isPurged = isPurged;
|
||||
});
|
||||
|
||||
this.queryParamsSubscription = this.route.queryParams.subscribe((params) => {
|
||||
if (params.showFlow === 'false') {
|
||||
this.overrideFlowPreference = false;
|
||||
@ -532,6 +538,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.fetchRbfSubscription.unsubscribe();
|
||||
this.fetchCachedTxSubscription.unsubscribe();
|
||||
this.txReplacedSubscription.unsubscribe();
|
||||
this.txPurgedSubscription.unsubscribe();
|
||||
this.blocksSubscription.unsubscribe();
|
||||
this.queryParamsSubscription.unsubscribe();
|
||||
this.flowPrefSubscription.unsubscribe();
|
||||
|
@ -16,6 +16,7 @@ export interface WebsocketResponse {
|
||||
tx?: Transaction;
|
||||
rbfTransaction?: ReplacedTransaction;
|
||||
txReplaced?: ReplacedTransaction;
|
||||
txPurged?: boolean;
|
||||
utxoSpent?: object;
|
||||
transactions?: TransactionStripped[];
|
||||
loadingIndicators?: ILoadingIndicators;
|
||||
|
@ -98,6 +98,7 @@ export class StateService {
|
||||
mempoolBlockTransactions$ = new Subject<TransactionStripped[]>();
|
||||
mempoolBlockDelta$ = new Subject<MempoolBlockDelta>();
|
||||
txReplaced$ = new Subject<ReplacedTransaction>();
|
||||
txPurged$ = new Subject<boolean>();
|
||||
utxoSpent$ = new Subject<object>();
|
||||
difficultyAdjustment$ = new ReplaySubject<DifficultyAdjustment>(1);
|
||||
mempoolTransactions$ = new Subject<Transaction>();
|
||||
|
@ -261,6 +261,10 @@ export class WebsocketService {
|
||||
this.stateService.txReplaced$.next(response.txReplaced);
|
||||
}
|
||||
|
||||
if (response.txPurged != null) {
|
||||
this.stateService.txPurged$.next(response.txPurged);
|
||||
}
|
||||
|
||||
if (response['mempool-blocks']) {
|
||||
this.stateService.mempoolBlocks$.next(response['mempool-blocks']);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user