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 BlocksRepository from '../repositories/BlocksRepository';
 | 
				
			||||||
import HashratesRepository from '../repositories/HashratesRepository';
 | 
					import HashratesRepository from '../repositories/HashratesRepository';
 | 
				
			||||||
import indexer from '../indexer';
 | 
					import indexer from '../indexer';
 | 
				
			||||||
 | 
					import fiatConversion from './fiat-conversion';
 | 
				
			||||||
 | 
					import RatesRepository from '../repositories/RatesRepository';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Blocks {
 | 
					class Blocks {
 | 
				
			||||||
  private blocks: BlockExtended[] = [];
 | 
					  private blocks: BlockExtended[] = [];
 | 
				
			||||||
@ -312,6 +314,8 @@ class Blocks {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const currentUsdPrice = fiatConversion.getConversionRates().USD;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (this.currentBlockHeight < blockHeightTip) {
 | 
					    while (this.currentBlockHeight < blockHeightTip) {
 | 
				
			||||||
      if (this.currentBlockHeight < blockHeightTip - config.MEMPOOL.INITIAL_BLOCKS_AMOUNT) {
 | 
					      if (this.currentBlockHeight < blockHeightTip - config.MEMPOOL.INITIAL_BLOCKS_AMOUNT) {
 | 
				
			||||||
        this.currentBlockHeight = blockHeightTip;
 | 
					        this.currentBlockHeight = blockHeightTip;
 | 
				
			||||||
@ -341,6 +345,9 @@ class Blocks {
 | 
				
			|||||||
          await blocksRepository.$saveBlockInDatabase(blockExtended);
 | 
					          await blocksRepository.$saveBlockInDatabase(blockExtended);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      if (fiatConversion.ratesInitialized === true) {
 | 
				
			||||||
 | 
					        await RatesRepository.$saveRate(blockExtended.height, fiatConversion.getConversionRates());
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (block.height % 2016 === 0) {
 | 
					      if (block.height % 2016 === 0) {
 | 
				
			||||||
        this.previousDifficultyRetarget = (block.difficulty - this.currentDifficulty) / this.currentDifficulty * 100;
 | 
					        this.previousDifficultyRetarget = (block.difficulty - this.currentDifficulty) / this.currentDifficulty * 100;
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import logger from '../logger';
 | 
				
			|||||||
import { Common } from './common';
 | 
					import { Common } from './common';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DatabaseMigration {
 | 
					class DatabaseMigration {
 | 
				
			||||||
  private static currentVersion = 18;
 | 
					  private static currentVersion = 19;
 | 
				
			||||||
  private queryTimeout = 120000;
 | 
					  private queryTimeout = 120000;
 | 
				
			||||||
  private statisticsAddedIndexed = false;
 | 
					  private statisticsAddedIndexed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -184,6 +184,10 @@ class DatabaseMigration {
 | 
				
			|||||||
      if (databaseSchemaVersion < 18 && isBitcoin === true) {
 | 
					      if (databaseSchemaVersion < 18 && isBitcoin === true) {
 | 
				
			||||||
        await this.$executeQuery('ALTER TABLE `blocks` ADD INDEX `hash` (`hash`);');
 | 
					        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) {
 | 
					    } catch (e) {
 | 
				
			||||||
      throw e;
 | 
					      throw e;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -466,6 +470,14 @@ class DatabaseMigration {
 | 
				
			|||||||
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`;
 | 
					    ) 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[]) {
 | 
					  public async $truncateIndexedData(tables: string[]) {
 | 
				
			||||||
    const allowedTables = ['blocks', 'hashrates'];
 | 
					    const allowedTables = ['blocks', 'hashrates'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -6,12 +6,19 @@ import backendInfo from './backend-info';
 | 
				
			|||||||
import { SocksProxyAgent } from 'socks-proxy-agent';
 | 
					import { SocksProxyAgent } from 'socks-proxy-agent';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FiatConversion {
 | 
					class FiatConversion {
 | 
				
			||||||
  private conversionRates: IConversionRates = {
 | 
					  private debasingFiatCurrencies = ['AED', 'AUD', 'BDT', 'BHD', 'BMD', 'BRL', 'CAD', 'CHF', 'CLP',
 | 
				
			||||||
    'USD': 0
 | 
					    '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;
 | 
					  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) {
 | 
					  public setProgressChangedCallback(fn: (rates: IConversionRates) => void) {
 | 
				
			||||||
    this.ratesChangedCallback = fn;
 | 
					    this.ratesChangedCallback = fn;
 | 
				
			||||||
@ -62,13 +69,14 @@ class FiatConversion {
 | 
				
			|||||||
        response = await axios.get(fiatConversionUrl, { headers: headers, timeout: 10000 });
 | 
					        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 = {
 | 
					      this.ratesInitialized = true;
 | 
				
			||||||
        'USD': usd.price,
 | 
					      logger.debug(`USD Conversion Rate: ${this.conversionRates.USD}`);
 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      logger.debug(`USD Conversion Rate: ${usd.price}`);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (this.ratesChangedCallback) {
 | 
					      if (this.ratesChangedCallback) {
 | 
				
			||||||
        this.ratesChangedCallback(this.conversionRates);
 | 
					        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