Merge pull request #1822 from mempool/nymkappa/bugfix/db-disabled

Add 'db-less' mining pool tagging support
This commit is contained in:
wiz 2022-06-08 02:26:02 +09:00 committed by GitHub
commit c64d95b0ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 33 deletions

View File

@ -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;
}
} }
/** /**

View File

@ -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(`

View File

@ -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.');

View File

@ -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() {

View File

@ -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));
}
} }
} }

View File

@ -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">