include per-tx pools in /accelerations endpoint

This commit is contained in:
Mononaut 2023-06-13 17:03:36 -04:00
parent ba54bc9d15
commit 6494f890fe
No known key found for this signature in database
GPG Key ID: A3F058E41374C04E
4 changed files with 42 additions and 27 deletions

View File

@ -1,6 +1,6 @@
import { GbtGenerator, GbtResult, ThreadTransaction as RustThreadTransaction } from '../../rust-gbt'; import { GbtGenerator, GbtResult, ThreadTransaction as RustThreadTransaction } from '../../rust-gbt';
import logger from '../logger'; import logger from '../logger';
import { MempoolBlock, MempoolTransactionExtended, TransactionStripped, MempoolBlockWithTransactions, MempoolBlockDelta, Ancestor, CompactThreadTransaction, EffectiveFeeStats } from '../mempool.interfaces'; import { MempoolBlock, MempoolTransactionExtended, TransactionStripped, MempoolBlockWithTransactions, MempoolBlockDelta, Ancestor, CompactThreadTransaction, EffectiveFeeStats, PoolTag } from '../mempool.interfaces';
import { Common, OnlineFeeStatsCalculator } from './common'; import { Common, OnlineFeeStatsCalculator } from './common';
import config from '../config'; import config from '../config';
import { Worker } from 'worker_threads'; import { Worker } from 'worker_threads';
@ -207,7 +207,7 @@ class MempoolBlocks {
return mempoolBlockDeltas; return mempoolBlockDeltas;
} }
public async $makeBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, saveResults: boolean = false, useAccelerations: boolean = false): Promise<MempoolBlockWithTransactions[]> { public async $makeBlockTemplates(newMempool: { [txid: string]: MempoolTransactionExtended }, saveResults: boolean = false, useAccelerations: boolean = false, accelerationPool?: number): Promise<MempoolBlockWithTransactions[]> {
const start = Date.now(); const start = Date.now();
// reset mempool short ids // reset mempool short ids
@ -225,7 +225,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 + (useAccelerations ? (accelerations[entry.txid] || 0) : 0), fee: entry.fee + (useAccelerations && (!accelerationPool || accelerations[entry.txid]?.pools?.includes(accelerationPool)) ? (accelerations[entry.txid]?.feeDelta || 0) : 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,
@ -298,7 +298,7 @@ class MempoolBlocks {
const addedStripped: CompactThreadTransaction[] = addedAndChanged.filter(entry => entry.uid != null).map(entry => { const addedStripped: CompactThreadTransaction[] = addedAndChanged.filter(entry => entry.uid != null).map(entry => {
return { return {
uid: entry.uid || 0, uid: entry.uid || 0,
fee: entry.fee + (useAccelerations ? (accelerations[entry.txid] || 0) : 0), fee: entry.fee + (useAccelerations ? (accelerations[entry.txid]?.feeDelta || 0) : 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,

View File

@ -23,7 +23,7 @@ class Mempool {
private $asyncMempoolChangedCallback: ((newMempool: {[txId: string]: MempoolTransactionExtended; }, mempoolSize: number, newTransactions: MempoolTransactionExtended[], private $asyncMempoolChangedCallback: ((newMempool: {[txId: string]: MempoolTransactionExtended; }, mempoolSize: number, newTransactions: MempoolTransactionExtended[],
deletedTransactions: MempoolTransactionExtended[], accelerationDelta: string[]) => Promise<void>) | undefined; deletedTransactions: MempoolTransactionExtended[], accelerationDelta: string[]) => Promise<void>) | undefined;
private accelerations: { [txId: string]: number } = {}; private accelerations: { [txId: string]: Acceleration } = {};
private txPerSecondArray: number[] = []; private txPerSecondArray: number[] = [];
private txPerSecond: number = 0; private txPerSecond: number = 0;
@ -332,7 +332,7 @@ class Mempool {
this.clearTimer(timer); this.clearTimer(timer);
} }
public getAccelerations(): { [txid: string]: number } { public getAccelerations(): { [txid: string]: Acceleration } {
return this.accelerations; return this.accelerations;
} }
@ -346,15 +346,37 @@ class Mempool {
const changed: string[] = []; const changed: string[] = [];
const newAccelerationMap: { [txid: string]: number } = {}; const newAccelerationMap: { [txid: string]: Acceleration } = {};
for (const acceleration of newAccelerations) { for (const acceleration of newAccelerations) {
newAccelerationMap[acceleration.txid] = acceleration.feeDelta; newAccelerationMap[acceleration.txid] = acceleration;
if (this.accelerations[acceleration.txid] == null) { if (this.accelerations[acceleration.txid] == null) {
// new acceleration // new acceleration
changed.push(acceleration.txid); changed.push(acceleration.txid);
} else if (this.accelerations[acceleration.txid] !== acceleration.feeDelta) { } else {
// feeDelta changed if (this.accelerations[acceleration.txid].feeDelta !== acceleration.feeDelta) {
changed.push(acceleration.txid); // feeDelta changed
changed.push(acceleration.txid);
} else if (this.accelerations[acceleration.txid].pools?.length) {
let poolsChanged = false;
const pools = new Set();
this.accelerations[acceleration.txid].pools.forEach(pool => {
pools.add(pool);
});
acceleration.pools.forEach(pool => {
if (!pools.has(pool)) {
poolsChanged = true;
} else {
pools.delete(pool);
}
});
if (pools.size > 0) {
poolsChanged = true;
}
if (poolsChanged) {
// pools changed
changed.push(acceleration.txid);
}
}
} }
} }

View File

@ -5,6 +5,7 @@ import { BlockExtended, PoolTag } from '../../mempool.interfaces';
export interface Acceleration { export interface Acceleration {
txid: string, txid: string,
feeDelta: number, feeDelta: number,
pools: number[],
} }
class AccelerationApi { class AccelerationApi {
@ -17,21 +18,12 @@ class AccelerationApi {
} }
} }
public async $fetchPools(): Promise<PoolTag[]> { public isAcceleratedBlock(block: BlockExtended, accelerations: Acceleration[]): boolean {
if (config.MEMPOOL_SERVICES.ACCELERATIONS) { let anyAccelerated = false;
const response = await query(`${config.MEMPOOL_SERVICES.API}/partners`); for (let i = 0; i < accelerations.length && !anyAccelerated; i++) {
return (response as PoolTag[]) || []; anyAccelerated = anyAccelerated || accelerations[i].pools?.includes(block.extras.pool.id);
} else {
return [];
} }
} return anyAccelerated;
public async $isAcceleratedBlock(block: BlockExtended): Promise<boolean> {
const pools = await this.$fetchPools();
if (block?.extras?.pool?.id == null) {
return false;
}
return pools.reduce((match, tag) => match || tag.uniqueId === block.extras.pool.id, false);
} }
} }

View File

@ -22,6 +22,7 @@ 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 accelerationApi from './services/acceleration'; import accelerationApi from './services/acceleration';
import mempool from './mempool';
// valid 'want' subscriptions // valid 'want' subscriptions
const wantable = [ const wantable = [
@ -657,7 +658,7 @@ class WebsocketHandler {
if (config.MEMPOOL.AUDIT && memPool.isInSync()) { if (config.MEMPOOL.AUDIT && memPool.isInSync()) {
let projectedBlocks; let projectedBlocks;
let auditMempool = _memPool; let auditMempool = _memPool;
const isAccelerated = config.MEMPOOL_SERVICES.ACCELERATIONS && await accelerationApi.$isAcceleratedBlock(block); const isAccelerated = config.MEMPOOL_SERVICES.ACCELERATIONS && accelerationApi.isAcceleratedBlock(block, Object.values(mempool.getAccelerations()));
// template calculation functions have mempool side effects, so calculate audits using // template calculation functions have mempool side effects, so calculate audits using
// a cloned copy of the mempool if we're running a different algorithm for mempool updates // a cloned copy of the mempool if we're running a different algorithm for mempool updates
const separateAudit = config.MEMPOOL.ADVANCED_GBT_AUDIT !== config.MEMPOOL.ADVANCED_GBT_MEMPOOL; const separateAudit = config.MEMPOOL.ADVANCED_GBT_AUDIT !== config.MEMPOOL.ADVANCED_GBT_MEMPOOL;
@ -667,7 +668,7 @@ class WebsocketHandler {
if (config.MEMPOOL.RUST_GBT) { if (config.MEMPOOL.RUST_GBT) {
projectedBlocks = await mempoolBlocks.$oneOffRustBlockTemplates(auditMempool); projectedBlocks = await mempoolBlocks.$oneOffRustBlockTemplates(auditMempool);
} else { } else {
projectedBlocks = await mempoolBlocks.$makeBlockTemplates(auditMempool, false, isAccelerated); projectedBlocks = await mempoolBlocks.$makeBlockTemplates(auditMempool, false, isAccelerated, block.extras.pool.id);
} }
} else { } else {
projectedBlocks = mempoolBlocks.updateMempoolBlocks(auditMempool, false); projectedBlocks = mempoolBlocks.updateMempoolBlocks(auditMempool, false);