Add 'db-less' mining pool tagging support
This commit is contained in:
		
							parent
							
								
									e99a684354
								
							
						
					
					
						commit
						53bc80e899
					
				@ -18,6 +18,7 @@ import HashratesRepository from '../repositories/HashratesRepository';
 | 
			
		||||
import indexer from '../indexer';
 | 
			
		||||
import fiatConversion from './fiat-conversion';
 | 
			
		||||
import RatesRepository from '../repositories/RatesRepository';
 | 
			
		||||
import poolsParser from './pools-parser';
 | 
			
		||||
 | 
			
		||||
class Blocks {
 | 
			
		||||
  private blocks: BlockExtended[] = [];
 | 
			
		||||
@ -139,7 +140,11 @@ class Blocks {
 | 
			
		||||
      if (blockExtended.extras?.coinbaseTx !== undefined) {
 | 
			
		||||
        pool = await this.$findBlockMiner(blockExtended.extras?.coinbaseTx);
 | 
			
		||||
      } else {
 | 
			
		||||
        if (config.DATABASE.ENABLED === true) {
 | 
			
		||||
          pool = await poolsRepository.$getUnknownPool();
 | 
			
		||||
        } else {
 | 
			
		||||
          pool = poolsParser.unknownPool;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (!pool) { // We should never have this situation in practise
 | 
			
		||||
@ -165,13 +170,22 @@ class Blocks {
 | 
			
		||||
   */
 | 
			
		||||
  private async $findBlockMiner(txMinerInfo: TransactionMinerInfo | undefined): Promise<PoolTag> {
 | 
			
		||||
    if (txMinerInfo === undefined || txMinerInfo.vout.length < 1) {
 | 
			
		||||
      if (config.DATABASE.ENABLED === true) {
 | 
			
		||||
        return await poolsRepository.$getUnknownPool();
 | 
			
		||||
      } else {
 | 
			
		||||
        return poolsParser.unknownPool;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const asciiScriptSig = transactionUtils.hex2ascii(txMinerInfo.vin[0].scriptsig);
 | 
			
		||||
    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) {
 | 
			
		||||
      if (address !== undefined) {
 | 
			
		||||
        const addresses: string[] = JSON.parse(pools[i].addresses);
 | 
			
		||||
@ -190,7 +204,11 @@ class Blocks {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (config.DATABASE.ENABLED === true) {
 | 
			
		||||
      return await poolsRepository.$getUnknownPool();
 | 
			
		||||
    } else {
 | 
			
		||||
      return poolsParser.unknownPool;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,14 @@ interface Pool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class PoolsParser {
 | 
			
		||||
  miningPools: any[] = [];
 | 
			
		||||
  unknownPool: any = {
 | 
			
		||||
    'name': "Unknown",
 | 
			
		||||
    'link': "https://learnmeabitcoin.com/technical/coinbase-transaction",
 | 
			
		||||
    'regexes': "[]",
 | 
			
		||||
    'addresses': "[]",
 | 
			
		||||
    'slug': 'unknown'
 | 
			
		||||
  };
 | 
			
		||||
  slugWarnFlag = false;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@ -60,12 +68,18 @@ class PoolsParser {
 | 
			
		||||
    // Get existing pools from the db
 | 
			
		||||
    let existingPools;
 | 
			
		||||
    try {
 | 
			
		||||
      if (config.DATABASE.ENABLED === true) {
 | 
			
		||||
        [existingPools] = await DB.query({ sql: 'SELECT * FROM pools;', timeout: 120000 });
 | 
			
		||||
      } else {
 | 
			
		||||
        existingPools = [];
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.err('Cannot get existing pools from the database, skipping pools.json import');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.miningPools = [];
 | 
			
		||||
 | 
			
		||||
    // Finally, we generate the final consolidated pools data
 | 
			
		||||
    const finalPoolDataAdd: Pool[] = [];
 | 
			
		||||
    const finalPoolDataUpdate: Pool[] = [];
 | 
			
		||||
@ -97,24 +111,33 @@ class PoolsParser {
 | 
			
		||||
        logger.warn(`No slug found for '${poolNames[i]}', generating it => '${slug}'`);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (existingPools.find((pool) => pool.name === poolNames[i]) !== undefined) {
 | 
			
		||||
        finalPoolDataUpdate.push({
 | 
			
		||||
      const poolObj = {
 | 
			
		||||
        'name': finalPoolName,
 | 
			
		||||
        'link': match[0].link,
 | 
			
		||||
        'regexes': allRegexes,
 | 
			
		||||
        'addresses': allAddresses,
 | 
			
		||||
        'slug': slug
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      if (existingPools.find((pool) => pool.name === poolNames[i]) !== undefined) {
 | 
			
		||||
        finalPoolDataUpdate.push(poolObj);
 | 
			
		||||
      } else {
 | 
			
		||||
        logger.debug(`Add '${finalPoolName}' mining pool`);
 | 
			
		||||
        finalPoolDataAdd.push({
 | 
			
		||||
        finalPoolDataAdd.push(poolObj);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.miningPools.push({
 | 
			
		||||
        'name': finalPoolName,
 | 
			
		||||
        'link': match[0].link,
 | 
			
		||||
          'regexes': allRegexes,
 | 
			
		||||
          'addresses': allAddresses,
 | 
			
		||||
        '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`);
 | 
			
		||||
@ -124,11 +147,11 @@ class PoolsParser {
 | 
			
		||||
    for (let i = 0; i < finalPoolDataAdd.length; ++i) {
 | 
			
		||||
      queryAdd += `('${finalPoolDataAdd[i].name}', '${finalPoolDataAdd[i].link}',
 | 
			
		||||
      '${JSON.stringify(finalPoolDataAdd[i].regexes)}', '${JSON.stringify(finalPoolDataAdd[i].addresses)}',
 | 
			
		||||
      ${JSON.stringify(finalPoolDataAdd[i].slug)}),`;
 | 
			
		||||
      ${finalPoolDataAdd[i].slug}),`;
 | 
			
		||||
    }
 | 
			
		||||
    queryAdd = queryAdd.slice(0, -1) + ';';
 | 
			
		||||
 | 
			
		||||
    // Add new mining pools into the database
 | 
			
		||||
    // Updated existing mining pools in the database
 | 
			
		||||
    const updateQueries: string[] = [];
 | 
			
		||||
    for (let i = 0; i < finalPoolDataUpdate.length; ++i) {
 | 
			
		||||
      updateQueries.push(`
 | 
			
		||||
 | 
			
		||||
@ -22,12 +22,20 @@ import { PoolOptions } from 'mysql2/typings/mysql';
 | 
			
		||||
    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?) {
 | 
			
		||||
    this.checkDBFlag();
 | 
			
		||||
    const pool = await this.getPool();
 | 
			
		||||
    return pool.query(query, params);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async checkDbConnection() {
 | 
			
		||||
    this.checkDBFlag();
 | 
			
		||||
    try {
 | 
			
		||||
      await this.query('SELECT ?', [1]);
 | 
			
		||||
      logger.info('Database connection established.');
 | 
			
		||||
 | 
			
		||||
@ -13,8 +13,10 @@ class Indexer {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public reindex() {
 | 
			
		||||
    if (Common.indexingEnabled()) {
 | 
			
		||||
      this.runIndexer = true;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async $run() {
 | 
			
		||||
    if (!Common.indexingEnabled() || this.runIndexer === false ||
 | 
			
		||||
 | 
			
		||||
@ -11,12 +11,13 @@ import * as https from 'https';
 | 
			
		||||
 */
 | 
			
		||||
class PoolsUpdater {
 | 
			
		||||
  lastRun: number = 0;
 | 
			
		||||
  currentSha: any = undefined;
 | 
			
		||||
 | 
			
		||||
  constructor() {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -38,14 +39,17 @@ class PoolsUpdater {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      const dbSha = await this.getShaFromDb();
 | 
			
		||||
      const githubSha = await this.fetchPoolsSha(); // Fetch pools.json sha from github
 | 
			
		||||
      if (githubSha === undefined) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      logger.debug(`Pools.json sha | Current: ${dbSha} | Github: ${githubSha}`);
 | 
			
		||||
      if (dbSha !== undefined && dbSha === githubSha) {
 | 
			
		||||
      if (config.DATABASE.ENABLED === true) {
 | 
			
		||||
        this.currentSha = await this.getShaFromDb();      
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      logger.debug(`Pools.json sha | Current: ${this.currentSha} | Github: ${githubSha}`);
 | 
			
		||||
      if (this.currentSha !== undefined && this.currentSha === githubSha) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
@ -68,12 +72,14 @@ class PoolsUpdater {
 | 
			
		||||
   * Fetch our latest pools.json sha from the db
 | 
			
		||||
   */
 | 
			
		||||
  private async updateDBSha(githubSha: string) {
 | 
			
		||||
    this.currentSha = githubSha;
 | 
			
		||||
    if (config.DATABASE.ENABLED === true) {
 | 
			
		||||
      try {
 | 
			
		||||
        await DB.query('DELETE FROM state where name="pools_json_sha"');
 | 
			
		||||
        await DB.query(`INSERT INTO state VALUES('pools_json_sha', NULL, '${githubSha}')`);
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        logger.err('Cannot save github pools.json sha into the db. Reason: '  + (e instanceof Error ? e.message : e));
 | 
			
		||||
      return undefined;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user