Save bisq aggregate exchange rates in the database for each new block
This commit is contained in:
		
							parent
							
								
									b91654886a
								
							
						
					
					
						commit
						875040c329
					
				@ -16,6 +16,8 @@ import { prepareBlock } from '../utils/blocks-utils';
 | 
			
		||||
import BlocksRepository from '../repositories/BlocksRepository';
 | 
			
		||||
import HashratesRepository from '../repositories/HashratesRepository';
 | 
			
		||||
import indexer from '../indexer';
 | 
			
		||||
import fiatConversion from './fiat-conversion';
 | 
			
		||||
import RatesRepository from '../repositories/RatesRepository';
 | 
			
		||||
 | 
			
		||||
class Blocks {
 | 
			
		||||
  private blocks: BlockExtended[] = [];
 | 
			
		||||
@ -312,6 +314,8 @@ class Blocks {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const currentUsdPrice = fiatConversion.getConversionRates().USD;
 | 
			
		||||
 | 
			
		||||
    while (this.currentBlockHeight < blockHeightTip) {
 | 
			
		||||
      if (this.currentBlockHeight < blockHeightTip - config.MEMPOOL.INITIAL_BLOCKS_AMOUNT) {
 | 
			
		||||
        this.currentBlockHeight = blockHeightTip;
 | 
			
		||||
@ -341,6 +345,9 @@ class Blocks {
 | 
			
		||||
          await blocksRepository.$saveBlockInDatabase(blockExtended);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (fiatConversion.ratesInitialized === true) {
 | 
			
		||||
        await RatesRepository.$saveRate(blockExtended.height, fiatConversion.getConversionRates());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (block.height % 2016 === 0) {
 | 
			
		||||
        this.previousDifficultyRetarget = (block.difficulty - this.currentDifficulty) / this.currentDifficulty * 100;
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,7 @@ import logger from '../logger';
 | 
			
		||||
import { Common } from './common';
 | 
			
		||||
 | 
			
		||||
class DatabaseMigration {
 | 
			
		||||
  private static currentVersion = 18;
 | 
			
		||||
  private static currentVersion = 19;
 | 
			
		||||
  private queryTimeout = 120000;
 | 
			
		||||
  private statisticsAddedIndexed = false;
 | 
			
		||||
 | 
			
		||||
@ -184,6 +184,10 @@ class DatabaseMigration {
 | 
			
		||||
      if (databaseSchemaVersion < 18 && isBitcoin === true) {
 | 
			
		||||
        await this.$executeQuery('ALTER TABLE `blocks` ADD INDEX `hash` (`hash`);');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (databaseSchemaVersion < 19 && isBitcoin === true) {
 | 
			
		||||
        await this.$executeQuery(this.getCreateRatesTableQuery(), await this.$checkIfTableExists('rates'));
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      throw e;
 | 
			
		||||
    }
 | 
			
		||||
@ -466,6 +470,14 @@ class DatabaseMigration {
 | 
			
		||||
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getCreateRatesTableQuery(): string {
 | 
			
		||||
    return `CREATE TABLE IF NOT EXISTS rates (
 | 
			
		||||
      height int(10) unsigned NOT NULL,
 | 
			
		||||
      bisq_rates JSON NOT NULL,
 | 
			
		||||
      PRIMARY KEY (height)
 | 
			
		||||
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async $truncateIndexedData(tables: string[]) {
 | 
			
		||||
    const allowedTables = ['blocks', 'hashrates'];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,12 +6,19 @@ import backendInfo from './backend-info';
 | 
			
		||||
import { SocksProxyAgent } from 'socks-proxy-agent';
 | 
			
		||||
 | 
			
		||||
class FiatConversion {
 | 
			
		||||
  private conversionRates: IConversionRates = {
 | 
			
		||||
    'USD': 0
 | 
			
		||||
  };
 | 
			
		||||
  private debasingFiatCurrencies = ['AED', 'AUD', 'BDT', 'BHD', 'BMD', 'BRL', 'CAD', 'CHF', 'CLP',
 | 
			
		||||
    'CNY', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'IDR', 'ILS', 'INR', 'JPY', 'KRW', 'KWD',
 | 
			
		||||
    'LKR', 'MMK', 'MXN', 'MYR', 'NGN', 'NOK', 'NZD', 'PHP', 'PKR', 'PLN', 'RUB', 'SAR', 'SEK',
 | 
			
		||||
    'SGD', 'THB', 'TRY', 'TWD', 'UAH', 'USD', 'VND', 'ZAR'];
 | 
			
		||||
  private conversionRates: IConversionRates = {};
 | 
			
		||||
  private ratesChangedCallback: ((rates: IConversionRates) => void) | undefined;
 | 
			
		||||
  public ratesInitialized = false; // If true, it means rates are ready for use
 | 
			
		||||
 | 
			
		||||
  constructor() { }
 | 
			
		||||
  constructor() {
 | 
			
		||||
    for (const fiat of this.debasingFiatCurrencies) {
 | 
			
		||||
      this.conversionRates[fiat] = 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public setProgressChangedCallback(fn: (rates: IConversionRates) => void) {
 | 
			
		||||
    this.ratesChangedCallback = fn;
 | 
			
		||||
@ -62,13 +69,14 @@ class FiatConversion {
 | 
			
		||||
        response = await axios.get(fiatConversionUrl, { headers: headers, timeout: 10000 });
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const usd = response.data.data.find((item: any) => item.currencyCode === 'USD');
 | 
			
		||||
      for (const rate of response.data.data) {
 | 
			
		||||
        if (this.debasingFiatCurrencies.includes(rate.currencyCode) && rate.provider === 'Bisq-Aggregate') {
 | 
			
		||||
          this.conversionRates[rate.currencyCode] = Math.round(100 * rate.price) / 100;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.conversionRates = {
 | 
			
		||||
        'USD': usd.price,
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      logger.debug(`USD Conversion Rate: ${usd.price}`);
 | 
			
		||||
      this.ratesInitialized = true;
 | 
			
		||||
      logger.debug(`USD Conversion Rate: ${this.conversionRates.USD}`);
 | 
			
		||||
 | 
			
		||||
      if (this.ratesChangedCallback) {
 | 
			
		||||
        this.ratesChangedCallback(this.conversionRates);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										21
									
								
								backend/src/repositories/RatesRepository.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								backend/src/repositories/RatesRepository.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
			
		||||
import DB from '../database';
 | 
			
		||||
import logger from '../logger';
 | 
			
		||||
import { IConversionRates } from '../mempool.interfaces';
 | 
			
		||||
 | 
			
		||||
class RatesRepository {
 | 
			
		||||
  public async $saveRate(height: number, rates: IConversionRates) {
 | 
			
		||||
    try {
 | 
			
		||||
      await DB.query(`INSERT INTO rates(height, bisq_rates) VALUE (?, ?)`, [height, JSON.stringify(rates)]);
 | 
			
		||||
    } catch (e: any) {
 | 
			
		||||
      if (e.errno === 1062) { // ER_DUP_ENTRY - This scenario is possible upon node backend restart
 | 
			
		||||
        logger.debug(`Rate already exists for block ${height}, ignoring`);
 | 
			
		||||
      } else {
 | 
			
		||||
        logger.err(`Cannot save exchange rate into db for block ${height} Reason: ` + (e instanceof Error ? e.message : e));
 | 
			
		||||
        throw e;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new RatesRepository();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user