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 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() {
 | 
				
			||||||
 | 
				
			|||||||
@ -11,12 +11,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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -38,14 +39,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;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -68,12 +72,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));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user