Retrieve acceleration request time and first seen time

This commit is contained in:
natsoni 2024-07-04 16:52:22 +09:00
parent 46c4d57367
commit 815dcbd4ce
No known key found for this signature in database
GPG Key ID: C65917583181743B
7 changed files with 20 additions and 2 deletions

View File

@ -162,6 +162,7 @@ class BitcoinRoutes {
adjustedVsize: tx.adjustedVsize, adjustedVsize: tx.adjustedVsize,
acceleration: tx.acceleration, acceleration: tx.acceleration,
acceleratedBy: tx.acceleratedBy || undefined, acceleratedBy: tx.acceleratedBy || undefined,
acceleratedAt: tx.acceleratedAt || undefined,
}); });
return; return;
} }

View File

@ -449,12 +449,14 @@ class MempoolBlocks {
} }
mempoolTx.acceleration = true; mempoolTx.acceleration = true;
mempoolTx.acceleratedBy = isAcceleratedBy[txid] || acceleration?.pools; mempoolTx.acceleratedBy = isAcceleratedBy[txid] || acceleration?.pools;
mempoolTx.acceleratedAt = acceleration?.added;
for (const ancestor of mempoolTx.ancestors || []) { for (const ancestor of mempoolTx.ancestors || []) {
if (!mempool[ancestor.txid].acceleration) { if (!mempool[ancestor.txid].acceleration) {
mempool[ancestor.txid].cpfpDirty = true; mempool[ancestor.txid].cpfpDirty = true;
} }
mempool[ancestor.txid].acceleration = true; mempool[ancestor.txid].acceleration = true;
mempool[ancestor.txid].acceleratedBy = mempoolTx.acceleratedBy; mempool[ancestor.txid].acceleratedBy = mempoolTx.acceleratedBy;
mempool[ancestor.txid].acceleratedAt = mempoolTx.acceleratedAt;
isAcceleratedBy[ancestor.txid] = mempoolTx.acceleratedBy; isAcceleratedBy[ancestor.txid] = mempoolTx.acceleratedBy;
} }
} else { } else {

View File

@ -822,6 +822,7 @@ class WebsocketHandler {
...mempoolTx.position, ...mempoolTx.position,
accelerated: mempoolTx.acceleration || undefined, accelerated: mempoolTx.acceleration || undefined,
acceleratedBy: mempoolTx.acceleratedBy || undefined, acceleratedBy: mempoolTx.acceleratedBy || undefined,
acceleratedAt: mempoolTx.acceleratedAt || undefined,
}, },
accelerationPositions: memPool.getAccelerationPositions(mempoolTx.txid), accelerationPositions: memPool.getAccelerationPositions(mempoolTx.txid),
}; };
@ -862,6 +863,7 @@ class WebsocketHandler {
...mempoolTx.position, ...mempoolTx.position,
accelerated: mempoolTx.acceleration || undefined, accelerated: mempoolTx.acceleration || undefined,
acceleratedBy: mempoolTx.acceleratedBy || undefined, acceleratedBy: mempoolTx.acceleratedBy || undefined,
acceleratedAt: mempoolTx.acceleratedAt || undefined,
}; };
if (!mempoolTx.cpfpChecked) { if (!mempoolTx.cpfpChecked) {
calculateCpfp(mempoolTx, newMempool); calculateCpfp(mempoolTx, newMempool);
@ -1139,6 +1141,7 @@ class WebsocketHandler {
...mempoolTx.position, ...mempoolTx.position,
accelerated: mempoolTx.acceleration || undefined, accelerated: mempoolTx.acceleration || undefined,
acceleratedBy: mempoolTx.acceleratedBy || undefined, acceleratedBy: mempoolTx.acceleratedBy || undefined,
acceleratedAt: mempoolTx.acceleratedAt || undefined,
}, },
accelerationPositions: memPool.getAccelerationPositions(mempoolTx.txid), accelerationPositions: memPool.getAccelerationPositions(mempoolTx.txid),
}); });
@ -1160,6 +1163,7 @@ class WebsocketHandler {
}, },
accelerated: mempoolTx.acceleration || undefined, accelerated: mempoolTx.acceleration || undefined,
acceleratedBy: mempoolTx.acceleratedBy || undefined, acceleratedBy: mempoolTx.acceleratedBy || undefined,
acceleratedAt: mempoolTx.acceleratedAt || undefined,
}; };
} }
} }

View File

@ -112,6 +112,7 @@ export interface TransactionExtended extends IEsploraApi.Transaction {
}; };
acceleration?: boolean; acceleration?: boolean;
acceleratedBy?: number[]; acceleratedBy?: number[];
acceleratedAt?: number;
replacement?: boolean; replacement?: boolean;
uid?: number; uid?: number;
flags?: number; flags?: number;
@ -434,7 +435,7 @@ export interface OptimizedStatistic {
export interface TxTrackingInfo { export interface TxTrackingInfo {
replacedBy?: string, replacedBy?: string,
position?: { block: number, vsize: number, accelerated?: boolean, acceleratedBy?: number[] }, position?: { block: number, vsize: number, accelerated?: boolean, acceleratedBy?: number[], acceleratedAt?: number },
cpfp?: { cpfp?: {
ancestors?: Ancestor[], ancestors?: Ancestor[],
bestDescendant?: Ancestor | null, bestDescendant?: Ancestor | null,
@ -446,6 +447,7 @@ export interface TxTrackingInfo {
utxoSpent?: { [vout: number]: { vin: number, txid: string } }, utxoSpent?: { [vout: number]: { vin: number, txid: string } },
accelerated?: boolean, accelerated?: boolean,
acceleratedBy?: number[], acceleratedBy?: number[],
acceleratedAt?: number,
confirmed?: boolean confirmed?: boolean
} }

View File

@ -51,6 +51,7 @@ interface AuditStatus {
accelerated?: boolean; accelerated?: boolean;
conflict?: boolean; conflict?: boolean;
coinbase?: boolean; coinbase?: boolean;
firstSeen?: number;
} }
@Component({ @Component({
@ -325,7 +326,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
const boostCost = acceleration.boostCost || acceleration.bidBoost; const boostCost = acceleration.boostCost || acceleration.bidBoost;
acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize; acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize;
acceleration.boost = boostCost; acceleration.boost = boostCost;
this.tx.acceleratedAt = acceleration.added;
this.accelerationInfo = acceleration; this.accelerationInfo = acceleration;
this.setIsAccelerated(); this.setIsAccelerated();
} }
@ -368,6 +369,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
const isAccelerated = audit.acceleratedTxs.includes(txid); const isAccelerated = audit.acceleratedTxs.includes(txid);
const isConflict = audit.fullrbfTxs.includes(txid); const isConflict = audit.fullrbfTxs.includes(txid);
const isExpected = audit.template.some(tx => tx.txid === txid); const isExpected = audit.template.some(tx => tx.txid === txid);
const firstSeen = audit.template.find(tx => tx.txid === txid)?.time;
return { return {
seen: isExpected || isPrioritized || isAccelerated, seen: isExpected || isPrioritized || isAccelerated,
expected: isExpected, expected: isExpected,
@ -375,6 +377,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
prioritized: isPrioritized, prioritized: isPrioritized,
conflict: isConflict, conflict: isConflict,
accelerated: isAccelerated, accelerated: isAccelerated,
firstSeen,
}; };
}), }),
retry({ count: 3, delay: 2000 }), retry({ count: 3, delay: 2000 }),
@ -388,6 +391,9 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
}) })
).subscribe(auditStatus => { ).subscribe(auditStatus => {
this.auditStatus = auditStatus; this.auditStatus = auditStatus;
if (this.auditStatus?.firstSeen) {
this.transactionTime = this.auditStatus.firstSeen;
}
this.setIsAccelerated(); this.setIsAccelerated();
}); });
@ -771,6 +777,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
if (cpfpInfo.acceleration) { if (cpfpInfo.acceleration) {
this.tx.acceleration = cpfpInfo.acceleration; this.tx.acceleration = cpfpInfo.acceleration;
this.tx.acceleratedBy = cpfpInfo.acceleratedBy; this.tx.acceleratedBy = cpfpInfo.acceleratedBy;
this.tx.acceleratedAt = cpfpInfo.acceleratedAt;
this.setIsAccelerated(firstCpfp); this.setIsAccelerated(firstCpfp);
} }

View File

@ -21,6 +21,7 @@ export interface Transaction {
cpfpChecked?: boolean; cpfpChecked?: boolean;
acceleration?: boolean; acceleration?: boolean;
acceleratedBy?: number[]; acceleratedBy?: number[];
acceleratedAt?: number;
deleteAfter?: number; deleteAfter?: number;
_unblinded?: any; _unblinded?: any;
_deduced?: boolean; _deduced?: boolean;

View File

@ -30,6 +30,7 @@ export interface CpfpInfo {
adjustedVsize?: number; adjustedVsize?: number;
acceleration?: boolean; acceleration?: boolean;
acceleratedBy?: number[]; acceleratedBy?: number[];
acceleratedAt?: number;
} }
export interface RbfInfo { export interface RbfInfo {