diff --git a/backend/README.md b/backend/README.md index 3d7c23eaa..d00dc1812 100644 --- a/backend/README.md +++ b/backend/README.md @@ -218,3 +218,21 @@ Generate block at regular interval (every 10 seconds in this example): ``` watch -n 10 "./src/bitcoin-cli -regtest -rpcport=8332 generatetoaddress 1 $address" ``` + +### Re-index tables + +You can manually force the nodejs backend to drop all data from a specified set of tables for future re-index. This is mostly useful for the mining dashboard and the lightning explorer. + +Use the `--reindex` command to specify a list of comma separated table which will be truncated at start. Note that a 5 seconds delay will be observed before truncating tables in order to give you a chance to cancel (CTRL+C) in case of misuse of the command. + +Usage: +``` +npm run start --reindex=blocks,hashrates +``` +Example output: +``` +Feb 13 14:55:27 [63246] WARN: Indexed data for "hashrates" tables will be erased in 5 seconds (using '--reindex') +Feb 13 14:55:32 [63246] NOTICE: Table hashrates has been truncated +``` + +Reference: https://github.com/mempool/mempool/pull/1269 \ No newline at end of file diff --git a/backend/mempool-config.sample.json b/backend/mempool-config.sample.json index f8417f0e7..5ebb25ea5 100644 --- a/backend/mempool-config.sample.json +++ b/backend/mempool-config.sample.json @@ -15,7 +15,6 @@ "MEMPOOL_BLOCKS_AMOUNT": 8, "INDEXING_BLOCKS_AMOUNT": 11000, "BLOCKS_SUMMARIES_INDEXING": false, - "PRICE_FEED_UPDATE_INTERVAL": 600, "USE_SECOND_NODE_FOR_MINFEE": false, "EXTERNAL_ASSETS": [], "EXTERNAL_MAX_RETRY": 1, diff --git a/backend/src/__fixtures__/mempool-config.template.json b/backend/src/__fixtures__/mempool-config.template.json index f15d9c328..9d8a7e900 100644 --- a/backend/src/__fixtures__/mempool-config.template.json +++ b/backend/src/__fixtures__/mempool-config.template.json @@ -16,7 +16,6 @@ "BLOCK_WEIGHT_UNITS": 6, "INITIAL_BLOCKS_AMOUNT": 7, "MEMPOOL_BLOCKS_AMOUNT": 8, - "PRICE_FEED_UPDATE_INTERVAL": 9, "USE_SECOND_NODE_FOR_MINFEE": 10, "EXTERNAL_ASSETS": 11, "EXTERNAL_MAX_RETRY": 12, diff --git a/backend/src/__tests__/config.test.ts b/backend/src/__tests__/config.test.ts index 88083f479..8b011d833 100644 --- a/backend/src/__tests__/config.test.ts +++ b/backend/src/__tests__/config.test.ts @@ -29,7 +29,6 @@ describe('Mempool Backend Config', () => { INITIAL_BLOCKS_AMOUNT: 8, MEMPOOL_BLOCKS_AMOUNT: 8, INDEXING_BLOCKS_AMOUNT: 11000, - PRICE_FEED_UPDATE_INTERVAL: 600, USE_SECOND_NODE_FOR_MINFEE: false, EXTERNAL_ASSETS: [], EXTERNAL_MAX_RETRY: 1, diff --git a/backend/src/api/bitcoin/esplora-api.ts b/backend/src/api/bitcoin/esplora-api.ts index 37f6e5892..0366695d1 100644 --- a/backend/src/api/bitcoin/esplora-api.ts +++ b/backend/src/api/bitcoin/esplora-api.ts @@ -1,8 +1,13 @@ import config from '../../config'; import axios, { AxiosRequestConfig } from 'axios'; +import http from 'http'; import { AbstractBitcoinApi } from './bitcoin-api-abstract-factory'; import { IEsploraApi } from './esplora-api.interface'; +const axiosConnection = axios.create({ + httpAgent: new http.Agent({ keepAlive: true }) +}); + class ElectrsApi implements AbstractBitcoinApi { axiosConfig: AxiosRequestConfig = { timeout: 10000, @@ -11,52 +16,52 @@ class ElectrsApi implements AbstractBitcoinApi { constructor() { } $getRawMempool(): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/mempool/txids', this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/mempool/txids', this.axiosConfig) .then((response) => response.data); } $getRawTransaction(txId: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/tx/' + txId, this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/tx/' + txId, this.axiosConfig) .then((response) => response.data); } $getTransactionHex(txId: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/hex', this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/hex', this.axiosConfig) .then((response) => response.data); } $getBlockHeightTip(): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/blocks/tip/height', this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/blocks/tip/height', this.axiosConfig) .then((response) => response.data); } $getBlockHashTip(): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/blocks/tip/hash', this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/blocks/tip/hash', this.axiosConfig) .then((response) => response.data); } $getTxIdsForBlock(hash: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/block/' + hash + '/txids', this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/block/' + hash + '/txids', this.axiosConfig) .then((response) => response.data); } $getBlockHash(height: number): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/block-height/' + height, this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/block-height/' + height, this.axiosConfig) .then((response) => response.data); } $getBlockHeader(hash: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/block/' + hash + '/header', this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/block/' + hash + '/header', this.axiosConfig) .then((response) => response.data); } $getBlock(hash: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/block/' + hash, this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/block/' + hash, this.axiosConfig) .then((response) => response.data); } $getRawBlock(hash: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/block/' + hash + "/raw", { ...this.axiosConfig, responseType: 'arraybuffer' }) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/block/' + hash + "/raw", { ...this.axiosConfig, responseType: 'arraybuffer' }) .then((response) => { return Buffer.from(response.data); }); } @@ -77,12 +82,12 @@ class ElectrsApi implements AbstractBitcoinApi { } $getOutspend(txId: string, vout: number): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/outspend/' + vout, this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/outspend/' + vout, this.axiosConfig) .then((response) => response.data); } $getOutspends(txId: string): Promise { - return axios.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/outspends', this.axiosConfig) + return axiosConnection.get(config.ESPLORA.REST_API_URL + '/tx/' + txId + '/outspends', this.axiosConfig) .then((response) => response.data); } diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index 84c919e5d..d110186f5 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -600,9 +600,11 @@ class Blocks { * Index a block if it's missing from the database. Returns the block after indexing */ public async $indexBlock(height: number): Promise { - const dbBlock = await blocksRepository.$getBlockByHeight(height); - if (dbBlock != null) { - return prepareBlock(dbBlock); + if (Common.indexingEnabled()) { + const dbBlock = await blocksRepository.$getBlockByHeight(height); + if (dbBlock !== null) { + return prepareBlock(dbBlock); + } } const blockHash = await bitcoinApi.$getBlockHash(height); @@ -610,7 +612,9 @@ class Blocks { const transactions = await this.$getTransactionsExtended(blockHash, block.height, true); const blockExtended = await this.$getBlockExtended(block, transactions); - await blocksRepository.$saveBlockInDatabase(blockExtended); + if (Common.indexingEnabled()) { + await blocksRepository.$saveBlockInDatabase(blockExtended); + } return prepareBlock(blockExtended); } @@ -714,7 +718,7 @@ class Blocks { block = await this.$indexBlock(currentHeight); returnBlocks.push(block); } else if (nextHash != null) { - block = prepareBlock(await bitcoinClient.getBlock(nextHash)); + block = await this.$indexBlock(currentHeight); nextHash = block.previousblockhash; returnBlocks.push(block); } diff --git a/backend/src/config.ts b/backend/src/config.ts index a5736996f..2cda8d85b 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -19,7 +19,6 @@ interface IConfig { MEMPOOL_BLOCKS_AMOUNT: number; INDEXING_BLOCKS_AMOUNT: number; BLOCKS_SUMMARIES_INDEXING: boolean; - PRICE_FEED_UPDATE_INTERVAL: number; USE_SECOND_NODE_FOR_MINFEE: boolean; EXTERNAL_ASSETS: string[]; EXTERNAL_MAX_RETRY: number; @@ -141,7 +140,6 @@ const defaults: IConfig = { 'MEMPOOL_BLOCKS_AMOUNT': 8, 'INDEXING_BLOCKS_AMOUNT': 11000, // 0 = disable indexing, -1 = index all blocks 'BLOCKS_SUMMARIES_INDEXING': false, - 'PRICE_FEED_UPDATE_INTERVAL': 600, 'USE_SECOND_NODE_FOR_MINFEE': false, 'EXTERNAL_ASSETS': [], 'EXTERNAL_MAX_RETRY': 1, diff --git a/backend/src/index.ts b/backend/src/index.ts index a81275066..919c039c3 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -36,6 +36,7 @@ import bitcoinRoutes from './api/bitcoin/bitcoin.routes'; import fundingTxFetcher from './tasks/lightning/sync-tasks/funding-tx-fetcher'; import forensicsService from './tasks/lightning/forensics.service'; import priceUpdater from './tasks/price-updater'; +import { AxiosError } from 'axios'; class Server { private wss: WebSocket.Server | undefined; @@ -178,7 +179,7 @@ class Server { setTimeout(this.runMainUpdateLoop.bind(this), config.MEMPOOL.POLL_RATE_MS); this.currentBackendRetryInterval = 5; - } catch (e) { + } catch (e: any) { const loggerMsg = `runMainLoop error: ${(e instanceof Error ? e.message : e)}. Retrying in ${this.currentBackendRetryInterval} sec.`; if (this.currentBackendRetryInterval > 5) { logger.warn(loggerMsg); @@ -186,7 +187,9 @@ class Server { } else { logger.debug(loggerMsg); } - logger.debug(JSON.stringify(e)); + if (e instanceof AxiosError) { + logger.debug(`AxiosError: ${e?.message}`); + } setTimeout(this.runMainUpdateLoop.bind(this), 1000 * this.currentBackendRetryInterval); this.currentBackendRetryInterval *= 2; this.currentBackendRetryInterval = Math.min(this.currentBackendRetryInterval, 60); diff --git a/backend/src/tasks/price-feeds/bitfinex-api.ts b/backend/src/tasks/price-feeds/bitfinex-api.ts index 04bd47732..0e06c3af7 100644 --- a/backend/src/tasks/price-feeds/bitfinex-api.ts +++ b/backend/src/tasks/price-feeds/bitfinex-api.ts @@ -13,7 +13,11 @@ class BitfinexApi implements PriceFeed { public async $fetchPrice(currency): Promise { const response = await query(this.url + currency); - return response ? parseInt(response['last_price'], 10) : -1; + if (response && response['last_price']) { + return parseInt(response['last_price'], 10); + } else { + return -1; + } } public async $fetchRecentPrice(currencies: string[], type: 'hour' | 'day'): Promise { diff --git a/backend/src/tasks/price-feeds/bitflyer-api.ts b/backend/src/tasks/price-feeds/bitflyer-api.ts index 143fbe8d9..72b2e6adf 100644 --- a/backend/src/tasks/price-feeds/bitflyer-api.ts +++ b/backend/src/tasks/price-feeds/bitflyer-api.ts @@ -13,7 +13,11 @@ class BitflyerApi implements PriceFeed { public async $fetchPrice(currency): Promise { const response = await query(this.url + currency); - return response ? parseInt(response['ltp'], 10) : -1; + if (response && response['ltp']) { + return parseInt(response['ltp'], 10); + } else { + return -1; + } } public async $fetchRecentPrice(currencies: string[], type: 'hour' | 'day'): Promise { diff --git a/backend/src/tasks/price-feeds/coinbase-api.ts b/backend/src/tasks/price-feeds/coinbase-api.ts index ef28b0d80..424ac8867 100644 --- a/backend/src/tasks/price-feeds/coinbase-api.ts +++ b/backend/src/tasks/price-feeds/coinbase-api.ts @@ -13,7 +13,11 @@ class CoinbaseApi implements PriceFeed { public async $fetchPrice(currency): Promise { const response = await query(this.url + currency); - return response ? parseInt(response['data']['amount'], 10) : -1; + if (response && response['data'] && response['data']['amount']) { + return parseInt(response['data']['amount'], 10); + } else { + return -1; + } } public async $fetchRecentPrice(currencies: string[], type: 'hour' | 'day'): Promise { diff --git a/backend/src/tasks/price-feeds/gemini-api.ts b/backend/src/tasks/price-feeds/gemini-api.ts index abd8e0939..fc86dc0a3 100644 --- a/backend/src/tasks/price-feeds/gemini-api.ts +++ b/backend/src/tasks/price-feeds/gemini-api.ts @@ -13,7 +13,11 @@ class GeminiApi implements PriceFeed { public async $fetchPrice(currency): Promise { const response = await query(this.url + currency); - return response ? parseInt(response['last'], 10) : -1; + if (response && response['last']) { + return parseInt(response['last'], 10); + } else { + return -1; + } } public async $fetchRecentPrice(currencies: string[], type: 'hour' | 'day'): Promise { diff --git a/backend/src/tasks/price-feeds/kraken-api.ts b/backend/src/tasks/price-feeds/kraken-api.ts index ea02a772d..c6b3c0c11 100644 --- a/backend/src/tasks/price-feeds/kraken-api.ts +++ b/backend/src/tasks/price-feeds/kraken-api.ts @@ -23,7 +23,14 @@ class KrakenApi implements PriceFeed { public async $fetchPrice(currency): Promise { const response = await query(this.url + currency); - return response ? parseInt(response['result'][this.getTicker(currency)]['c'][0], 10) : -1; + const ticker = this.getTicker(currency); + if (response && response['result'] && response['result'][ticker] && + response['result'][ticker]['c'] && response['result'][ticker]['c'].length > 0 + ) { + return parseInt(response['result'][ticker]['c'][0], 10); + } else { + return -1; + } } public async $fetchRecentPrice(currencies: string[], type: 'hour' | 'day'): Promise { diff --git a/backend/src/tasks/price-updater.ts b/backend/src/tasks/price-updater.ts index e42c5887a..939a1ea85 100644 --- a/backend/src/tasks/price-updater.ts +++ b/backend/src/tasks/price-updater.ts @@ -130,7 +130,11 @@ class PriceUpdater { // Compute average price, non weighted prices = prices.filter(price => price > 0); - this.latestPrices[currency] = Math.round((prices.reduce((partialSum, a) => partialSum + a, 0)) / prices.length); + if (prices.length === 0) { + this.latestPrices[currency] = -1; + } else { + this.latestPrices[currency] = Math.round((prices.reduce((partialSum, a) => partialSum + a, 0)) / prices.length); + } } logger.info(`Latest BTC fiat averaged price: ${JSON.stringify(this.latestPrices)}`); diff --git a/backend/src/utils/blocks-utils.ts b/backend/src/utils/blocks-utils.ts index b933d6ae7..43a2fc964 100644 --- a/backend/src/utils/blocks-utils.ts +++ b/backend/src/utils/blocks-utils.ts @@ -17,7 +17,7 @@ export function prepareBlock(block: any): BlockExtended { extras: { coinbaseRaw: block.coinbase_raw ?? block.extras?.coinbaseRaw, medianFee: block.medianFee ?? block.median_fee ?? block.extras?.medianFee, - feeRange: block.feeRange ?? block.fee_span, + feeRange: block.feeRange ?? block?.extras?.feeRange ?? block.fee_span, reward: block.reward ?? block?.extras?.reward, totalFees: block.totalFees ?? block?.fees ?? block?.extras?.totalFees, avgFee: block?.extras?.avgFee ?? block.avg_fee, diff --git a/docker/README.md b/docker/README.md index 1c10a5e15..69bb96030 100644 --- a/docker/README.md +++ b/docker/README.md @@ -101,7 +101,6 @@ Below we list all settings from `mempool-config.json` and the corresponding over "INITIAL_BLOCKS_AMOUNT": 8, "MEMPOOL_BLOCKS_AMOUNT": 8, "BLOCKS_SUMMARIES_INDEXING": false, - "PRICE_FEED_UPDATE_INTERVAL": 600, "USE_SECOND_NODE_FOR_MINFEE": false, "EXTERNAL_ASSETS": ["https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json"], "STDOUT_LOG_MIN_PRIORITY": "info", @@ -132,7 +131,6 @@ Corresponding `docker-compose.yml` overrides: MEMPOOL_INITIAL_BLOCKS_AMOUNT: "" MEMPOOL_MEMPOOL_BLOCKS_AMOUNT: "" MEMPOOL_BLOCKS_SUMMARIES_INDEXING: "" - MEMPOOL_PRICE_FEED_UPDATE_INTERVAL: "" MEMPOOL_USE_SECOND_NODE_FOR_MINFEE: "" MEMPOOL_EXTERNAL_ASSETS: "" MEMPOOL_STDOUT_LOG_MIN_PRIORITY: "" diff --git a/docker/backend/mempool-config.json b/docker/backend/mempool-config.json index 17901acc4..904370f3e 100644 --- a/docker/backend/mempool-config.json +++ b/docker/backend/mempool-config.json @@ -13,7 +13,6 @@ "BLOCK_WEIGHT_UNITS": __MEMPOOL_BLOCK_WEIGHT_UNITS__, "INITIAL_BLOCKS_AMOUNT": __MEMPOOL_INITIAL_BLOCKS_AMOUNT__, "MEMPOOL_BLOCKS_AMOUNT": __MEMPOOL_MEMPOOL_BLOCKS_AMOUNT__, - "PRICE_FEED_UPDATE_INTERVAL": __MEMPOOL_PRICE_FEED_UPDATE_INTERVAL__, "USE_SECOND_NODE_FOR_MINFEE": __MEMPOOL_USE_SECOND_NODE_FOR_MINFEE__, "EXTERNAL_ASSETS": __MEMPOOL_EXTERNAL_ASSETS__, "EXTERNAL_MAX_RETRY": __MEMPOOL_EXTERNAL_MAX_RETRY__, diff --git a/docker/backend/start.sh b/docker/backend/start.sh index e02706bce..58b19898a 100755 --- a/docker/backend/start.sh +++ b/docker/backend/start.sh @@ -16,7 +16,6 @@ __MEMPOOL_INITIAL_BLOCKS_AMOUNT__=${MEMPOOL_INITIAL_BLOCKS_AMOUNT:=8} __MEMPOOL_MEMPOOL_BLOCKS_AMOUNT__=${MEMPOOL_MEMPOOL_BLOCKS_AMOUNT:=8} __MEMPOOL_INDEXING_BLOCKS_AMOUNT__=${MEMPOOL_INDEXING_BLOCKS_AMOUNT:=11000} __MEMPOOL_BLOCKS_SUMMARIES_INDEXING__=${MEMPOOL_BLOCKS_SUMMARIES_INDEXING:=false} -__MEMPOOL_PRICE_FEED_UPDATE_INTERVAL__=${MEMPOOL_PRICE_FEED_UPDATE_INTERVAL:=600} __MEMPOOL_USE_SECOND_NODE_FOR_MINFEE__=${MEMPOOL_USE_SECOND_NODE_FOR_MINFEE:=false} __MEMPOOL_EXTERNAL_ASSETS__=${MEMPOOL_EXTERNAL_ASSETS:=[]} __MEMPOOL_EXTERNAL_MAX_RETRY__=${MEMPOOL_EXTERNAL_MAX_RETRY:=1} @@ -129,7 +128,6 @@ sed -i "s/__MEMPOOL_INITIAL_BLOCKS_AMOUNT__/${__MEMPOOL_INITIAL_BLOCKS_AMOUNT__} sed -i "s/__MEMPOOL_MEMPOOL_BLOCKS_AMOUNT__/${__MEMPOOL_MEMPOOL_BLOCKS_AMOUNT__}/g" mempool-config.json sed -i "s/__MEMPOOL_INDEXING_BLOCKS_AMOUNT__/${__MEMPOOL_INDEXING_BLOCKS_AMOUNT__}/g" mempool-config.json sed -i "s/__MEMPOOL_BLOCKS_SUMMARIES_INDEXING__/${__MEMPOOL_BLOCKS_SUMMARIES_INDEXING__}/g" mempool-config.json -sed -i "s/__MEMPOOL_PRICE_FEED_UPDATE_INTERVAL__/${__MEMPOOL_PRICE_FEED_UPDATE_INTERVAL__}/g" mempool-config.json sed -i "s/__MEMPOOL_USE_SECOND_NODE_FOR_MINFEE__/${__MEMPOOL_USE_SECOND_NODE_FOR_MINFEE__}/g" mempool-config.json sed -i "s!__MEMPOOL_EXTERNAL_ASSETS__!${__MEMPOOL_EXTERNAL_ASSETS__}!g" mempool-config.json sed -i "s!__MEMPOOL_EXTERNAL_MAX_RETRY__!${__MEMPOOL_EXTERNAL_MAX_RETRY__}!g" mempool-config.json diff --git a/frontend/.tx/config b/frontend/.tx/config index 3016be606..825e77ddc 100644 --- a/frontend/.tx/config +++ b/frontend/.tx/config @@ -1,7 +1,9 @@ [main] host = https://www.transifex.com -[mempool.frontend-src-locale-messages-xlf--master] +[o:mempool:p:mempool:r:frontend-src-locale-messages-xlf--master] file_filter = frontend/src/locale/messages..xlf +source_file = frontend/src/locale/messages.en-US.xlf source_lang = en-US -type = XLIFF +type = XLIFF + diff --git a/frontend/cypress/e2e/mainnet/mainnet.spec.ts b/frontend/cypress/e2e/mainnet/mainnet.spec.ts index d6fe94dac..5ab3f9ce9 100644 --- a/frontend/cypress/e2e/mainnet/mainnet.spec.ts +++ b/frontend/cypress/e2e/mainnet/mainnet.spec.ts @@ -64,7 +64,7 @@ describe('Mainnet', () => { it('loads the status screen', () => { cy.visit('/status'); cy.get('#mempool-block-0').should('be.visible'); - cy.get('[id^="bitcoin-block-"]').should('have.length', 8); + cy.get('[id^="bitcoin-block-"]').should('have.length', 22); cy.get('.footer').should('be.visible'); cy.get('.row > :nth-child(1)').invoke('text').then((text) => { expect(text).to.match(/Incoming transactions.* vB\/s/); @@ -219,11 +219,11 @@ describe('Mainnet', () => { describe('blocks navigation', () => { describe('keyboard events', () => { - it('loads first blockchain blocks visible and keypress arrow right', () => { + it('loads first blockchain block visible and keypress arrow right', () => { cy.viewport('macbook-16'); cy.visit('/'); cy.waitForSkeletonGone(); - cy.get('.blockchain-blocks-0 > a').click().then(() => { + cy.get('[data-cy="bitcoin-block-offset-0-index-0"]').click().then(() => { cy.get('[ngbtooltip="Next Block"] > .ng-fa-icon > .svg-inline--fa').should('not.exist'); cy.get('[ngbtooltip="Previous Block"] > .ng-fa-icon > .svg-inline--fa').should('be.visible'); cy.waitForPageIdle(); @@ -233,11 +233,11 @@ describe('Mainnet', () => { }); }); - it('loads first blockchain blocks visible and keypress arrow left', () => { + it('loads first blockchain block visible and keypress arrow left', () => { cy.viewport('macbook-16'); cy.visit('/'); cy.waitForSkeletonGone(); - cy.get('.blockchain-blocks-0 > a').click().then(() => { + cy.get('[data-cy="bitcoin-block-offset-0-index-0"]').click().then(() => { cy.waitForPageIdle(); cy.get('[ngbtooltip="Next Block"] > .ng-fa-icon > .svg-inline--fa').should('not.exist'); cy.get('[ngbtooltip="Previous Block"] > .ng-fa-icon > .svg-inline--fa').should('be.visible'); @@ -246,11 +246,11 @@ describe('Mainnet', () => { }); }); - it('loads last blockchain blocks and keypress arrow right', () => { + it.skip('loads last blockchain block and keypress arrow right', () => { //Skip for now as "last" doesn't really work with infinite scrolling cy.viewport('macbook-16'); cy.visit('/'); cy.waitForSkeletonGone(); - cy.get('.blockchain-blocks-4 > a').click().then(() => { + cy.get('bitcoin-block-offset-0-index-7').click().then(() => { cy.waitForPageIdle(); // block 6 @@ -309,7 +309,7 @@ describe('Mainnet', () => { cy.viewport('macbook-16'); cy.visit('/'); cy.waitForSkeletonGone(); - cy.get('.blockchain-blocks-0 > a').click().then(() => { + cy.get('[data-cy="bitcoin-block-offset-0-index-0"]').click().then(() => { cy.waitForPageIdle(); cy.get('[ngbtooltip="Next Block"] > .ng-fa-icon > .svg-inline--fa').should('not.exist'); cy.get('[ngbtooltip="Previous Block"] > .ng-fa-icon > .svg-inline--fa').should('be.visible'); diff --git a/frontend/src/app/app.constants.ts b/frontend/src/app/app.constants.ts index 5cc446dbf..8a954166e 100644 --- a/frontend/src/app/app.constants.ts +++ b/frontend/src/app/app.constants.ts @@ -72,22 +72,10 @@ export const chartColors = [ ]; export const poolsColor = { - 'foundryusa': '#D81B60', - 'antpool': '#8E24AA', - 'f2pool': '#5E35B1', - 'poolin': '#3949AB', - 'binancepool': '#1E88E5', - 'viabtc': '#039BE5', - 'btccom': '#00897B', - 'braiinspool': '#00ACC1', - 'sbicrypto': '#43A047', - 'marapool': '#7CB342', - 'luxor': '#C0CA33', - 'unknown': '#FDD835', - 'okkong': '#FFB300', -} + 'unknown': '#9C9C9C', +}; - export const feeLevels = [1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200, +export const feeLevels = [1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 20, 30, 40, 50, 60, 70, 80, 90, 100, 125, 150, 175, 200, 250, 300, 350, 400, 500, 600, 700, 800, 900, 1000, 1200, 1400, 1600, 1800, 2000]; export interface Language { diff --git a/frontend/src/app/components/address/address.component.html b/frontend/src/app/components/address/address.component.html index d3b23315a..ae2d7ba9c 100644 --- a/frontend/src/app/components/address/address.component.html +++ b/frontend/src/app/components/address/address.component.html @@ -1,4 +1,4 @@ -
+

Address