Merge pull request #1822 from mempool/nymkappa/bugfix/db-disabled
Add 'db-less' mining pool tagging support
This commit is contained in:
commit
c64d95b0ec
@ -18,6 +18,7 @@ import HashratesRepository from '../repositories/HashratesRepository';
|
|||||||
import indexer from '../indexer';
|
import indexer from '../indexer';
|
||||||
import fiatConversion from './fiat-conversion';
|
import fiatConversion from './fiat-conversion';
|
||||||
import RatesRepository from '../repositories/RatesRepository';
|
import RatesRepository from '../repositories/RatesRepository';
|
||||||
|
import poolsParser from './pools-parser';
|
||||||
|
|
||||||
class Blocks {
|
class Blocks {
|
||||||
private blocks: BlockExtended[] = [];
|
private blocks: BlockExtended[] = [];
|
||||||
@ -139,7 +140,11 @@ class Blocks {
|
|||||||
if (blockExtended.extras?.coinbaseTx !== undefined) {
|
if (blockExtended.extras?.coinbaseTx !== undefined) {
|
||||||
pool = await this.$findBlockMiner(blockExtended.extras?.coinbaseTx);
|
pool = await this.$findBlockMiner(blockExtended.extras?.coinbaseTx);
|
||||||
} else {
|
} else {
|
||||||
pool = await poolsRepository.$getUnknownPool();
|
if (config.DATABASE.ENABLED === true) {
|
||||||
|
pool = await poolsRepository.$getUnknownPool();
|
||||||
|
} else {
|
||||||
|
pool = poolsParser.unknownPool;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pool) { // We should never have this situation in practise
|
if (!pool) { // We should never have this situation in practise
|
||||||
@ -165,13 +170,22 @@ class Blocks {
|
|||||||
*/
|
*/
|
||||||
private async $findBlockMiner(txMinerInfo: TransactionMinerInfo | undefined): Promise<PoolTag> {
|
private async $findBlockMiner(txMinerInfo: TransactionMinerInfo | undefined): Promise<PoolTag> {
|
||||||
if (txMinerInfo === undefined || txMinerInfo.vout.length < 1) {
|
if (txMinerInfo === undefined || txMinerInfo.vout.length < 1) {
|
||||||
return await poolsRepository.$getUnknownPool();
|
if (config.DATABASE.ENABLED === true) {
|
||||||
|
return await poolsRepository.$getUnknownPool();
|
||||||
|
} else {
|
||||||
|
return poolsParser.unknownPool;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const asciiScriptSig = transactionUtils.hex2ascii(txMinerInfo.vin[0].scriptsig);
|
const asciiScriptSig = transactionUtils.hex2ascii(txMinerInfo.vin[0].scriptsig);
|
||||||
const address = txMinerInfo.vout[0].scriptpubkey_address;
|
const address = txMinerInfo.vout[0].scriptpubkey_address;
|
||||||
|
|
||||||
const pools: PoolTag[] = await poolsRepository.$getPools();
|
let pools: PoolTag[] = [];
|
||||||
|
if (config.DATABASE.ENABLED === true) {
|
||||||
|
pools = await poolsRepository.$getPools();
|
||||||
|
} else {
|
||||||
|
pools = poolsParser.miningPools;
|
||||||
|
}
|
||||||
for (let i = 0; i < pools.length; ++i) {
|
for (let i = 0; i < pools.length; ++i) {
|
||||||
if (address !== undefined) {
|
if (address !== undefined) {
|
||||||
const addresses: string[] = JSON.parse(pools[i].addresses);
|
const addresses: string[] = JSON.parse(pools[i].addresses);
|
||||||
@ -190,7 +204,11 @@ class Blocks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return await poolsRepository.$getUnknownPool();
|
if (config.DATABASE.ENABLED === true) {
|
||||||
|
return await poolsRepository.$getUnknownPool();
|
||||||
|
} else {
|
||||||
|
return poolsParser.unknownPool;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +11,14 @@ interface Pool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class PoolsParser {
|
class PoolsParser {
|
||||||
|
miningPools: any[] = [];
|
||||||
|
unknownPool: any = {
|
||||||
|
'name': "Unknown",
|
||||||
|
'link': "https://learnmeabitcoin.com/technical/coinbase-transaction",
|
||||||
|
'regexes': "[]",
|
||||||
|
'addresses': "[]",
|
||||||
|
'slug': 'unknown'
|
||||||
|
};
|
||||||
slugWarnFlag = false;
|
slugWarnFlag = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,12 +68,18 @@ class PoolsParser {
|
|||||||
// Get existing pools from the db
|
// Get existing pools from the db
|
||||||
let existingPools;
|
let existingPools;
|
||||||
try {
|
try {
|
||||||
[existingPools] = await DB.query({ sql: 'SELECT * FROM pools;', timeout: 120000 });
|
if (config.DATABASE.ENABLED === true) {
|
||||||
|
[existingPools] = await DB.query({ sql: 'SELECT * FROM pools;', timeout: 120000 });
|
||||||
|
} else {
|
||||||
|
existingPools = [];
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.err('Cannot get existing pools from the database, skipping pools.json import');
|
logger.err('Cannot get existing pools from the database, skipping pools.json import');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.miningPools = [];
|
||||||
|
|
||||||
// Finally, we generate the final consolidated pools data
|
// Finally, we generate the final consolidated pools data
|
||||||
const finalPoolDataAdd: Pool[] = [];
|
const finalPoolDataAdd: Pool[] = [];
|
||||||
const finalPoolDataUpdate: Pool[] = [];
|
const finalPoolDataUpdate: Pool[] = [];
|
||||||
@ -97,24 +111,33 @@ class PoolsParser {
|
|||||||
logger.warn(`No slug found for '${poolNames[i]}', generating it => '${slug}'`);
|
logger.warn(`No slug found for '${poolNames[i]}', generating it => '${slug}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const poolObj = {
|
||||||
|
'name': finalPoolName,
|
||||||
|
'link': match[0].link,
|
||||||
|
'regexes': allRegexes,
|
||||||
|
'addresses': allAddresses,
|
||||||
|
'slug': slug
|
||||||
|
};
|
||||||
|
|
||||||
if (existingPools.find((pool) => pool.name === poolNames[i]) !== undefined) {
|
if (existingPools.find((pool) => pool.name === poolNames[i]) !== undefined) {
|
||||||
finalPoolDataUpdate.push({
|
finalPoolDataUpdate.push(poolObj);
|
||||||
'name': finalPoolName,
|
|
||||||
'link': match[0].link,
|
|
||||||
'regexes': allRegexes,
|
|
||||||
'addresses': allAddresses,
|
|
||||||
'slug': slug
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
logger.debug(`Add '${finalPoolName}' mining pool`);
|
logger.debug(`Add '${finalPoolName}' mining pool`);
|
||||||
finalPoolDataAdd.push({
|
finalPoolDataAdd.push(poolObj);
|
||||||
'name': finalPoolName,
|
|
||||||
'link': match[0].link,
|
|
||||||
'regexes': allRegexes,
|
|
||||||
'addresses': allAddresses,
|
|
||||||
'slug': slug
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.miningPools.push({
|
||||||
|
'name': finalPoolName,
|
||||||
|
'link': match[0].link,
|
||||||
|
'regexes': JSON.stringify(allRegexes),
|
||||||
|
'addresses': JSON.stringify(allAddresses),
|
||||||
|
'slug': slug
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.DATABASE.ENABLED === false) { // Don't run db operations
|
||||||
|
logger.info('Mining pools.json import completed (no database)');
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug(`Update pools table now`);
|
logger.debug(`Update pools table now`);
|
||||||
@ -124,11 +147,11 @@ class PoolsParser {
|
|||||||
for (let i = 0; i < finalPoolDataAdd.length; ++i) {
|
for (let i = 0; i < finalPoolDataAdd.length; ++i) {
|
||||||
queryAdd += `('${finalPoolDataAdd[i].name}', '${finalPoolDataAdd[i].link}',
|
queryAdd += `('${finalPoolDataAdd[i].name}', '${finalPoolDataAdd[i].link}',
|
||||||
'${JSON.stringify(finalPoolDataAdd[i].regexes)}', '${JSON.stringify(finalPoolDataAdd[i].addresses)}',
|
'${JSON.stringify(finalPoolDataAdd[i].regexes)}', '${JSON.stringify(finalPoolDataAdd[i].addresses)}',
|
||||||
${JSON.stringify(finalPoolDataAdd[i].slug)}),`;
|
${finalPoolDataAdd[i].slug}),`;
|
||||||
}
|
}
|
||||||
queryAdd = queryAdd.slice(0, -1) + ';';
|
queryAdd = queryAdd.slice(0, -1) + ';';
|
||||||
|
|
||||||
// Add new mining pools into the database
|
// Updated existing mining pools in the database
|
||||||
const updateQueries: string[] = [];
|
const updateQueries: string[] = [];
|
||||||
for (let i = 0; i < finalPoolDataUpdate.length; ++i) {
|
for (let i = 0; i < finalPoolDataUpdate.length; ++i) {
|
||||||
updateQueries.push(`
|
updateQueries.push(`
|
||||||
|
@ -22,12 +22,20 @@ import { PoolOptions } from 'mysql2/typings/mysql';
|
|||||||
timezone: '+00:00',
|
timezone: '+00:00',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private checkDBFlag() {
|
||||||
|
if (config.DATABASE.ENABLED === false) {
|
||||||
|
logger.err('Trying to use DB feature but config.DATABASE.ENABLED is set to false, please open an issue');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async query(query, params?) {
|
public async query(query, params?) {
|
||||||
|
this.checkDBFlag();
|
||||||
const pool = await this.getPool();
|
const pool = await this.getPool();
|
||||||
return pool.query(query, params);
|
return pool.query(query, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async checkDbConnection() {
|
public async checkDbConnection() {
|
||||||
|
this.checkDBFlag();
|
||||||
try {
|
try {
|
||||||
await this.query('SELECT ?', [1]);
|
await this.query('SELECT ?', [1]);
|
||||||
logger.info('Database connection established.');
|
logger.info('Database connection established.');
|
||||||
|
@ -13,7 +13,9 @@ class Indexer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public reindex() {
|
public reindex() {
|
||||||
this.runIndexer = true;
|
if (Common.indexingEnabled()) {
|
||||||
|
this.runIndexer = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $run() {
|
public async $run() {
|
||||||
|
@ -12,12 +12,13 @@ import * as https from 'https';
|
|||||||
*/
|
*/
|
||||||
class PoolsUpdater {
|
class PoolsUpdater {
|
||||||
lastRun: number = 0;
|
lastRun: number = 0;
|
||||||
|
currentSha: any = undefined;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updatePoolsJson() {
|
public async updatePoolsJson() {
|
||||||
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) === false || config.DATABASE.ENABLED === false) {
|
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,14 +40,17 @@ class PoolsUpdater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const dbSha = await this.getShaFromDb();
|
|
||||||
const githubSha = await this.fetchPoolsSha(); // Fetch pools.json sha from github
|
const githubSha = await this.fetchPoolsSha(); // Fetch pools.json sha from github
|
||||||
if (githubSha === undefined) {
|
if (githubSha === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug(`Pools.json sha | Current: ${dbSha} | Github: ${githubSha}`);
|
if (config.DATABASE.ENABLED === true) {
|
||||||
if (dbSha !== undefined && dbSha === githubSha) {
|
this.currentSha = await this.getShaFromDb();
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.debug(`Pools.json sha | Current: ${this.currentSha} | Github: ${githubSha}`);
|
||||||
|
if (this.currentSha !== undefined && this.currentSha === githubSha) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,12 +73,14 @@ class PoolsUpdater {
|
|||||||
* Fetch our latest pools.json sha from the db
|
* Fetch our latest pools.json sha from the db
|
||||||
*/
|
*/
|
||||||
private async updateDBSha(githubSha: string) {
|
private async updateDBSha(githubSha: string) {
|
||||||
try {
|
this.currentSha = githubSha;
|
||||||
await DB.query('DELETE FROM state where name="pools_json_sha"');
|
if (config.DATABASE.ENABLED === true) {
|
||||||
await DB.query(`INSERT INTO state VALUES('pools_json_sha', NULL, '${githubSha}')`);
|
try {
|
||||||
} catch (e) {
|
await DB.query('DELETE FROM state where name="pools_json_sha"');
|
||||||
logger.err('Cannot save github pools.json sha into the db. Reason: ' + (e instanceof Error ? e.message : e));
|
await DB.query(`INSERT INTO state VALUES('pools_json_sha', NULL, '${githubSha}')`);
|
||||||
return undefined;
|
} catch (e) {
|
||||||
|
logger.err('Cannot save github pools.json sha into the db. Reason: ' + (e instanceof Error ? e.message : e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
<tbody *ngIf="blocks$ | async as blocks; else skeleton" [style]="isLoading ? 'opacity: 0.75' : ''">
|
<tbody *ngIf="blocks$ | async as blocks; else skeleton" [style]="isLoading ? 'opacity: 0.75' : ''">
|
||||||
<tr *ngFor="let block of blocks; let i= index; trackBy: trackByBlock">
|
<tr *ngFor="let block of blocks; let i= index; trackBy: trackByBlock">
|
||||||
<td class="text-left" [class]="widget ? 'widget' : ''">
|
<td class="text-left" [class]="widget ? 'widget' : ''">
|
||||||
<a [routerLink]="['/block' | relativeUrl, block.id]" [state]="{ data: { block: block } }">{{ block.height }}</a>
|
<a [routerLink]="['/block' | relativeUrl, block.id]">{{ block.height }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td *ngIf="indexingAvailable" class="pool text-left" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}">
|
<td *ngIf="indexingAvailable" class="pool text-left" [ngClass]="{'widget': widget, 'legacy': !indexingAvailable}">
|
||||||
<div class="tooltip-custom">
|
<div class="tooltip-custom">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user