Compute median fee and fee percentiles in sats
This commit is contained in:
parent
8f716a1d8c
commit
458f24c9f2
@ -203,11 +203,14 @@ class Blocks {
|
|||||||
blk.extras.segwitTotalWeight = stats.swtotal_weight;
|
blk.extras.segwitTotalWeight = stats.swtotal_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
blk.extras.feePercentiles = [], // TODO
|
|
||||||
blk.extras.medianFeeAmt = 0; // TODO
|
|
||||||
blk.extras.blockTime = 0; // TODO
|
blk.extras.blockTime = 0; // TODO
|
||||||
blk.extras.orphaned = false; // TODO
|
blk.extras.orphaned = false; // TODO
|
||||||
|
|
||||||
|
blk.extras.feePercentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(block.id);
|
||||||
|
if (blk.extras.feePercentiles !== null) {
|
||||||
|
blk.extras.medianFeeAmt = blk.extras.feePercentiles[3];
|
||||||
|
}
|
||||||
|
|
||||||
blk.extras.virtualSize = block.weight / 4.0;
|
blk.extras.virtualSize = block.weight / 4.0;
|
||||||
if (blk.extras.coinbaseTx.vout.length > 0) {
|
if (blk.extras.coinbaseTx.vout.length > 0) {
|
||||||
blk.extras.coinbaseAddress = blk.extras.coinbaseTx.vout[0].scriptpubkey_address ?? null;
|
blk.extras.coinbaseAddress = blk.extras.coinbaseTx.vout[0].scriptpubkey_address ?? null;
|
||||||
@ -791,7 +794,6 @@ class Blocks {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(block.hash);
|
delete(block.hash);
|
||||||
delete(block.previous_block_hash);
|
delete(block.previous_block_hash);
|
||||||
delete(block.pool_name);
|
delete(block.pool_name);
|
||||||
@ -800,6 +802,16 @@ class Blocks {
|
|||||||
delete(block.pool_regexes);
|
delete(block.pool_regexes);
|
||||||
delete(block.median_timestamp);
|
delete(block.median_timestamp);
|
||||||
|
|
||||||
|
// This requires `blocks_summaries` to be available. It takes a very long
|
||||||
|
// time to index this table so we just try to serve the data the best we can
|
||||||
|
if (block.fee_percentiles === null) {
|
||||||
|
block.fee_percentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(block.id);
|
||||||
|
if (block.fee_percentiles !== null) {
|
||||||
|
block.median_fee_amt = block.fee_percentiles[3];
|
||||||
|
await blocksRepository.$saveFeePercentilesForBlockId(block.id, block.fee_percentiles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
blocks.push(block);
|
blocks.push(block);
|
||||||
fromHeight++;
|
fromHeight++;
|
||||||
}
|
}
|
||||||
|
@ -772,7 +772,7 @@ class DatabaseMigration {
|
|||||||
ADD total_outputs int unsigned NOT NULL,
|
ADD total_outputs int unsigned NOT NULL,
|
||||||
ADD total_output_amt bigint unsigned NOT NULL,
|
ADD total_output_amt bigint unsigned NOT NULL,
|
||||||
ADD fee_percentiles longtext NULL,
|
ADD fee_percentiles longtext NULL,
|
||||||
ADD median_fee_amt int unsigned NOT NULL,
|
ADD median_fee_amt int unsigned NULL,
|
||||||
ADD segwit_total_txs int unsigned NOT NULL,
|
ADD segwit_total_txs int unsigned NOT NULL,
|
||||||
ADD segwit_total_size int unsigned NOT NULL,
|
ADD segwit_total_size int unsigned NOT NULL,
|
||||||
ADD segwit_total_weight int unsigned NOT NULL,
|
ADD segwit_total_weight int unsigned NOT NULL,
|
||||||
|
@ -171,8 +171,8 @@ export interface BlockExtension {
|
|||||||
totalInputs?: number;
|
totalInputs?: number;
|
||||||
totalOutputs?: number;
|
totalOutputs?: number;
|
||||||
totalOutputAmt?: number;
|
totalOutputAmt?: number;
|
||||||
medianFeeAmt?: number;
|
medianFeeAmt?: number | null;
|
||||||
feePercentiles?: number[],
|
feePercentiles?: number[] | null,
|
||||||
segwitTotalTxs?: number;
|
segwitTotalTxs?: number;
|
||||||
segwitTotalSize?: number;
|
segwitTotalSize?: number;
|
||||||
segwitTotalWeight?: number;
|
segwitTotalWeight?: number;
|
||||||
|
@ -811,6 +811,25 @@ class BlocksRepository {
|
|||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save indexed median fee to avoid recomputing it later
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param feePercentiles
|
||||||
|
*/
|
||||||
|
public async $saveFeePercentilesForBlockId(id: string, feePercentiles: number[]): Promise<void> {
|
||||||
|
try {
|
||||||
|
await DB.query(`
|
||||||
|
UPDATE blocks SET fee_percentiles = ?, median_fee_amt = ?
|
||||||
|
WHERE hash = ?`,
|
||||||
|
[JSON.stringify(feePercentiles), feePercentiles[3], id]
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Cannot update block fee_percentiles. Reason: ` + (e instanceof Error ? e.message : e));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new BlocksRepository();
|
export default new BlocksRepository();
|
||||||
|
@ -80,6 +80,48 @@ class BlocksSummariesRepository {
|
|||||||
logger.err('Cannot delete indexed blocks summaries. Reason: ' + (e instanceof Error ? e.message : e));
|
logger.err('Cannot delete indexed blocks summaries. Reason: ' + (e instanceof Error ? e.message : e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the fee percentiles if the block has already been indexed, [] otherwise
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
*/
|
||||||
|
public async $getFeePercentilesByBlockId(id: string): Promise<number[] | null> {
|
||||||
|
try {
|
||||||
|
const [rows]: any[] = await DB.query(`
|
||||||
|
SELECT transactions
|
||||||
|
FROM blocks_summaries
|
||||||
|
WHERE id = ?`,
|
||||||
|
[id]
|
||||||
|
);
|
||||||
|
if (rows === null || rows.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const transactions = JSON.parse(rows[0].transactions);
|
||||||
|
if (transactions === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
transactions.shift(); // Ignore coinbase
|
||||||
|
transactions.sort((a: any, b: any) => a.fee - b.fee);
|
||||||
|
const fees = transactions.map((t: any) => t.fee);
|
||||||
|
|
||||||
|
return [
|
||||||
|
fees[0], // min
|
||||||
|
fees[Math.max(0, Math.floor(fees.length * 0.1) - 1)], // 10th
|
||||||
|
fees[Math.max(0, Math.floor(fees.length * 0.25) - 1)], // 25th
|
||||||
|
fees[Math.max(0, Math.floor(fees.length * 0.5) - 1)], // median
|
||||||
|
fees[Math.max(0, Math.floor(fees.length * 0.75) - 1)], // 75th
|
||||||
|
fees[Math.max(0, Math.floor(fees.length * 0.9) - 1)], // 90th
|
||||||
|
fees[fees.length - 1], // max
|
||||||
|
];
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Cannot get block summaries transactions. Reason: ` + (e instanceof Error ? e.message : e));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new BlocksSummariesRepository();
|
export default new BlocksSummariesRepository();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user