Merge branch 'master' into mononaut/hide-arrow-on-replace
This commit is contained in:
@@ -478,7 +478,7 @@ class BitcoinRoutes {
|
||||
}
|
||||
|
||||
let nextHash = startFromHash;
|
||||
for (let i = 0; i < 10 && nextHash; i++) {
|
||||
for (let i = 0; i < 15 && nextHash; i++) {
|
||||
const localBlock = blocks.getBlocks().find((b) => b.id === nextHash);
|
||||
if (localBlock) {
|
||||
returnBlocks.push(localBlock);
|
||||
|
||||
@@ -75,9 +75,9 @@ class FailoverRouter {
|
||||
|
||||
const results = await Promise.allSettled(this.hosts.map(async (host) => {
|
||||
if (host.socket) {
|
||||
return this.pollConnection.get<number>('/blocks/tip/height', { socketPath: host.host, timeout: 5000 });
|
||||
return this.pollConnection.get<number>('/blocks/tip/height', { socketPath: host.host, timeout: config.ESPLORA.FALLBACK_TIMEOUT });
|
||||
} else {
|
||||
return this.pollConnection.get<number>(host.host + '/blocks/tip/height', { timeout: 5000 });
|
||||
return this.pollConnection.get<number>(host.host + '/blocks/tip/height', { timeout: config.ESPLORA.FALLBACK_TIMEOUT });
|
||||
}
|
||||
}));
|
||||
const maxHeight = results.reduce((max, result) => Math.max(max, result.status === 'fulfilled' ? result.value?.data || 0 : 0), 0);
|
||||
@@ -168,10 +168,10 @@ class FailoverRouter {
|
||||
let axiosConfig;
|
||||
let url;
|
||||
if (host.socket) {
|
||||
axiosConfig = { socketPath: host.host, timeout: 10000, responseType };
|
||||
axiosConfig = { socketPath: host.host, timeout: config.ESPLORA.REQUEST_TIMEOUT, responseType };
|
||||
url = path;
|
||||
} else {
|
||||
axiosConfig = { timeout: 10000, responseType };
|
||||
axiosConfig = { timeout: config.ESPLORA.REQUEST_TIMEOUT, responseType };
|
||||
url = host.host + path;
|
||||
}
|
||||
return (method === 'post'
|
||||
|
||||
@@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository';
|
||||
import { RowDataPacket } from 'mysql2';
|
||||
|
||||
class DatabaseMigration {
|
||||
private static currentVersion = 65;
|
||||
private static currentVersion = 66;
|
||||
private queryTimeout = 3600_000;
|
||||
private statisticsAddedIndexed = false;
|
||||
private uniqueLogs: string[] = [];
|
||||
@@ -553,6 +553,11 @@ class DatabaseMigration {
|
||||
await this.$executeQuery('ALTER TABLE `blocks_audits` ADD accelerated_txs JSON DEFAULT "[]"');
|
||||
await this.updateToSchemaVersion(65);
|
||||
}
|
||||
|
||||
if (databaseSchemaVersion < 66) {
|
||||
await this.$executeQuery('ALTER TABLE `statistics` ADD min_fee FLOAT UNSIGNED DEFAULT NULL');
|
||||
await this.updateToSchemaVersion(66);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,21 +3,30 @@ import { Common } from './common';
|
||||
import mempool from './mempool';
|
||||
import projectedBlocks from './mempool-blocks';
|
||||
|
||||
interface RecommendedFees {
|
||||
fastestFee: number,
|
||||
halfHourFee: number,
|
||||
hourFee: number,
|
||||
economyFee: number,
|
||||
minimumFee: number,
|
||||
}
|
||||
|
||||
class FeeApi {
|
||||
constructor() { }
|
||||
|
||||
defaultFee = Common.isLiquid() ? 0.1 : 1;
|
||||
|
||||
public getRecommendedFee() {
|
||||
public getRecommendedFee(): RecommendedFees {
|
||||
const pBlocks = projectedBlocks.getMempoolBlocks();
|
||||
const mPool = mempool.getMempoolInfo();
|
||||
const minimumFee = Math.ceil(mPool.mempoolminfee * 100000);
|
||||
const defaultMinFee = Math.max(minimumFee, this.defaultFee);
|
||||
|
||||
if (!pBlocks.length) {
|
||||
return {
|
||||
'fastestFee': this.defaultFee,
|
||||
'halfHourFee': this.defaultFee,
|
||||
'hourFee': this.defaultFee,
|
||||
'fastestFee': defaultMinFee,
|
||||
'halfHourFee': defaultMinFee,
|
||||
'hourFee': defaultMinFee,
|
||||
'economyFee': minimumFee,
|
||||
'minimumFee': minimumFee,
|
||||
};
|
||||
@@ -27,11 +36,15 @@ class FeeApi {
|
||||
const secondMedianFee = pBlocks[1] ? this.optimizeMedianFee(pBlocks[1], pBlocks[2], firstMedianFee) : this.defaultFee;
|
||||
const thirdMedianFee = pBlocks[2] ? this.optimizeMedianFee(pBlocks[2], pBlocks[3], secondMedianFee) : this.defaultFee;
|
||||
|
||||
// explicitly enforce a minimum of ceil(mempoolminfee) on all recommendations.
|
||||
// simply rounding up recommended rates is insufficient, as the purging rate
|
||||
// can exceed the median rate of projected blocks in some extreme scenarios
|
||||
// (see https://bitcoin.stackexchange.com/a/120024)
|
||||
return {
|
||||
'fastestFee': firstMedianFee,
|
||||
'halfHourFee': secondMedianFee,
|
||||
'hourFee': thirdMedianFee,
|
||||
'economyFee': Math.min(2 * minimumFee, thirdMedianFee),
|
||||
'fastestFee': Math.max(minimumFee, firstMedianFee),
|
||||
'halfHourFee': Math.max(minimumFee, secondMedianFee),
|
||||
'hourFee': Math.max(minimumFee, thirdMedianFee),
|
||||
'economyFee': Math.max(minimumFee, Math.min(2 * minimumFee, thirdMedianFee)),
|
||||
'minimumFee': minimumFee,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ class MemoryCache {
|
||||
}
|
||||
|
||||
private cleanup() {
|
||||
this.cache = this.cache.filter((cache) => cache.expires < (new Date()));
|
||||
this.cache = this.cache.filter((cache) => cache.expires > (new Date()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ class StatisticsApi {
|
||||
mempool_byte_weight,
|
||||
fee_data,
|
||||
total_fee,
|
||||
min_fee,
|
||||
vsize_1,
|
||||
vsize_2,
|
||||
vsize_3,
|
||||
@@ -54,7 +55,7 @@ class StatisticsApi {
|
||||
vsize_1800,
|
||||
vsize_2000
|
||||
)
|
||||
VALUES (NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
VALUES (NOW(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)`;
|
||||
const [result]: any = await DB.query(query);
|
||||
return result.insertId;
|
||||
@@ -73,6 +74,7 @@ class StatisticsApi {
|
||||
mempool_byte_weight,
|
||||
fee_data,
|
||||
total_fee,
|
||||
min_fee,
|
||||
vsize_1,
|
||||
vsize_2,
|
||||
vsize_3,
|
||||
@@ -112,7 +114,7 @@ class StatisticsApi {
|
||||
vsize_1800,
|
||||
vsize_2000
|
||||
)
|
||||
VALUES (${statistics.added}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
||||
VALUES (${statistics.added}, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`;
|
||||
|
||||
const params: (string | number)[] = [
|
||||
@@ -122,6 +124,7 @@ class StatisticsApi {
|
||||
statistics.mempool_byte_weight,
|
||||
statistics.fee_data,
|
||||
statistics.total_fee,
|
||||
statistics.min_fee,
|
||||
statistics.vsize_1,
|
||||
statistics.vsize_2,
|
||||
statistics.vsize_3,
|
||||
@@ -173,6 +176,7 @@ class StatisticsApi {
|
||||
UNIX_TIMESTAMP(added) as added,
|
||||
CAST(avg(unconfirmed_transactions) as DOUBLE) as unconfirmed_transactions,
|
||||
CAST(avg(vbytes_per_second) as DOUBLE) as vbytes_per_second,
|
||||
CAST(avg(min_fee) as DOUBLE) as min_fee,
|
||||
CAST(avg(vsize_1) as DOUBLE) as vsize_1,
|
||||
CAST(avg(vsize_2) as DOUBLE) as vsize_2,
|
||||
CAST(avg(vsize_3) as DOUBLE) as vsize_3,
|
||||
@@ -222,6 +226,7 @@ class StatisticsApi {
|
||||
UNIX_TIMESTAMP(added) as added,
|
||||
CAST(avg(unconfirmed_transactions) as DOUBLE) as unconfirmed_transactions,
|
||||
CAST(avg(vbytes_per_second) as DOUBLE) as vbytes_per_second,
|
||||
CAST(avg(min_fee) as DOUBLE) as min_fee,
|
||||
vsize_1,
|
||||
vsize_2,
|
||||
vsize_3,
|
||||
@@ -407,6 +412,7 @@ class StatisticsApi {
|
||||
vbytes_per_second: s.vbytes_per_second,
|
||||
mempool_byte_weight: s.mempool_byte_weight,
|
||||
total_fee: s.total_fee,
|
||||
min_fee: s.min_fee,
|
||||
vsizes: [
|
||||
s.vsize_1,
|
||||
s.vsize_2,
|
||||
|
||||
@@ -89,6 +89,9 @@ class Statistics {
|
||||
}
|
||||
});
|
||||
|
||||
// get minFee and convert to sats/vb
|
||||
const minFee = memPool.getMempoolInfo().mempoolminfee * 100000;
|
||||
|
||||
try {
|
||||
const insertId = await statisticsApi.$create({
|
||||
added: 'NOW()',
|
||||
@@ -98,6 +101,7 @@ class Statistics {
|
||||
mempool_byte_weight: totalWeight,
|
||||
total_fee: totalFee,
|
||||
fee_data: '',
|
||||
min_fee: minFee,
|
||||
vsize_1: weightVsizeFees['1'] || 0,
|
||||
vsize_2: weightVsizeFees['2'] || 0,
|
||||
vsize_3: weightVsizeFees['3'] || 0,
|
||||
|
||||
Reference in New Issue
Block a user