mirror of
https://github.com/mempool/mempool.git
synced 2025-02-24 06:47:52 +01:00
Merge branch 'master' into nymkappa/feature/merge-blocks
This commit is contained in:
commit
9e0fdec053
4 changed files with 64 additions and 64 deletions
|
@ -15,6 +15,7 @@ import BitcoinApi from './bitcoin/bitcoin-api';
|
||||||
import { prepareBlock } from '../utils/blocks-utils';
|
import { prepareBlock } from '../utils/blocks-utils';
|
||||||
import BlocksRepository from '../repositories/BlocksRepository';
|
import BlocksRepository from '../repositories/BlocksRepository';
|
||||||
import HashratesRepository from '../repositories/HashratesRepository';
|
import HashratesRepository from '../repositories/HashratesRepository';
|
||||||
|
import indexer from '../indexer';
|
||||||
|
|
||||||
class Blocks {
|
class Blocks {
|
||||||
private blocks: BlockExtended[] = [];
|
private blocks: BlockExtended[] = [];
|
||||||
|
@ -23,9 +24,6 @@ class Blocks {
|
||||||
private lastDifficultyAdjustmentTime = 0;
|
private lastDifficultyAdjustmentTime = 0;
|
||||||
private previousDifficultyRetarget = 0;
|
private previousDifficultyRetarget = 0;
|
||||||
private newBlockCallbacks: ((block: BlockExtended, txIds: string[], transactions: TransactionExtended[]) => void)[] = [];
|
private newBlockCallbacks: ((block: BlockExtended, txIds: string[], transactions: TransactionExtended[]) => void)[] = [];
|
||||||
private blockIndexingStarted = false;
|
|
||||||
public blockIndexingCompleted = false;
|
|
||||||
public reindexFlag = false;
|
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
|
@ -197,24 +195,15 @@ class Blocks {
|
||||||
* [INDEXING] Index all blocks metadata for the mining dashboard
|
* [INDEXING] Index all blocks metadata for the mining dashboard
|
||||||
*/
|
*/
|
||||||
public async $generateBlockDatabase() {
|
public async $generateBlockDatabase() {
|
||||||
if (this.blockIndexingStarted && !this.reindexFlag) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.reindexFlag = false;
|
|
||||||
|
|
||||||
const blockchainInfo = await bitcoinClient.getBlockchainInfo();
|
const blockchainInfo = await bitcoinClient.getBlockchainInfo();
|
||||||
if (blockchainInfo.blocks !== blockchainInfo.headers) { // Wait for node to sync
|
if (blockchainInfo.blocks !== blockchainInfo.headers) { // Wait for node to sync
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.blockIndexingStarted = true;
|
|
||||||
this.blockIndexingCompleted = false;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let currentBlockHeight = blockchainInfo.blocks;
|
let currentBlockHeight = blockchainInfo.blocks;
|
||||||
|
|
||||||
let indexingBlockAmount = config.MEMPOOL.INDEXING_BLOCKS_AMOUNT;
|
let indexingBlockAmount = Math.min(config.MEMPOOL.INDEXING_BLOCKS_AMOUNT, blockchainInfo.blocks);
|
||||||
if (indexingBlockAmount <= -1) {
|
if (indexingBlockAmount <= -1) {
|
||||||
indexingBlockAmount = currentBlockHeight + 1;
|
indexingBlockAmount = currentBlockHeight + 1;
|
||||||
}
|
}
|
||||||
|
@ -275,14 +264,14 @@ class Blocks {
|
||||||
loadingIndicators.setProgress('block-indexing', 100);
|
loadingIndicators.setProgress('block-indexing', 100);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.err('Block indexing failed. Trying again later. Reason: ' + (e instanceof Error ? e.message : e));
|
logger.err('Block indexing failed. Trying again later. Reason: ' + (e instanceof Error ? e.message : e));
|
||||||
this.blockIndexingStarted = false;
|
|
||||||
loadingIndicators.setProgress('block-indexing', 100);
|
loadingIndicators.setProgress('block-indexing', 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const chainValid = await BlocksRepository.$validateChain();
|
const chainValid = await BlocksRepository.$validateChain();
|
||||||
this.reindexFlag = !chainValid;
|
if (!chainValid) {
|
||||||
this.blockIndexingCompleted = chainValid;
|
indexer.reindex();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $updateBlocks() {
|
public async $updateBlocks() {
|
||||||
|
@ -299,6 +288,8 @@ class Blocks {
|
||||||
logger.info(`${blockHeightTip - this.currentBlockHeight} blocks since tip. Fast forwarding to the ${config.MEMPOOL.INITIAL_BLOCKS_AMOUNT} recent blocks`);
|
logger.info(`${blockHeightTip - this.currentBlockHeight} blocks since tip. Fast forwarding to the ${config.MEMPOOL.INITIAL_BLOCKS_AMOUNT} recent blocks`);
|
||||||
this.currentBlockHeight = blockHeightTip - config.MEMPOOL.INITIAL_BLOCKS_AMOUNT;
|
this.currentBlockHeight = blockHeightTip - config.MEMPOOL.INITIAL_BLOCKS_AMOUNT;
|
||||||
fastForwarded = true;
|
fastForwarded = true;
|
||||||
|
logger.info(`Re-indexing skipped blocks and corresponding hashrates data`);
|
||||||
|
indexer.reindex(); // Make sure to index the skipped blocks #1619
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.lastDifficultyAdjustmentTime) {
|
if (!this.lastDifficultyAdjustmentTime) {
|
||||||
|
|
|
@ -4,15 +4,11 @@ import PoolsRepository from '../repositories/PoolsRepository';
|
||||||
import HashratesRepository from '../repositories/HashratesRepository';
|
import HashratesRepository from '../repositories/HashratesRepository';
|
||||||
import bitcoinClient from './bitcoin/bitcoin-client';
|
import bitcoinClient from './bitcoin/bitcoin-client';
|
||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
import blocks from './blocks';
|
|
||||||
import { Common } from './common';
|
import { Common } from './common';
|
||||||
import loadingIndicators from './loading-indicators';
|
import loadingIndicators from './loading-indicators';
|
||||||
import { escape } from 'mysql2';
|
import { escape } from 'mysql2';
|
||||||
|
|
||||||
class Mining {
|
class Mining {
|
||||||
hashrateIndexingStarted = false;
|
|
||||||
weeklyHashrateIndexingStarted = false;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,14 +149,9 @@ class Mining {
|
||||||
* [INDEXING] Generate weekly mining pool hashrate history
|
* [INDEXING] Generate weekly mining pool hashrate history
|
||||||
*/
|
*/
|
||||||
public async $generatePoolHashrateHistory(): Promise<void> {
|
public async $generatePoolHashrateHistory(): Promise<void> {
|
||||||
if (!blocks.blockIndexingCompleted || this.hashrateIndexingStarted || this.weeklyHashrateIndexingStarted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.weeklyHashrateIndexingStarted = true;
|
|
||||||
const lastestRunDate = await HashratesRepository.$getLatestRun('last_weekly_hashrates_indexing');
|
const lastestRunDate = await HashratesRepository.$getLatestRun('last_weekly_hashrates_indexing');
|
||||||
|
|
||||||
// Run only if:
|
// Run only if:
|
||||||
|
@ -168,11 +159,9 @@ class Mining {
|
||||||
// * we started a new week (around Monday midnight)
|
// * we started a new week (around Monday midnight)
|
||||||
const runIndexing = lastestRunDate === 0 || now.getUTCDay() === 1 && lastestRunDate !== now.getUTCDate();
|
const runIndexing = lastestRunDate === 0 || now.getUTCDay() === 1 && lastestRunDate !== now.getUTCDate();
|
||||||
if (!runIndexing) {
|
if (!runIndexing) {
|
||||||
this.weeklyHashrateIndexingStarted = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.weeklyHashrateIndexingStarted = false;
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,6 +181,7 @@ class Mining {
|
||||||
const startedAt = new Date().getTime() / 1000;
|
const startedAt = new Date().getTime() / 1000;
|
||||||
let timer = new Date().getTime() / 1000;
|
let timer = new Date().getTime() / 1000;
|
||||||
|
|
||||||
|
logger.debug(`Indexing weekly mining pool hashrate`);
|
||||||
loadingIndicators.setProgress('weekly-hashrate-indexing', 0);
|
loadingIndicators.setProgress('weekly-hashrate-indexing', 0);
|
||||||
|
|
||||||
while (toTimestamp > genesisTimestamp) {
|
while (toTimestamp > genesisTimestamp) {
|
||||||
|
@ -256,7 +246,6 @@ class Mining {
|
||||||
++indexedThisRun;
|
++indexedThisRun;
|
||||||
++totalIndexed;
|
++totalIndexed;
|
||||||
}
|
}
|
||||||
this.weeklyHashrateIndexingStarted = false;
|
|
||||||
await HashratesRepository.$setLatestRun('last_weekly_hashrates_indexing', new Date().getUTCDate());
|
await HashratesRepository.$setLatestRun('last_weekly_hashrates_indexing', new Date().getUTCDate());
|
||||||
if (newlyIndexed > 0) {
|
if (newlyIndexed > 0) {
|
||||||
logger.info(`Indexed ${newlyIndexed} pools weekly hashrate`);
|
logger.info(`Indexed ${newlyIndexed} pools weekly hashrate`);
|
||||||
|
@ -264,7 +253,6 @@ class Mining {
|
||||||
loadingIndicators.setProgress('weekly-hashrate-indexing', 100);
|
loadingIndicators.setProgress('weekly-hashrate-indexing', 100);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
loadingIndicators.setProgress('weekly-hashrate-indexing', 100);
|
loadingIndicators.setProgress('weekly-hashrate-indexing', 100);
|
||||||
this.weeklyHashrateIndexingStarted = false;
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,22 +261,14 @@ class Mining {
|
||||||
* [INDEXING] Generate daily hashrate data
|
* [INDEXING] Generate daily hashrate data
|
||||||
*/
|
*/
|
||||||
public async $generateNetworkHashrateHistory(): Promise<void> {
|
public async $generateNetworkHashrateHistory(): Promise<void> {
|
||||||
if (!blocks.blockIndexingCompleted || this.hashrateIndexingStarted) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.hashrateIndexingStarted = true;
|
|
||||||
|
|
||||||
// We only run this once a day around midnight
|
// We only run this once a day around midnight
|
||||||
const latestRunDate = await HashratesRepository.$getLatestRun('last_hashrates_indexing');
|
const latestRunDate = await HashratesRepository.$getLatestRun('last_hashrates_indexing');
|
||||||
const now = new Date().getUTCDate();
|
const now = new Date().getUTCDate();
|
||||||
if (now === latestRunDate) {
|
if (now === latestRunDate) {
|
||||||
this.hashrateIndexingStarted = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.hashrateIndexingStarted = false;
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,6 +286,7 @@ class Mining {
|
||||||
const startedAt = new Date().getTime() / 1000;
|
const startedAt = new Date().getTime() / 1000;
|
||||||
let timer = new Date().getTime() / 1000;
|
let timer = new Date().getTime() / 1000;
|
||||||
|
|
||||||
|
logger.debug(`Indexing daily network hashrate`);
|
||||||
loadingIndicators.setProgress('daily-hashrate-indexing', 0);
|
loadingIndicators.setProgress('daily-hashrate-indexing', 0);
|
||||||
|
|
||||||
while (toTimestamp > genesisTimestamp) {
|
while (toTimestamp > genesisTimestamp) {
|
||||||
|
@ -377,14 +358,12 @@ class Mining {
|
||||||
await HashratesRepository.$saveHashrates(hashrates);
|
await HashratesRepository.$saveHashrates(hashrates);
|
||||||
|
|
||||||
await HashratesRepository.$setLatestRun('last_hashrates_indexing', new Date().getUTCDate());
|
await HashratesRepository.$setLatestRun('last_hashrates_indexing', new Date().getUTCDate());
|
||||||
this.hashrateIndexingStarted = false;
|
|
||||||
if (newlyIndexed > 0) {
|
if (newlyIndexed > 0) {
|
||||||
logger.info(`Indexed ${newlyIndexed} day of network hashrate`);
|
logger.info(`Indexed ${newlyIndexed} day of network hashrate`);
|
||||||
}
|
}
|
||||||
loadingIndicators.setProgress('daily-hashrate-indexing', 100);
|
loadingIndicators.setProgress('daily-hashrate-indexing', 100);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
loadingIndicators.setProgress('daily-hashrate-indexing', 100);
|
loadingIndicators.setProgress('daily-hashrate-indexing', 100);
|
||||||
this.hashrateIndexingStarted = false;
|
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import { Common } from './api/common';
|
||||||
import mining from './api/mining';
|
import mining from './api/mining';
|
||||||
import HashratesRepository from './repositories/HashratesRepository';
|
import HashratesRepository from './repositories/HashratesRepository';
|
||||||
import poolsUpdater from './tasks/pools-updater';
|
import poolsUpdater from './tasks/pools-updater';
|
||||||
|
import indexer from './indexer';
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
private wss: WebSocket.Server | undefined;
|
private wss: WebSocket.Server | undefined;
|
||||||
|
@ -98,7 +99,7 @@ class Server {
|
||||||
}
|
}
|
||||||
await databaseMigration.$initializeOrMigrateDatabase();
|
await databaseMigration.$initializeOrMigrateDatabase();
|
||||||
if (Common.indexingEnabled()) {
|
if (Common.indexingEnabled()) {
|
||||||
await this.$resetHashratesIndexingState();
|
await indexer.$resetHashratesIndexingState();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error(e instanceof Error ? e.message : 'Error');
|
throw new Error(e instanceof Error ? e.message : 'Error');
|
||||||
|
@ -153,7 +154,7 @@ class Server {
|
||||||
await poolsUpdater.updatePoolsJson();
|
await poolsUpdater.updatePoolsJson();
|
||||||
await blocks.$updateBlocks();
|
await blocks.$updateBlocks();
|
||||||
await memPool.$updateMempool();
|
await memPool.$updateMempool();
|
||||||
this.$runIndexingWhenReady();
|
indexer.$run();
|
||||||
|
|
||||||
setTimeout(this.runMainUpdateLoop.bind(this), config.MEMPOOL.POLL_RATE_MS);
|
setTimeout(this.runMainUpdateLoop.bind(this), config.MEMPOOL.POLL_RATE_MS);
|
||||||
this.currentBackendRetryInterval = 5;
|
this.currentBackendRetryInterval = 5;
|
||||||
|
@ -172,29 +173,6 @@ class Server {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async $resetHashratesIndexingState() {
|
|
||||||
try {
|
|
||||||
await HashratesRepository.$setLatestRun('last_hashrates_indexing', 0);
|
|
||||||
await HashratesRepository.$setLatestRun('last_weekly_hashrates_indexing', 0);
|
|
||||||
} catch (e) {
|
|
||||||
logger.err(`Cannot reset hashrate indexing timestamps. Reason: ` + (e instanceof Error ? e.message : e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async $runIndexingWhenReady() {
|
|
||||||
if (!Common.indexingEnabled() || mempool.hasPriority()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await blocks.$generateBlockDatabase();
|
|
||||||
await mining.$generateNetworkHashrateHistory();
|
|
||||||
await mining.$generatePoolHashrateHistory();
|
|
||||||
} catch (e) {
|
|
||||||
logger.err(`Indexing failed, trying again later. Reason: ` + (e instanceof Error ? e.message : e));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setUpWebsocketHandling() {
|
setUpWebsocketHandling() {
|
||||||
if (this.wss) {
|
if (this.wss) {
|
||||||
websocketHandler.setWebsocketServer(this.wss);
|
websocketHandler.setWebsocketServer(this.wss);
|
||||||
|
|
52
backend/src/indexer.ts
Normal file
52
backend/src/indexer.ts
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import { Common } from './api/common';
|
||||||
|
import blocks from './api/blocks';
|
||||||
|
import mempool from './api/mempool';
|
||||||
|
import mining from './api/mining';
|
||||||
|
import logger from './logger';
|
||||||
|
import HashratesRepository from './repositories/HashratesRepository';
|
||||||
|
|
||||||
|
class Indexer {
|
||||||
|
runIndexer = true;
|
||||||
|
indexerRunning = false;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public reindex() {
|
||||||
|
this.runIndexer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async $run() {
|
||||||
|
if (!Common.indexingEnabled() || this.runIndexer === false ||
|
||||||
|
this.indexerRunning === true || mempool.hasPriority()
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.runIndexer = false;
|
||||||
|
this.indexerRunning = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await blocks.$generateBlockDatabase();
|
||||||
|
await this.$resetHashratesIndexingState();
|
||||||
|
await mining.$generateNetworkHashrateHistory();
|
||||||
|
await mining.$generatePoolHashrateHistory();
|
||||||
|
} catch (e) {
|
||||||
|
this.reindex();
|
||||||
|
logger.err(`Indexer failed, trying again later. Reason: ` + (e instanceof Error ? e.message : e));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.indexerRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async $resetHashratesIndexingState() {
|
||||||
|
try {
|
||||||
|
await HashratesRepository.$setLatestRun('last_hashrates_indexing', 0);
|
||||||
|
await HashratesRepository.$setLatestRun('last_weekly_hashrates_indexing', 0);
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Cannot reset hashrate indexing timestamps. Reason: ` + (e instanceof Error ? e.message : e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new Indexer();
|
Loading…
Add table
Reference in a new issue