use accelerated rates for block templates & show in viz
This commit is contained in:
parent
e489f713eb
commit
aa24f6a84d
@ -6,7 +6,7 @@ import rbfCache from './rbf-cache';
|
|||||||
const PROPAGATION_MARGIN = 180; // in seconds, time since a transaction is first seen after which it is assumed to have propagated to all miners
|
const PROPAGATION_MARGIN = 180; // in seconds, time since a transaction is first seen after which it is assumed to have propagated to all miners
|
||||||
|
|
||||||
class Audit {
|
class Audit {
|
||||||
auditBlock(transactions: MempoolTransactionExtended[], projectedBlocks: MempoolBlockWithTransactions[], mempool: { [txId: string]: MempoolTransactionExtended }, accelerations: { [txid: string]: number })
|
auditBlock(transactions: MempoolTransactionExtended[], projectedBlocks: MempoolBlockWithTransactions[], mempool: { [txId: string]: MempoolTransactionExtended })
|
||||||
: { censored: string[], added: string[], fresh: string[], sigop: string[], fullrbf: string[], accelerated: string[], score: number, similarity: number } {
|
: { censored: string[], added: string[], fresh: string[], sigop: string[], fullrbf: string[], accelerated: string[], score: number, similarity: number } {
|
||||||
if (!projectedBlocks?.[0]?.transactionIds || !mempool) {
|
if (!projectedBlocks?.[0]?.transactionIds || !mempool) {
|
||||||
return { censored: [], added: [], fresh: [], sigop: [], fullrbf: [], accelerated: [], score: 0, similarity: 1 };
|
return { censored: [], added: [], fresh: [], sigop: [], fullrbf: [], accelerated: [], score: 0, similarity: 1 };
|
||||||
@ -29,7 +29,7 @@ class Audit {
|
|||||||
const now = Math.round((Date.now() / 1000));
|
const now = Math.round((Date.now() / 1000));
|
||||||
for (const tx of transactions) {
|
for (const tx of transactions) {
|
||||||
inBlock[tx.txid] = tx;
|
inBlock[tx.txid] = tx;
|
||||||
if (accelerations[tx.txid]) {
|
if (tx.acceleration) {
|
||||||
accelerated.push(tx.txid);
|
accelerated.push(tx.txid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,6 +214,7 @@ class BitcoinRoutes {
|
|||||||
effectiveFeePerVsize: tx.effectiveFeePerVsize || null,
|
effectiveFeePerVsize: tx.effectiveFeePerVsize || null,
|
||||||
sigops: tx.sigops,
|
sigops: tx.sigops,
|
||||||
adjustedVsize: tx.adjustedVsize,
|
adjustedVsize: tx.adjustedVsize,
|
||||||
|
acceleration: tx.acceleration
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -111,6 +111,7 @@ export class Common {
|
|||||||
fee: tx.fee,
|
fee: tx.fee,
|
||||||
vsize: tx.weight / 4,
|
vsize: tx.weight / 4,
|
||||||
value: tx.vout.reduce((acc, vout) => acc + (vout.value ? vout.value : 0), 0),
|
value: tx.vout.reduce((acc, vout) => acc + (vout.value ? vout.value : 0), 0),
|
||||||
|
acc: tx.acceleration || undefined,
|
||||||
rate: tx.effectiveFeePerVsize,
|
rate: tx.effectiveFeePerVsize,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ class MempoolBlocks {
|
|||||||
for (let i = 0; i < Math.max(mempoolBlocks.length, prevBlocks.length); i++) {
|
for (let i = 0; i < Math.max(mempoolBlocks.length, prevBlocks.length); i++) {
|
||||||
let added: TransactionStripped[] = [];
|
let added: TransactionStripped[] = [];
|
||||||
let removed: string[] = [];
|
let removed: string[] = [];
|
||||||
const changed: { txid: string, rate: number | undefined }[] = [];
|
const changed: { txid: string, rate: number | undefined, acc: number | undefined }[] = [];
|
||||||
if (mempoolBlocks[i] && !prevBlocks[i]) {
|
if (mempoolBlocks[i] && !prevBlocks[i]) {
|
||||||
added = mempoolBlocks[i].transactions;
|
added = mempoolBlocks[i].transactions;
|
||||||
} else if (!mempoolBlocks[i] && prevBlocks[i]) {
|
} else if (!mempoolBlocks[i] && prevBlocks[i]) {
|
||||||
@ -192,8 +192,8 @@ class MempoolBlocks {
|
|||||||
mempoolBlocks[i].transactions.forEach(tx => {
|
mempoolBlocks[i].transactions.forEach(tx => {
|
||||||
if (!prevIds[tx.txid]) {
|
if (!prevIds[tx.txid]) {
|
||||||
added.push(tx);
|
added.push(tx);
|
||||||
} else if (tx.rate !== prevIds[tx.txid].rate) {
|
} else if (tx.rate !== prevIds[tx.txid].rate || tx.acc !== prevIds[tx.txid].acc) {
|
||||||
changed.push({ txid: tx.txid, rate: tx.rate });
|
changed.push({ txid: tx.txid, rate: tx.rate, acc: tx.acc });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -206,7 +206,7 @@ class MempoolBlocks {
|
|||||||
return mempoolBlockDeltas;
|
return mempoolBlockDeltas;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $makeBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, saveResults: boolean = false, accelerations: { [txid: string]: number } = {}): Promise<MempoolBlockWithTransactions[]> {
|
public async $makeBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, saveResults: boolean = false): Promise<MempoolBlockWithTransactions[]> {
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
|
||||||
// reset mempool short ids
|
// reset mempool short ids
|
||||||
@ -222,7 +222,7 @@ class MempoolBlocks {
|
|||||||
if (entry.uid !== null && entry.uid !== undefined) {
|
if (entry.uid !== null && entry.uid !== undefined) {
|
||||||
const stripped = {
|
const stripped = {
|
||||||
uid: entry.uid,
|
uid: entry.uid,
|
||||||
fee: entry.fee,
|
fee: entry.fee + (entry.acceleration || 0),
|
||||||
weight: (entry.adjustedVsize * 4),
|
weight: (entry.adjustedVsize * 4),
|
||||||
sigops: entry.sigops,
|
sigops: entry.sigops,
|
||||||
feePerVsize: entry.adjustedFeePerVsize || entry.feePerVsize,
|
feePerVsize: entry.adjustedFeePerVsize || entry.feePerVsize,
|
||||||
@ -285,13 +285,14 @@ class MempoolBlocks {
|
|||||||
for (const tx of Object.values(added)) {
|
for (const tx of Object.values(added)) {
|
||||||
this.setUid(tx, true);
|
this.setUid(tx, true);
|
||||||
}
|
}
|
||||||
const removedUids = removed.map(tx => this.getUid(tx)).filter(uid => (uid !== null && uid !== undefined)) as number[];
|
|
||||||
|
const removedUids = removed.map(tx => this.getUid(tx)).filter(uid => uid != null) as number[];
|
||||||
// prepare a stripped down version of the mempool with only the minimum necessary data
|
// prepare a stripped down version of the mempool with only the minimum necessary data
|
||||||
// to reduce the overhead of passing this data to the worker thread
|
// to reduce the overhead of passing this data to the worker thread
|
||||||
const addedStripped: CompactThreadTransaction[] = added.filter(entry => (entry.uid !== null && entry.uid !== undefined)).map(entry => {
|
const addedStripped: CompactThreadTransaction[] = added.filter(entry => (entry.uid !== null && entry.uid !== undefined)).map(entry => {
|
||||||
return {
|
return {
|
||||||
uid: entry.uid || 0,
|
uid: entry.uid || 0,
|
||||||
fee: entry.fee,
|
fee: entry.fee + (entry.acceleration || 0),
|
||||||
weight: (entry.adjustedVsize * 4),
|
weight: (entry.adjustedVsize * 4),
|
||||||
sigops: entry.sigops,
|
sigops: entry.sigops,
|
||||||
feePerVsize: entry.adjustedFeePerVsize || entry.feePerVsize,
|
feePerVsize: entry.adjustedFeePerVsize || entry.feePerVsize,
|
||||||
|
@ -23,6 +23,8 @@ class Mempool {
|
|||||||
private $asyncMempoolChangedCallback: ((newMempool: {[txId: string]: MempoolTransactionExtended; }, mempoolSize: number, newTransactions: MempoolTransactionExtended[],
|
private $asyncMempoolChangedCallback: ((newMempool: {[txId: string]: MempoolTransactionExtended; }, mempoolSize: number, newTransactions: MempoolTransactionExtended[],
|
||||||
deletedTransactions: MempoolTransactionExtended[]) => Promise<void>) | undefined;
|
deletedTransactions: MempoolTransactionExtended[]) => Promise<void>) | undefined;
|
||||||
|
|
||||||
|
private accelerations: { [txId: string]: number } = {};
|
||||||
|
|
||||||
private txPerSecondArray: number[] = [];
|
private txPerSecondArray: number[] = [];
|
||||||
private txPerSecond: number = 0;
|
private txPerSecond: number = 0;
|
||||||
|
|
||||||
@ -301,6 +303,17 @@ class Mempool {
|
|||||||
const newTransactionsStripped = newTransactions.map((tx) => Common.stripTransaction(tx));
|
const newTransactionsStripped = newTransactions.map((tx) => Common.stripTransaction(tx));
|
||||||
this.latestTransactions = newTransactionsStripped.concat(this.latestTransactions).slice(0, 6);
|
this.latestTransactions = newTransactionsStripped.concat(this.latestTransactions).slice(0, 6);
|
||||||
|
|
||||||
|
const newAccelerations: { txid: string, delta: number }[] = [];
|
||||||
|
newTransactions.forEach(tx => {
|
||||||
|
if (tx.txid.startsWith('00')) {
|
||||||
|
const delta = Math.floor(Math.random() * 100000) + 100000;
|
||||||
|
newAccelerations.push({ txid: tx.txid, delta });
|
||||||
|
tx.acceleration = delta;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.addAccelerations(newAccelerations);
|
||||||
|
this.removeAccelerations(deletedTransactions.map(tx => tx.txid));
|
||||||
|
|
||||||
this.mempoolCacheDelta = Math.abs(transactions.length - newMempoolSize);
|
this.mempoolCacheDelta = Math.abs(transactions.length - newMempoolSize);
|
||||||
|
|
||||||
if (this.mempoolChangedCallback && (hasChange || deletedTransactions.length)) {
|
if (this.mempoolChangedCallback && (hasChange || deletedTransactions.length)) {
|
||||||
@ -325,6 +338,22 @@ class Mempool {
|
|||||||
this.clearTimer(timer);
|
this.clearTimer(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getAccelerations(): { [txid: string]: number } {
|
||||||
|
return this.accelerations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addAccelerations(newAccelerations: { txid: string, delta: number }[]): void {
|
||||||
|
for (const acceleration of newAccelerations) {
|
||||||
|
this.accelerations[acceleration.txid] = acceleration.delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeAccelerations(txids: string[]): void {
|
||||||
|
for (const txid of txids) {
|
||||||
|
delete this.accelerations[txid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private startTimer() {
|
private startTimer() {
|
||||||
const state: any = {
|
const state: any = {
|
||||||
start: Date.now(),
|
start: Date.now(),
|
||||||
|
@ -21,6 +21,7 @@ import Audit from './audit';
|
|||||||
import { deepClone } from '../utils/clone';
|
import { deepClone } from '../utils/clone';
|
||||||
import priceUpdater from '../tasks/price-updater';
|
import priceUpdater from '../tasks/price-updater';
|
||||||
import { ApiPrice } from '../repositories/PricesRepository';
|
import { ApiPrice } from '../repositories/PricesRepository';
|
||||||
|
import mempool from './mempool';
|
||||||
|
|
||||||
// valid 'want' subscriptions
|
// valid 'want' subscriptions
|
||||||
const wantable = [
|
const wantable = [
|
||||||
@ -666,7 +667,7 @@ class WebsocketHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Common.indexingEnabled()) {
|
if (Common.indexingEnabled()) {
|
||||||
const { censored, added, fresh, sigop, fullrbf, accelerated, score, similarity } = Audit.auditBlock(transactions, projectedBlocks, auditMempool, accelerations);
|
const { censored, added, fresh, sigop, fullrbf, accelerated, score, similarity } = Audit.auditBlock(transactions, projectedBlocks, auditMempool);
|
||||||
const matchRate = Math.round(score * 100 * 100) / 100;
|
const matchRate = Math.round(score * 100 * 100) / 100;
|
||||||
|
|
||||||
const stripped = projectedBlocks[0]?.transactions ? projectedBlocks[0].transactions : [];
|
const stripped = projectedBlocks[0]?.transactions ? projectedBlocks[0].transactions : [];
|
||||||
@ -737,6 +738,8 @@ class WebsocketHandler {
|
|||||||
const fees = feeApi.getRecommendedFee();
|
const fees = feeApi.getRecommendedFee();
|
||||||
const mempoolInfo = memPool.getMempoolInfo();
|
const mempoolInfo = memPool.getMempoolInfo();
|
||||||
|
|
||||||
|
memPool.removeAccelerations(txIds);
|
||||||
|
|
||||||
// update init data
|
// update init data
|
||||||
this.updateSocketDataFields({
|
this.updateSocketDataFields({
|
||||||
'mempoolInfo': mempoolInfo,
|
'mempoolInfo': mempoolInfo,
|
||||||
|
@ -92,6 +92,7 @@ export interface TransactionExtended extends IEsploraApi.Transaction {
|
|||||||
block: number,
|
block: number,
|
||||||
vsize: number,
|
vsize: number,
|
||||||
};
|
};
|
||||||
|
acceleration?: number;
|
||||||
uid?: number;
|
uid?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,6 +184,7 @@ export interface TransactionStripped {
|
|||||||
fee: number;
|
fee: number;
|
||||||
vsize: number;
|
vsize: number;
|
||||||
value: number;
|
value: number;
|
||||||
|
acc?: number;
|
||||||
rate?: number; // effective fee rate
|
rate?: number; // effective fee rate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update(add: TransactionStripped[], remove: string[], change: { txid: string, rate: number | undefined }[], direction: string = 'left', resetLayout: boolean = false): void {
|
update(add: TransactionStripped[], remove: string[], change: { txid: string, rate: number | undefined, acc: number | undefined }[], direction: string = 'left', resetLayout: boolean = false): void {
|
||||||
if (this.scene) {
|
if (this.scene) {
|
||||||
this.scene.update(add, remove, change, direction, resetLayout);
|
this.scene.update(add, remove, change, direction, resetLayout);
|
||||||
this.start();
|
this.start();
|
||||||
|
@ -150,7 +150,7 @@ export default class BlockScene {
|
|||||||
this.updateAll(startTime, 200, direction);
|
this.updateAll(startTime, 200, direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
update(add: TransactionStripped[], remove: string[], change: { txid: string, rate: number | undefined }[], direction: string = 'left', resetLayout: boolean = false): void {
|
update(add: TransactionStripped[], remove: string[], change: { txid: string, rate: number | undefined, acc: number | undefined }[], direction: string = 'left', resetLayout: boolean = false): void {
|
||||||
const startTime = performance.now();
|
const startTime = performance.now();
|
||||||
const removed = this.removeBatch(remove, startTime, direction);
|
const removed = this.removeBatch(remove, startTime, direction);
|
||||||
|
|
||||||
@ -175,6 +175,7 @@ export default class BlockScene {
|
|||||||
// update effective rates
|
// update effective rates
|
||||||
change.forEach(tx => {
|
change.forEach(tx => {
|
||||||
if (this.txs[tx.txid]) {
|
if (this.txs[tx.txid]) {
|
||||||
|
this.txs[tx.txid].acc = tx.acc;
|
||||||
this.txs[tx.txid].feerate = tx.rate || (this.txs[tx.txid].fee / this.txs[tx.txid].vsize);
|
this.txs[tx.txid].feerate = tx.rate || (this.txs[tx.txid].fee / this.txs[tx.txid].vsize);
|
||||||
this.txs[tx.txid].rate = tx.rate;
|
this.txs[tx.txid].rate = tx.rate;
|
||||||
this.txs[tx.txid].dirty = true;
|
this.txs[tx.txid].dirty = true;
|
||||||
|
@ -38,6 +38,7 @@ export default class TxView implements TransactionStripped {
|
|||||||
vsize: number;
|
vsize: number;
|
||||||
value: number;
|
value: number;
|
||||||
feerate: number;
|
feerate: number;
|
||||||
|
acc?: number;
|
||||||
rate?: number;
|
rate?: number;
|
||||||
status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'censored' | 'selected' | 'rbf' | 'accelerated';
|
status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'censored' | 'selected' | 'rbf' | 'accelerated';
|
||||||
context?: 'projected' | 'actual';
|
context?: 'projected' | 'actual';
|
||||||
@ -64,6 +65,7 @@ export default class TxView implements TransactionStripped {
|
|||||||
this.vsize = tx.vsize;
|
this.vsize = tx.vsize;
|
||||||
this.value = tx.value;
|
this.value = tx.value;
|
||||||
this.feerate = tx.rate || (tx.fee / tx.vsize); // sort by effective fee rate where available
|
this.feerate = tx.rate || (tx.fee / tx.vsize); // sort by effective fee rate where available
|
||||||
|
this.acc = tx.acc;
|
||||||
this.rate = tx.rate;
|
this.rate = tx.rate;
|
||||||
this.status = tx.status;
|
this.status = tx.status;
|
||||||
this.initialised = false;
|
this.initialised = false;
|
||||||
@ -200,6 +202,11 @@ export default class TxView implements TransactionStripped {
|
|||||||
const feeLevelColor = feeColors[feeLevelIndex] || feeColors[mempoolFeeColors.length - 1];
|
const feeLevelColor = feeColors[feeLevelIndex] || feeColors[mempoolFeeColors.length - 1];
|
||||||
// Normal mode
|
// Normal mode
|
||||||
if (!this.scene?.highlightingEnabled) {
|
if (!this.scene?.highlightingEnabled) {
|
||||||
|
if (this.acc) {
|
||||||
|
return auditColors.accelerated;
|
||||||
|
} else {
|
||||||
|
return feeLevelColor;
|
||||||
|
}
|
||||||
return feeLevelColor;
|
return feeLevelColor;
|
||||||
}
|
}
|
||||||
// Block audit
|
// Block audit
|
||||||
@ -226,7 +233,11 @@ export default class TxView implements TransactionStripped {
|
|||||||
return feeLevelColor;
|
return feeLevelColor;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return feeLevelColor;
|
if (this.acc) {
|
||||||
|
return auditColors.accelerated;
|
||||||
|
} else {
|
||||||
|
return feeLevelColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,8 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngIf="effectiveRate && effectiveRate !== feeRate">
|
<tr *ngIf="effectiveRate && effectiveRate !== feeRate">
|
||||||
<td class="td-width" i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
|
<td *ngIf="!this.acceleration" class="td-width" i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
|
||||||
|
<td *ngIf="this.acceleration" class="td-width" i18n="transaction.effective-fee-rate|Effective transaction fee rate">Accelerated fee rate</td>
|
||||||
<td>
|
<td>
|
||||||
<app-fee-rate [fee]="effectiveRate"></app-fee-rate>
|
<app-fee-rate [fee]="effectiveRate"></app-fee-rate>
|
||||||
</td>
|
</td>
|
||||||
|
@ -21,6 +21,7 @@ export class BlockOverviewTooltipComponent implements OnChanges {
|
|||||||
vsize = 1;
|
vsize = 1;
|
||||||
feeRate = 0;
|
feeRate = 0;
|
||||||
effectiveRate;
|
effectiveRate;
|
||||||
|
acceleration;
|
||||||
|
|
||||||
tooltipPosition: Position = { x: 0, y: 0 };
|
tooltipPosition: Position = { x: 0, y: 0 };
|
||||||
|
|
||||||
@ -53,6 +54,7 @@ export class BlockOverviewTooltipComponent implements OnChanges {
|
|||||||
this.vsize = tx.vsize || 1;
|
this.vsize = tx.vsize || 1;
|
||||||
this.feeRate = this.fee / this.vsize;
|
this.feeRate = this.fee / this.vsize;
|
||||||
this.effectiveRate = tx.rate;
|
this.effectiveRate = tx.rate;
|
||||||
|
this.acceleration = tx.acc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,6 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
|
|||||||
|
|
||||||
updateBlock(delta: MempoolBlockDelta): void {
|
updateBlock(delta: MempoolBlockDelta): void {
|
||||||
const blockMined = (this.stateService.latestBlockHeight > this.lastBlockHeight);
|
const blockMined = (this.stateService.latestBlockHeight > this.lastBlockHeight);
|
||||||
|
|
||||||
if (this.blockIndex !== this.index) {
|
if (this.blockIndex !== this.index) {
|
||||||
const direction = (this.blockIndex == null || this.index < this.blockIndex) ? this.poolDirection : this.chainDirection;
|
const direction = (this.blockIndex == null || this.index < this.blockIndex) ? this.poolDirection : this.chainDirection;
|
||||||
this.blockGraph.replace(delta.added, direction);
|
this.blockGraph.replace(delta.added, direction);
|
||||||
|
@ -488,7 +488,8 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr *ngIf="cpfpInfo && hasEffectiveFeeRate">
|
<tr *ngIf="cpfpInfo && hasEffectiveFeeRate">
|
||||||
<td i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
|
<td *ngIf="cpfpInfo.acceleration" i18n="transaction.effective-fee-rate|Effective transaction fee rate">Accelerated fee rate</td>
|
||||||
|
<td *ngIf="!cpfpInfo.acceleration" i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="effective-fee-container">
|
<div class="effective-fee-container">
|
||||||
<app-fee-rate [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
|
<app-fee-rate [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
|
||||||
|
@ -183,6 +183,9 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
|
|||||||
} else {
|
} else {
|
||||||
this.tx.effectiveFeePerVsize = cpfpInfo.effectiveFeePerVsize;
|
this.tx.effectiveFeePerVsize = cpfpInfo.effectiveFeePerVsize;
|
||||||
}
|
}
|
||||||
|
if (cpfpInfo.acceleration) {
|
||||||
|
this.tx.acceleration = cpfpInfo.acceleration;
|
||||||
|
}
|
||||||
|
|
||||||
this.cpfpInfo = cpfpInfo;
|
this.cpfpInfo = cpfpInfo;
|
||||||
this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01));
|
this.hasEffectiveFeeRate = hasRelatives || (this.tx.effectiveFeePerVsize && (Math.abs(this.tx.effectiveFeePerVsize - this.tx.feePerVsize) > 0.01));
|
||||||
|
@ -19,6 +19,7 @@ export interface Transaction {
|
|||||||
ancestors?: Ancestor[];
|
ancestors?: Ancestor[];
|
||||||
bestDescendant?: BestDescendant | null;
|
bestDescendant?: BestDescendant | null;
|
||||||
cpfpChecked?: boolean;
|
cpfpChecked?: boolean;
|
||||||
|
acceleration?: number;
|
||||||
deleteAfter?: number;
|
deleteAfter?: number;
|
||||||
_unblinded?: any;
|
_unblinded?: any;
|
||||||
_deduced?: boolean;
|
_deduced?: boolean;
|
||||||
|
@ -27,6 +27,7 @@ export interface CpfpInfo {
|
|||||||
effectiveFeePerVsize?: number;
|
effectiveFeePerVsize?: number;
|
||||||
sigops?: number;
|
sigops?: number;
|
||||||
adjustedVsize?: number;
|
adjustedVsize?: number;
|
||||||
|
acceleration?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RbfInfo {
|
export interface RbfInfo {
|
||||||
|
@ -70,7 +70,7 @@ export interface MempoolBlockWithTransactions extends MempoolBlock {
|
|||||||
export interface MempoolBlockDelta {
|
export interface MempoolBlockDelta {
|
||||||
added: TransactionStripped[],
|
added: TransactionStripped[],
|
||||||
removed: string[],
|
removed: string[],
|
||||||
changed?: { txid: string, rate: number | undefined }[];
|
changed?: { txid: string, rate: number | undefined, acc: number | undefined }[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MempoolInfo {
|
export interface MempoolInfo {
|
||||||
@ -88,6 +88,7 @@ export interface TransactionStripped {
|
|||||||
fee: number;
|
fee: number;
|
||||||
vsize: number;
|
vsize: number;
|
||||||
value: number;
|
value: number;
|
||||||
|
acc?: number; // acceleration delta
|
||||||
rate?: number; // effective fee rate
|
rate?: number; // effective fee rate
|
||||||
status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'censored' | 'selected' | 'rbf' | 'accelerated';
|
status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'censored' | 'selected' | 'rbf' | 'accelerated';
|
||||||
context?: 'projected' | 'actual';
|
context?: 'projected' | 'actual';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user