diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75884def7..2ff25b22f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,7 +9,7 @@ jobs: if: "!contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')" strategy: matrix: - node: ["16.16.0", "18.5.0"] + node: ["16.16.0", "18.14.1"] flavor: ["dev", "prod"] fail-fast: false runs-on: "ubuntu-latest" @@ -55,7 +55,7 @@ jobs: if: "!contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')" strategy: matrix: - node: ["16.15.0", "18.5.0"] + node: ["16.16.0", "18.14.1"] flavor: ["dev", "prod"] fail-fast: false runs-on: "ubuntu-latest" diff --git a/LICENSE b/LICENSE index 966417847..ac267d120 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ The Mempool Open Source Project -Copyright (c) 2019-2022 The Mempool Open Source Project Developers +Copyright (c) 2019-2023 The Mempool Open Source Project Developers This program is free software; you can redistribute it and/or modify it under the terms of (at your option) either: diff --git a/backend/README.md b/backend/README.md index d00dc1812..be85d25af 100644 --- a/backend/README.md +++ b/backend/README.md @@ -160,7 +160,7 @@ npm install -g ts-node nodemon Then, run the watcher: ``` -nodemon src/index.ts --ignore cache/ --ignore pools.json +nodemon src/index.ts --ignore cache/ ``` `nodemon` should be in npm's global binary folder. If needed, you can determine where that is with `npm -g bin`. @@ -219,6 +219,16 @@ Generate block at regular interval (every 10 seconds in this example): watch -n 10 "./src/bitcoin-cli -regtest -rpcport=8332 generatetoaddress 1 $address" ``` +### Mining pools update + +By default, mining pools will be not automatically updated regularly (`config.MEMPOOL.AUTOMATIC_BLOCK_REINDEXING` is set to `false`). + +To manually update your mining pools, you can use the `--update-pools` command line flag when you run the nodejs backend. For example `npm run start --update-pools`. This will trigger the mining pools update and automatically re-index appropriate blocks. + +You can enabled the automatic mining pools update by settings `config.MEMPOOL.AUTOMATIC_BLOCK_REINDEXING` to `true` in your `mempool-config.json`. + +When a `coinbase tag` or `coinbase address` change is detected, all blocks tagged to the `unknown` mining pools (starting from height 130635) will be deleted from the `blocks` table. Additionaly, all blocks which were tagged to the pool which has been updated will also be deleted from the `blocks` table. Of course, those blocks will be automatically reindexed. + ### 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. @@ -235,4 +245,4 @@ Feb 13 14:55:27 [63246] WARN: Indexed data for "hashrates" tables wi 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 +Reference: https://github.com/mempool/mempool/pull/1269 diff --git a/backend/mempool-config.sample.json b/backend/mempool-config.sample.json index 5ebb25ea5..2369b64b5 100644 --- a/backend/mempool-config.sample.json +++ b/backend/mempool-config.sample.json @@ -22,7 +22,7 @@ "USER_AGENT": "mempool", "STDOUT_LOG_MIN_PRIORITY": "debug", "AUTOMATIC_BLOCK_REINDEXING": false, - "POOLS_JSON_URL": "https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json", + "POOLS_JSON_URL": "https://raw.githubusercontent.com/mempool/mining-pools/master/pools-v2.json", "POOLS_JSON_TREE_URL": "https://api.github.com/repos/mempool/mining-pools/git/trees/master", "AUDIT": false, "ADVANCED_GBT_AUDIT": false, diff --git a/backend/src/__fixtures__/mempool-config.template.json b/backend/src/__fixtures__/mempool-config.template.json index 9d8a7e900..2bf52cbcf 100644 --- a/backend/src/__fixtures__/mempool-config.template.json +++ b/backend/src/__fixtures__/mempool-config.template.json @@ -3,12 +3,11 @@ "ENABLED": true, "NETWORK": "__MEMPOOL_NETWORK__", "BACKEND": "__MEMPOOL_BACKEND__", - "ENABLED": true, "BLOCKS_SUMMARIES_INDEXING": true, "HTTP_PORT": 1, "SPAWN_CLUSTER_PROCS": 2, "API_URL_PREFIX": "__MEMPOOL_API_URL_PREFIX__", - "AUTOMATIC_BLOCK_REINDEXING": true, + "AUTOMATIC_BLOCK_REINDEXING": false, "POLL_RATE_MS": 3, "CACHE_DIR": "__MEMPOOL_CACHE_DIR__", "CLEAR_PROTECTION_MINUTES": 4, @@ -28,7 +27,8 @@ "AUDIT": "__MEMPOOL_AUDIT__", "ADVANCED_GBT_AUDIT": "__MEMPOOL_ADVANCED_GBT_AUDIT__", "ADVANCED_GBT_MEMPOOL": "__MEMPOOL_ADVANCED_GBT_MEMPOOL__", - "CPFP_INDEXING": "__MEMPOOL_CPFP_INDEXING__" + "CPFP_INDEXING": "__MEMPOOL_CPFP_INDEXING__", + "MAX_BLOCKS_BULK_QUERY": "__MEMPOOL_MAX_BLOCKS_BULK_QUERY__" }, "CORE_RPC": { "HOST": "__CORE_RPC_HOST__", diff --git a/backend/src/__tests__/config.test.ts b/backend/src/__tests__/config.test.ts index 8b011d833..5717808dd 100644 --- a/backend/src/__tests__/config.test.ts +++ b/backend/src/__tests__/config.test.ts @@ -36,11 +36,12 @@ describe('Mempool Backend Config', () => { USER_AGENT: 'mempool', STDOUT_LOG_MIN_PRIORITY: 'debug', POOLS_JSON_TREE_URL: 'https://api.github.com/repos/mempool/mining-pools/git/trees/master', - POOLS_JSON_URL: 'https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json', + POOLS_JSON_URL: 'https://raw.githubusercontent.com/mempool/mining-pools/master/pools-v2.json', AUDIT: false, ADVANCED_GBT_AUDIT: false, ADVANCED_GBT_MEMPOOL: false, CPFP_INDEXING: false, + MAX_BLOCKS_BULK_QUERY: 0, }); expect(config.ELECTRUM).toStrictEqual({ HOST: '127.0.0.1', PORT: 3306, TLS_ENABLED: true }); diff --git a/backend/src/api/bitcoin/bitcoin-api.ts b/backend/src/api/bitcoin/bitcoin-api.ts index cad11aeda..117245ef8 100644 --- a/backend/src/api/bitcoin/bitcoin-api.ts +++ b/backend/src/api/bitcoin/bitcoin-api.ts @@ -28,6 +28,7 @@ class BitcoinApi implements AbstractBitcoinApi { size: block.size, weight: block.weight, previousblockhash: block.previousblockhash, + medianTime: block.mediantime, }; } diff --git a/backend/src/api/bitcoin/bitcoin.routes.ts b/backend/src/api/bitcoin/bitcoin.routes.ts index ea8154206..78d027663 100644 --- a/backend/src/api/bitcoin/bitcoin.routes.ts +++ b/backend/src/api/bitcoin/bitcoin.routes.ts @@ -95,6 +95,8 @@ class BitcoinRoutes { .get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/summary', this.getStrippedBlockTransactions) .get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/audit-summary', this.getBlockAuditSummary) .post(config.MEMPOOL.API_URL_PREFIX + 'psbt/addparents', this.postPsbtCompletion) + .get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from', this.getBlocksByBulk.bind(this)) + .get(config.MEMPOOL.API_URL_PREFIX + 'blocks-bulk/:from/:to', this.getBlocksByBulk.bind(this)) ; if (config.MEMPOOL.BACKEND !== 'esplora') { @@ -402,6 +404,41 @@ class BitcoinRoutes { } } + private async getBlocksByBulk(req: Request, res: Response) { + try { + if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) === false) { // Liquid, Bisq - Not implemented + return res.status(404).send(`This API is only available for Bitcoin networks`); + } + if (config.MEMPOOL.MAX_BLOCKS_BULK_QUERY <= 0) { + return res.status(404).send(`This API is disabled. Set config.MEMPOOL.MAX_BLOCKS_BULK_QUERY to a positive number to enable it.`); + } + if (!Common.indexingEnabled()) { + return res.status(404).send(`Indexing is required for this API`); + } + + const from = parseInt(req.params.from, 10); + if (!req.params.from || from < 0) { + return res.status(400).send(`Parameter 'from' must be a block height (integer)`); + } + const to = req.params.to === undefined ? await bitcoinApi.$getBlockHeightTip() : parseInt(req.params.to, 10); + if (to < 0) { + return res.status(400).send(`Parameter 'to' must be a block height (integer)`); + } + if (from > to) { + return res.status(400).send(`Parameter 'to' must be a higher block height than 'from'`); + } + if ((to - from + 1) > config.MEMPOOL.MAX_BLOCKS_BULK_QUERY) { + return res.status(400).send(`You can only query ${config.MEMPOOL.MAX_BLOCKS_BULK_QUERY} blocks at once.`); + } + + res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); + res.json(await blocks.$getBlocksBetweenHeight(from, to)); + + } catch (e) { + res.status(500).send(e instanceof Error ? e.message : e); + } + } + private async getLegacyBlocks(req: Request, res: Response) { try { const returnBlocks: IEsploraApi.Block[] = []; diff --git a/backend/src/api/bitcoin/esplora-api.interface.ts b/backend/src/api/bitcoin/esplora-api.interface.ts index 39f8cfd6f..eaf6476f4 100644 --- a/backend/src/api/bitcoin/esplora-api.interface.ts +++ b/backend/src/api/bitcoin/esplora-api.interface.ts @@ -88,6 +88,7 @@ export namespace IEsploraApi { size: number; weight: number; previousblockhash: string; + medianTime?: number; } export interface Address { diff --git a/backend/src/api/blocks.ts b/backend/src/api/blocks.ts index d110186f5..204419496 100644 --- a/backend/src/api/blocks.ts +++ b/backend/src/api/blocks.ts @@ -25,6 +25,7 @@ import mining from './mining/mining'; import DifficultyAdjustmentsRepository from '../repositories/DifficultyAdjustmentsRepository'; import PricesRepository from '../repositories/PricesRepository'; import priceUpdater from '../tasks/price-updater'; +import chainTips from './chain-tips'; class Blocks { private blocks: BlockExtended[] = []; @@ -165,33 +166,80 @@ class Blocks { * @returns BlockExtended */ private async $getBlockExtended(block: IEsploraApi.Block, transactions: TransactionExtended[]): Promise { - const blockExtended: BlockExtended = Object.assign({ extras: {} }, block); - blockExtended.extras.reward = transactions[0].vout.reduce((acc, curr) => acc + curr.value, 0); - blockExtended.extras.coinbaseTx = transactionUtils.stripCoinbaseTransaction(transactions[0]); - blockExtended.extras.coinbaseRaw = blockExtended.extras.coinbaseTx.vin[0].scriptsig; - blockExtended.extras.usd = priceUpdater.latestPrices.USD; + const blk: BlockExtended = Object.assign({ extras: {} }, block); + blk.extras.reward = transactions[0].vout.reduce((acc, curr) => acc + curr.value, 0); + blk.extras.coinbaseTx = transactionUtils.stripCoinbaseTransaction(transactions[0]); + blk.extras.coinbaseRaw = blk.extras.coinbaseTx.vin[0].scriptsig; + blk.extras.usd = priceUpdater.latestPrices.USD; + blk.extras.medianTimestamp = block.medianTime; + blk.extras.orphans = chainTips.getOrphanedBlocksAtHeight(blk.height); if (block.height === 0) { - blockExtended.extras.medianFee = 0; // 50th percentiles - blockExtended.extras.feeRange = [0, 0, 0, 0, 0, 0, 0]; - blockExtended.extras.totalFees = 0; - blockExtended.extras.avgFee = 0; - blockExtended.extras.avgFeeRate = 0; + blk.extras.medianFee = 0; // 50th percentiles + blk.extras.feeRange = [0, 0, 0, 0, 0, 0, 0]; + blk.extras.totalFees = 0; + blk.extras.avgFee = 0; + blk.extras.avgFeeRate = 0; + blk.extras.utxoSetChange = 0; + blk.extras.avgTxSize = 0; + blk.extras.totalInputs = 0; + blk.extras.totalOutputs = 1; + blk.extras.totalOutputAmt = 0; + blk.extras.segwitTotalTxs = 0; + blk.extras.segwitTotalSize = 0; + blk.extras.segwitTotalWeight = 0; } else { - const stats = await bitcoinClient.getBlockStats(block.id, [ - 'feerate_percentiles', 'minfeerate', 'maxfeerate', 'totalfee', 'avgfee', 'avgfeerate' - ]); - blockExtended.extras.medianFee = stats.feerate_percentiles[2]; // 50th percentiles - blockExtended.extras.feeRange = [stats.minfeerate, stats.feerate_percentiles, stats.maxfeerate].flat(); - blockExtended.extras.totalFees = stats.totalfee; - blockExtended.extras.avgFee = stats.avgfee; - blockExtended.extras.avgFeeRate = stats.avgfeerate; + const stats = await bitcoinClient.getBlockStats(block.id); + blk.extras.medianFee = stats.feerate_percentiles[2]; // 50th percentiles + blk.extras.feeRange = [stats.minfeerate, stats.feerate_percentiles, stats.maxfeerate].flat(); + blk.extras.totalFees = stats.totalfee; + blk.extras.avgFee = stats.avgfee; + blk.extras.avgFeeRate = stats.avgfeerate; + blk.extras.utxoSetChange = stats.utxo_increase; + blk.extras.avgTxSize = Math.round(stats.total_size / stats.txs * 100) * 0.01; + blk.extras.totalInputs = stats.ins; + blk.extras.totalOutputs = stats.outs; + blk.extras.totalOutputAmt = stats.total_out; + blk.extras.segwitTotalTxs = stats.swtxs; + blk.extras.segwitTotalSize = stats.swtotal_size; + blk.extras.segwitTotalWeight = stats.swtotal_weight; + } + + if (Common.blocksSummariesIndexingEnabled()) { + blk.extras.feePercentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(block.id); + if (blk.extras.feePercentiles !== null) { + blk.extras.medianFeeAmt = blk.extras.feePercentiles[3]; + } + } + + blk.extras.virtualSize = block.weight / 4.0; + if (blk.extras.coinbaseTx.vout.length > 0) { + blk.extras.coinbaseAddress = blk.extras.coinbaseTx.vout[0].scriptpubkey_address ?? null; + blk.extras.coinbaseSignature = blk.extras.coinbaseTx.vout[0].scriptpubkey_asm ?? null; + blk.extras.coinbaseSignatureAscii = transactionUtils.hex2ascii(blk.extras.coinbaseTx.vin[0].scriptsig) ?? null; + } else { + blk.extras.coinbaseAddress = null; + blk.extras.coinbaseSignature = null; + blk.extras.coinbaseSignatureAscii = null; + } + + const header = await bitcoinClient.getBlockHeader(block.id, false); + blk.extras.header = header; + + const coinStatsIndex = indexer.isCoreIndexReady('coinstatsindex'); + if (coinStatsIndex !== null && coinStatsIndex.best_block_height >= block.height) { + const txoutset = await bitcoinClient.getTxoutSetinfo('none', block.height); + blk.extras.utxoSetSize = txoutset.txouts, + blk.extras.totalInputAmt = Math.round(txoutset.block_info.prevout_spent * 100000000); + } else { + blk.extras.utxoSetSize = null; + blk.extras.totalInputAmt = null; } if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK)) { let pool: PoolTag; - if (blockExtended.extras?.coinbaseTx !== undefined) { - pool = await this.$findBlockMiner(blockExtended.extras?.coinbaseTx); + if (blk.extras?.coinbaseTx !== undefined) { + pool = await this.$findBlockMiner(blk.extras?.coinbaseTx); } else { if (config.DATABASE.ENABLED === true) { pool = await poolsRepository.$getUnknownPool(); @@ -201,10 +249,10 @@ class Blocks { } if (!pool) { // We should never have this situation in practise - logger.warn(`Cannot assign pool to block ${blockExtended.height} and 'unknown' pool does not exist. ` + + logger.warn(`Cannot assign pool to block ${blk.height} and 'unknown' pool does not exist. ` + `Check your "pools" table entries`); } else { - blockExtended.extras.pool = { + blk.extras.pool = { id: pool.id, name: pool.name, slug: pool.slug, @@ -214,12 +262,12 @@ class Blocks { if (config.MEMPOOL.AUDIT) { const auditScore = await BlocksAuditsRepository.$getBlockAuditScore(block.id); if (auditScore != null) { - blockExtended.extras.matchRate = auditScore.matchRate; + blk.extras.matchRate = auditScore.matchRate; } } } - return blockExtended; + return blk; } /** @@ -500,6 +548,7 @@ class Blocks { } else { this.currentBlockHeight++; logger.debug(`New block found (#${this.currentBlockHeight})!`); + await chainTips.updateOrphanedBlocks(); } const blockHash = await bitcoinApi.$getBlockHash(this.currentBlockHeight); @@ -688,7 +737,6 @@ class Blocks { } public async $getBlocks(fromHeight?: number, limit: number = 15): Promise { - let currentHeight = fromHeight !== undefined ? fromHeight : this.currentBlockHeight; if (currentHeight > this.currentBlockHeight) { limit -= currentHeight - this.currentBlockHeight; @@ -728,6 +776,113 @@ class Blocks { return returnBlocks; } + /** + * Used for bulk block data query + * + * @param fromHeight + * @param toHeight + */ + public async $getBlocksBetweenHeight(fromHeight: number, toHeight: number): Promise { + if (!Common.indexingEnabled()) { + return []; + } + + const blocks: any[] = []; + + while (fromHeight <= toHeight) { + let block: any = await blocksRepository.$getBlockByHeight(fromHeight); + if (!block) { + await this.$indexBlock(fromHeight); + block = await blocksRepository.$getBlockByHeight(fromHeight); + if (!block) { + continue; + } + } + + // Cleanup fields before sending the response + const cleanBlock: any = { + height: block.height ?? null, + hash: block.id ?? null, + timestamp: block.blockTimestamp ?? null, + median_timestamp: block.medianTime ?? null, + previous_block_hash: block.previousblockhash ?? null, + difficulty: block.difficulty ?? null, + header: block.header ?? null, + version: block.version ?? null, + bits: block.bits ?? null, + nonce: block.nonce ?? null, + size: block.size ?? null, + weight: block.weight ?? null, + tx_count: block.tx_count ?? null, + merkle_root: block.merkle_root ?? null, + reward: block.reward ?? null, + total_fee_amt: block.fees ?? null, + avg_fee_amt: block.avg_fee ?? null, + median_fee_amt: block.median_fee_amt ?? null, + fee_amt_percentiles: block.fee_percentiles ?? null, + avg_fee_rate: block.avg_fee_rate ?? null, + median_fee_rate: block.median_fee ?? null, + fee_rate_percentiles: block.fee_span ?? null, + total_inputs: block.total_inputs ?? null, + total_input_amt: block.total_input_amt ?? null, + total_outputs: block.total_outputs ?? null, + total_output_amt: block.total_output_amt ?? null, + segwit_total_txs: block.segwit_total_txs ?? null, + segwit_total_size: block.segwit_total_size ?? null, + segwit_total_weight: block.segwit_total_weight ?? null, + avg_tx_size: block.avg_tx_size ?? null, + utxoset_change: block.utxoset_change ?? null, + utxoset_size: block.utxoset_size ?? null, + coinbase_raw: block.coinbase_raw ?? null, + coinbase_address: block.coinbase_address ?? null, + coinbase_signature: block.coinbase_signature ?? null, + coinbase_signature_ascii: block.coinbase_signature_ascii ?? null, + pool_slug: block.pool_slug ?? null, + }; + + if (Common.blocksSummariesIndexingEnabled() && cleanBlock.fee_amt_percentiles === null) { + cleanBlock.fee_amt_percentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(cleanBlock.hash); + if (cleanBlock.fee_amt_percentiles === null) { + const block = await bitcoinClient.getBlock(cleanBlock.hash, 2); + const summary = this.summarizeBlock(block); + await BlocksSummariesRepository.$saveSummary({ height: block.height, mined: summary }); + cleanBlock.fee_amt_percentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(cleanBlock.hash); + } + if (cleanBlock.fee_amt_percentiles !== null) { + cleanBlock.median_fee_amt = cleanBlock.fee_amt_percentiles[3]; + } + } + + cleanBlock.fee_amt_percentiles = { + 'min': cleanBlock.fee_amt_percentiles[0], + 'perc_10': cleanBlock.fee_amt_percentiles[1], + 'perc_25': cleanBlock.fee_amt_percentiles[2], + 'perc_50': cleanBlock.fee_amt_percentiles[3], + 'perc_75': cleanBlock.fee_amt_percentiles[4], + 'perc_90': cleanBlock.fee_amt_percentiles[5], + 'max': cleanBlock.fee_amt_percentiles[6], + }; + cleanBlock.fee_rate_percentiles = { + 'min': cleanBlock.fee_rate_percentiles[0], + 'perc_10': cleanBlock.fee_rate_percentiles[1], + 'perc_25': cleanBlock.fee_rate_percentiles[2], + 'perc_50': cleanBlock.fee_rate_percentiles[3], + 'perc_75': cleanBlock.fee_rate_percentiles[4], + 'perc_90': cleanBlock.fee_rate_percentiles[5], + 'max': cleanBlock.fee_rate_percentiles[6], + }; + + // Re-org can happen after indexing so we need to always get the + // latest state from core + cleanBlock.orphans = chainTips.getOrphanedBlocksAtHeight(cleanBlock.height); + + blocks.push(cleanBlock); + fromHeight++; + } + + return blocks; + } + public async $getBlockAuditSummary(hash: string): Promise { let summary; if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK)) { diff --git a/backend/src/api/chain-tips.ts b/backend/src/api/chain-tips.ts new file mode 100644 index 000000000..3384ebb19 --- /dev/null +++ b/backend/src/api/chain-tips.ts @@ -0,0 +1,57 @@ +import logger from "../logger"; +import bitcoinClient from "./bitcoin/bitcoin-client"; + +export interface ChainTip { + height: number; + hash: string; + branchlen: number; + status: 'invalid' | 'active' | 'valid-fork' | 'valid-headers' | 'headers-only'; +}; + +export interface OrphanedBlock { + height: number; + hash: string; + status: 'valid-fork' | 'valid-headers' | 'headers-only'; +} + +class ChainTips { + private chainTips: ChainTip[] = []; + private orphanedBlocks: OrphanedBlock[] = []; + + public async updateOrphanedBlocks(): Promise { + try { + this.chainTips = await bitcoinClient.getChainTips(); + this.orphanedBlocks = []; + + for (const chain of this.chainTips) { + if (chain.status === 'valid-fork' || chain.status === 'valid-headers') { + let block = await bitcoinClient.getBlock(chain.hash); + while (block && block.confirmations === -1) { + this.orphanedBlocks.push({ + height: block.height, + hash: block.hash, + status: chain.status + }); + block = await bitcoinClient.getBlock(block.previousblockhash); + } + } + } + + logger.debug(`Updated orphaned blocks cache. Found ${this.orphanedBlocks.length} orphaned blocks`); + } catch (e) { + logger.err(`Cannot get fetch orphaned blocks. Reason: ${e instanceof Error ? e.message : e}`); + } + } + + public getOrphanedBlocksAtHeight(height: number): OrphanedBlock[] { + const orphans: OrphanedBlock[] = []; + for (const block of this.orphanedBlocks) { + if (block.height === height) { + orphans.push(block); + } + } + return orphans; + } +} + +export default new ChainTips(); \ No newline at end of file diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index a0200c98c..13cffd755 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository'; import { RowDataPacket } from 'mysql2'; class DatabaseMigration { - private static currentVersion = 53; + private static currentVersion = 56; private queryTimeout = 3600_000; private statisticsAddedIndexed = false; private uniqueLogs: string[] = []; @@ -62,8 +62,8 @@ class DatabaseMigration { if (databaseSchemaVersion <= 2) { // Disable some spam logs when they're not relevant - this.uniqueLogs.push(this.blocksTruncatedMessage); - this.uniqueLogs.push(this.hashratesTruncatedMessage); + this.uniqueLog(logger.notice, this.blocksTruncatedMessage); + this.uniqueLog(logger.notice, this.hashratesTruncatedMessage); } logger.debug('MIGRATIONS: Current state.schema_version ' + databaseSchemaVersion); @@ -86,7 +86,7 @@ class DatabaseMigration { try { await this.$migrateTableSchemaFromVersion(databaseSchemaVersion); if (databaseSchemaVersion === 0) { - logger.notice(`MIGRATIONS: OK. Database schema has been properly initialized to version ${DatabaseMigration.currentVersion} (latest version)`); + logger.notice(`MIGRATIONS: OK. Database schema has been properly initialized to version ${DatabaseMigration.currentVersion} (latest version)`); } else { logger.notice(`MIGRATIONS: OK. Database schema have been migrated from version ${databaseSchemaVersion} to ${DatabaseMigration.currentVersion} (latest version)`); } @@ -300,7 +300,7 @@ class DatabaseMigration { await this.$executeQuery('ALTER TABLE `lightning_stats` ADD med_base_fee_mtokens bigint(20) unsigned NOT NULL DEFAULT "0"'); await this.updateToSchemaVersion(27); } - + if (databaseSchemaVersion < 28 && isBitcoin === true) { if (config.LIGHTNING.ENABLED) { this.uniqueLog(logger.notice, `'lightning_stats' and 'node_stats' tables have been truncated.`); @@ -464,7 +464,7 @@ class DatabaseMigration { await this.$executeQuery('DROP TABLE IF EXISTS `transactions`'); await this.$executeQuery('DROP TABLE IF EXISTS `cpfp_clusters`'); await this.updateToSchemaVersion(52); - } catch(e) { + } catch (e) { logger.warn('' + (e instanceof Error ? e.message : e)); } } @@ -473,6 +473,33 @@ class DatabaseMigration { await this.$executeQuery('ALTER TABLE statistics MODIFY mempool_byte_weight bigint(20) UNSIGNED NOT NULL'); await this.updateToSchemaVersion(53); } + + if (databaseSchemaVersion < 54) { + this.uniqueLog(logger.notice, `'prices' table has been truncated`); + await this.$executeQuery(`TRUNCATE prices`); + if (isBitcoin === true) { + this.uniqueLog(logger.notice, `'blocks_prices' table has been truncated`); + await this.$executeQuery(`TRUNCATE blocks_prices`); + } + await this.updateToSchemaVersion(54); + } + + if (databaseSchemaVersion < 55) { + await this.$executeQuery(this.getAdditionalBlocksDataQuery()); + this.uniqueLog(logger.notice, this.blocksTruncatedMessage); + await this.$executeQuery('TRUNCATE blocks;'); // Need to re-index + await this.updateToSchemaVersion(55); + } + + if (databaseSchemaVersion < 56) { + await this.$executeQuery('ALTER TABLE pools ADD unique_id int NOT NULL DEFAULT -1'); + await this.$executeQuery('TRUNCATE TABLE `blocks`'); + this.uniqueLog(logger.notice, this.blocksTruncatedMessage); + await this.$executeQuery('DELETE FROM `pools`'); + await this.$executeQuery('ALTER TABLE pools AUTO_INCREMENT = 1'); + this.uniqueLog(logger.notice, '`pools` table has been truncated`'); + await this.updateToSchemaVersion(56); + } } /** @@ -596,7 +623,7 @@ class DatabaseMigration { queries.push(`INSERT INTO state(name, number, string) VALUES ('last_hashrates_indexing', 0, NULL)`); } - if (version < 9 && isBitcoin === true) { + if (version < 9 && isBitcoin === true) { queries.push(`INSERT INTO state(name, number, string) VALUES ('last_weekly_hashrates_indexing', 0, NULL)`); } @@ -746,6 +773,28 @@ class DatabaseMigration { ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; } + private getAdditionalBlocksDataQuery(): string { + return `ALTER TABLE blocks + ADD median_timestamp timestamp NOT NULL, + ADD coinbase_address varchar(100) NULL, + ADD coinbase_signature varchar(500) NULL, + ADD coinbase_signature_ascii varchar(500) NULL, + ADD avg_tx_size double unsigned NOT NULL, + ADD total_inputs int unsigned NOT NULL, + ADD total_outputs int unsigned NOT NULL, + ADD total_output_amt bigint unsigned NOT NULL, + ADD fee_percentiles longtext NULL, + ADD median_fee_amt int unsigned NULL, + ADD segwit_total_txs int unsigned NOT NULL, + ADD segwit_total_size int unsigned NOT NULL, + ADD segwit_total_weight int unsigned NOT NULL, + ADD header varchar(160) NOT NULL, + ADD utxoset_change int NOT NULL, + ADD utxoset_size int unsigned NULL, + ADD total_input_amt bigint unsigned NULL + `; + } + private getCreateDailyStatsTableQuery(): string { return `CREATE TABLE IF NOT EXISTS hashrates ( hashrate_timestamp timestamp NOT NULL, @@ -963,26 +1012,16 @@ class DatabaseMigration { ) ENGINE=InnoDB DEFAULT CHARSET=utf8;`; } - public async $truncateIndexedData(tables: string[]) { - const allowedTables = ['blocks', 'hashrates', 'prices']; + public async $blocksReindexingTruncate(): Promise { + logger.warn(`Truncating pools, blocks and hashrates for re-indexing (using '--reindex-blocks'). You can cancel this command within 5 seconds`); + await Common.sleep$(5000); - try { - for (const table of tables) { - if (!allowedTables.includes(table)) { - logger.debug(`Table ${table} cannot to be re-indexed (not allowed)`); - continue; - } - - await this.$executeQuery(`TRUNCATE ${table}`, true); - if (table === 'hashrates') { - await this.$executeQuery('UPDATE state set number = 0 where name = "last_hashrates_indexing"', true); - } - logger.notice(`Table ${table} has been truncated`); - } - } catch (e) { - logger.warn(`Unable to erase indexed data`); - } - } + await this.$executeQuery(`TRUNCATE blocks`); + await this.$executeQuery(`TRUNCATE hashrates`); + await this.$executeQuery('DELETE FROM `pools`'); + await this.$executeQuery('ALTER TABLE pools AUTO_INCREMENT = 1'); + await this.$executeQuery(`UPDATE state SET string = NULL WHERE name = 'pools_json_sha'`); +} private async $convertCompactCpfpTables(): Promise { try { diff --git a/backend/src/api/disk-cache.ts b/backend/src/api/disk-cache.ts index cf40d6952..a75fd43cc 100644 --- a/backend/src/api/disk-cache.ts +++ b/backend/src/api/disk-cache.ts @@ -9,7 +9,7 @@ import { TransactionExtended } from '../mempool.interfaces'; import { Common } from './common'; class DiskCache { - private cacheSchemaVersion = 1; + private cacheSchemaVersion = 2; private static FILE_NAME = config.MEMPOOL.CACHE_DIR + '/cache.json'; private static FILE_NAMES = config.MEMPOOL.CACHE_DIR + '/cache{number}.json'; diff --git a/backend/src/api/mining/mining-routes.ts b/backend/src/api/mining/mining-routes.ts index 393ea119a..f7f392068 100644 --- a/backend/src/api/mining/mining-routes.ts +++ b/backend/src/api/mining/mining-routes.ts @@ -38,7 +38,16 @@ class MiningRoutes { private async $getHistoricalPrice(req: Request, res: Response): Promise { try { - res.status(200).send(await PricesRepository.$getHistoricalPrice()); + res.header('Pragma', 'public'); + res.header('Cache-control', 'public'); + res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString()); + if (req.query.timestamp) { + res.status(200).send(await PricesRepository.$getNearestHistoricalPrice( + parseInt(req.query.timestamp ?? 0, 10) + )); + } else { + res.status(200).send(await PricesRepository.$getHistoricalPrices()); + } } catch (e) { res.status(500).send(e instanceof Error ? e.message : e); } diff --git a/backend/src/api/mining/mining.ts b/backend/src/api/mining/mining.ts index edcb5b2e5..f33a68dcb 100644 --- a/backend/src/api/mining/mining.ts +++ b/backend/src/api/mining/mining.ts @@ -172,7 +172,7 @@ class Mining { } /** - * [INDEXING] Generate weekly mining pool hashrate history + * Generate weekly mining pool hashrate history */ public async $generatePoolHashrateHistory(): Promise { const now = new Date(); @@ -279,7 +279,7 @@ class Mining { } /** - * [INDEXING] Generate daily hashrate data + * Generate daily hashrate data */ public async $generateNetworkHashrateHistory(): Promise { // We only run this once a day around midnight @@ -459,7 +459,7 @@ class Mining { /** * Create a link between blocks and the latest price at when they were mined */ - public async $indexBlockPrices() { + public async $indexBlockPrices(): Promise { if (this.blocksPriceIndexingRunning === true) { return; } @@ -520,6 +520,41 @@ class Mining { this.blocksPriceIndexingRunning = false; } + /** + * Index core coinstatsindex + */ + public async $indexCoinStatsIndex(): Promise { + let timer = new Date().getTime() / 1000; + let totalIndexed = 0; + + const blockchainInfo = await bitcoinClient.getBlockchainInfo(); + let currentBlockHeight = blockchainInfo.blocks; + + while (currentBlockHeight > 0) { + const indexedBlocks = await BlocksRepository.$getBlocksMissingCoinStatsIndex( + currentBlockHeight, currentBlockHeight - 10000); + + for (const block of indexedBlocks) { + const txoutset = await bitcoinClient.getTxoutSetinfo('none', block.height); + await BlocksRepository.$updateCoinStatsIndexData(block.hash, txoutset.txouts, + Math.round(txoutset.block_info.prevout_spent * 100000000)); + ++totalIndexed; + + const elapsedSeconds = Math.max(1, new Date().getTime() / 1000 - timer); + if (elapsedSeconds > 5) { + logger.info(`Indexing coinstatsindex data for block #${block.height}. Indexed ${totalIndexed} blocks.`, logger.tags.mining); + timer = new Date().getTime() / 1000; + } + } + + currentBlockHeight -= 10000; + } + + if (totalIndexed) { + logger.info(`Indexing missing coinstatsindex data completed`, logger.tags.mining); + } + } + private getDateMidnight(date: Date): Date { date.setUTCHours(0); date.setUTCMinutes(0); diff --git a/backend/src/api/pools-parser.ts b/backend/src/api/pools-parser.ts index e37414bbe..b34dcb7b8 100644 --- a/backend/src/api/pools-parser.ts +++ b/backend/src/api/pools-parser.ts @@ -1,15 +1,8 @@ import DB from '../database'; import logger from '../logger'; import config from '../config'; -import BlocksRepository from '../repositories/BlocksRepository'; - -interface Pool { - name: string; - link: string; - regexes: string[]; - addresses: string[]; - slug: string; -} +import PoolsRepository from '../repositories/PoolsRepository'; +import { PoolTag } from '../mempool.interfaces'; class PoolsParser { miningPools: any[] = []; @@ -20,270 +13,142 @@ class PoolsParser { 'addresses': '[]', 'slug': 'unknown' }; - slugWarnFlag = false; + private uniqueLogs: string[] = []; + + private uniqueLog(loggerFunction: any, msg: string): void { + if (this.uniqueLogs.includes(msg)) { + return; + } + this.uniqueLogs.push(msg); + loggerFunction(msg); + } + + public setMiningPools(pools): void { + for (const pool of pools) { + pool.regexes = pool.tags; + delete(pool.tags); + } + this.miningPools = pools; + } /** - * Parse the pools.json file, consolidate the data and dump it into the database + * Populate our db with updated mining pool definition + * @param pools */ - public async migratePoolsJson(poolsJson: object): Promise { - if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) === false) { - return; - } + public async migratePoolsJson(): Promise { + await this.$insertUnknownPool(); - // First we save every entries without paying attention to pool duplication - const poolsDuplicated: Pool[] = []; - - const coinbaseTags = Object.entries(poolsJson['coinbase_tags']); - for (let i = 0; i < coinbaseTags.length; ++i) { - poolsDuplicated.push({ - 'name': (coinbaseTags[i][1]).name, - 'link': (coinbaseTags[i][1]).link, - 'regexes': [coinbaseTags[i][0]], - 'addresses': [], - 'slug': '' - }); - } - const addressesTags = Object.entries(poolsJson['payout_addresses']); - for (let i = 0; i < addressesTags.length; ++i) { - poolsDuplicated.push({ - 'name': (addressesTags[i][1]).name, - 'link': (addressesTags[i][1]).link, - 'regexes': [], - 'addresses': [addressesTags[i][0]], - 'slug': '' - }); - } - - // Then, we find unique mining pool names - const poolNames: string[] = []; - for (let i = 0; i < poolsDuplicated.length; ++i) { - if (poolNames.indexOf(poolsDuplicated[i].name) === -1) { - poolNames.push(poolsDuplicated[i].name); + for (const pool of this.miningPools) { + if (!pool.id) { + logger.info(`Mining pool ${pool.name} has no unique 'id' defined. Skipping.`); + continue; } - } - logger.debug(`Found ${poolNames.length} unique mining pools`, logger.tags.mining); - // Get existing pools from the db - let existingPools; - try { - if (config.DATABASE.ENABLED === true) { - [existingPools] = await DB.query({ sql: 'SELECT * FROM pools;', timeout: 120000 }); + const poolDB = await PoolsRepository.$getPoolByUniqueId(pool.id, false); + if (!poolDB) { + // New mining pool + const slug = pool.name.replace(/[^a-z0-9]/gi, '').toLowerCase(); + logger.debug(`Inserting new mining pool ${pool.name}`); + await PoolsRepository.$insertNewMiningPool(pool, slug); + await this.$deleteUnknownBlocks(); } else { - existingPools = []; - } - } catch (e) { - logger.err('Cannot get existing pools from the database, skipping pools.json import', logger.tags.mining); - return; - } - - this.miningPools = []; - - // Finally, we generate the final consolidated pools data - const finalPoolDataAdd: Pool[] = []; - const finalPoolDataUpdate: Pool[] = []; - const finalPoolDataRename: Pool[] = []; - for (let i = 0; i < poolNames.length; ++i) { - let allAddresses: string[] = []; - let allRegexes: string[] = []; - const match = poolsDuplicated.filter((pool: Pool) => pool.name === poolNames[i]); - - for (let y = 0; y < match.length; ++y) { - allAddresses = allAddresses.concat(match[y].addresses); - allRegexes = allRegexes.concat(match[y].regexes); - } - - const finalPoolName = poolNames[i].replace(`'`, `''`); // To support single quote in names when doing db queries - - let slug: string | undefined; - try { - slug = poolsJson['slugs'][poolNames[i]]; - } catch (e) { - if (this.slugWarnFlag === false) { - logger.warn(`pools.json does not seem to contain the 'slugs' object`, logger.tags.mining); - this.slugWarnFlag = true; + if (poolDB.name !== pool.name) { + // Pool has been renamed + const newSlug = pool.name.replace(/[^a-z0-9]/gi, '').toLowerCase(); + logger.warn(`Renaming ${poolDB.name} mining pool to ${pool.name}. Slug has been updated. Maybe you want to make a redirection from 'https://mempool.space/mining/pool/${poolDB.slug}' to 'https://mempool.space/mining/pool/${newSlug}`); + await PoolsRepository.$renameMiningPool(poolDB.id, newSlug, pool.name); } - } - - if (slug === undefined) { - // Only keep alphanumerical - slug = poolNames[i].replace(/[^a-z0-9]/gi, '').toLowerCase(); - logger.warn(`No slug found for '${poolNames[i]}', generating it => '${slug}'`, logger.tags.mining); - } - - const poolObj = { - 'name': finalPoolName, - 'link': match[0].link, - 'regexes': allRegexes, - 'addresses': allAddresses, - 'slug': slug - }; - - const existingPool = existingPools.find((pool) => pool.name === poolNames[i]); - if (existingPool !== undefined) { - // Check if any data was actually updated - const equals = (a, b) => - a.length === b.length && - a.every((v, i) => v === b[i]); - if (!equals(JSON.parse(existingPool.addresses), poolObj.addresses) || !equals(JSON.parse(existingPool.regexes), poolObj.regexes)) { - finalPoolDataUpdate.push(poolObj); + if (poolDB.link !== pool.link) { + // Pool link has changed + logger.debug(`Updating link for ${pool.name} mining pool`); + await PoolsRepository.$updateMiningPoolLink(poolDB.id, pool.link); } - } else if (config.DATABASE.ENABLED) { - // Double check that if we're not just renaming a pool (same address same regex) - const [poolToRename]: any[] = await DB.query(` - SELECT * FROM pools - WHERE addresses = ? OR regexes = ?`, - [JSON.stringify(poolObj.addresses), JSON.stringify(poolObj.regexes)] - ); - if (poolToRename && poolToRename.length > 0) { - // We're actually renaming an existing pool - finalPoolDataRename.push({ - 'name': poolObj.name, - 'link': poolObj.link, - 'regexes': allRegexes, - 'addresses': allAddresses, - 'slug': slug - }); - logger.debug(`Rename '${poolToRename[0].name}' mining pool to ${poolObj.name}`, logger.tags.mining); - } else { - logger.debug(`Add '${finalPoolName}' mining pool`, logger.tags.mining); - finalPoolDataAdd.push(poolObj); + if (JSON.stringify(pool.addresses) !== poolDB.addresses || + JSON.stringify(pool.regexes) !== poolDB.regexes) { + // Pool addresses changed or coinbase tags changed + logger.notice(`Updating addresses and/or coinbase tags for ${pool.name} mining pool. If 'AUTOMATIC_BLOCK_REINDEXING' is enabled, we will re-index its blocks and 'unknown' blocks`); + await PoolsRepository.$updateMiningPoolTags(poolDB.id, pool.addresses, pool.regexes); + await this.$deleteBlocksForPool(poolDB); } } - - 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)', logger.tags.mining); - return; - } - - if (finalPoolDataAdd.length > 0 || finalPoolDataUpdate.length > 0 || - finalPoolDataRename.length > 0 - ) { - logger.debug(`Update pools table now`, logger.tags.mining); - - // Add new mining pools into the database - let queryAdd: string = 'INSERT INTO pools(name, link, regexes, addresses, slug) VALUES '; - 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)}),`; - } - queryAdd = queryAdd.slice(0, -1) + ';'; - - // Updated existing mining pools in the database - const updateQueries: string[] = []; - for (let i = 0; i < finalPoolDataUpdate.length; ++i) { - updateQueries.push(` - UPDATE pools - SET name='${finalPoolDataUpdate[i].name}', link='${finalPoolDataUpdate[i].link}', - regexes='${JSON.stringify(finalPoolDataUpdate[i].regexes)}', addresses='${JSON.stringify(finalPoolDataUpdate[i].addresses)}', - slug='${finalPoolDataUpdate[i].slug}' - WHERE name='${finalPoolDataUpdate[i].name}' - ;`); - } - - // Rename mining pools - const renameQueries: string[] = []; - for (let i = 0; i < finalPoolDataRename.length; ++i) { - renameQueries.push(` - UPDATE pools - SET name='${finalPoolDataRename[i].name}', link='${finalPoolDataRename[i].link}', - slug='${finalPoolDataRename[i].slug}' - WHERE regexes='${JSON.stringify(finalPoolDataRename[i].regexes)}' - AND addresses='${JSON.stringify(finalPoolDataRename[i].addresses)}' - ;`); - } - - try { - if (finalPoolDataAdd.length > 0 || updateQueries.length > 0) { - await this.$deleteBlocskToReindex(finalPoolDataUpdate); - } - - if (finalPoolDataAdd.length > 0) { - await DB.query({ sql: queryAdd, timeout: 120000 }); - } - for (const query of updateQueries) { - await DB.query({ sql: query, timeout: 120000 }); - } - for (const query of renameQueries) { - await DB.query({ sql: query, timeout: 120000 }); - } - await this.insertUnknownPool(); - logger.info('Mining pools.json import completed', logger.tags.mining); - } catch (e) { - logger.err(`Cannot import pools in the database`, logger.tags.mining); - throw e; - } } - try { - await this.insertUnknownPool(); - } catch (e) { - logger.err(`Cannot insert unknown pool in the database`, logger.tags.mining); - throw e; - } + logger.info('Mining pools-v2.json import completed'); } /** * Manually add the 'unknown pool' */ - private async insertUnknownPool() { + public async $insertUnknownPool(): Promise { + if (!config.DATABASE.ENABLED) { + return; + } + try { const [rows]: any[] = await DB.query({ sql: 'SELECT name from pools where name="Unknown"', timeout: 120000 }); if (rows.length === 0) { await DB.query({ - sql: `INSERT INTO pools(name, link, regexes, addresses, slug) - VALUES("Unknown", "https://learnmeabitcoin.com/technical/coinbase-transaction", "[]", "[]", "unknown"); + sql: `INSERT INTO pools(name, link, regexes, addresses, slug, unique_id) + VALUES("${this.unknownPool.name}", "${this.unknownPool.link}", "[]", "[]", "${this.unknownPool.slug}", 0); `}); } else { await DB.query(`UPDATE pools - SET name='Unknown', link='https://learnmeabitcoin.com/technical/coinbase-transaction', + SET name='${this.unknownPool.name}', link='${this.unknownPool.link}', regexes='[]', addresses='[]', - slug='unknown' - WHERE name='Unknown' + slug='${this.unknownPool.slug}', + unique_id=0 + WHERE slug='${this.unknownPool.slug}' `); } } catch (e) { - logger.err('Unable to insert "Unknown" mining pool', logger.tags.mining); + logger.err(`Unable to insert or update "Unknown" mining pool. Reason: ${e instanceof Error ? e.message : e}`); } } /** - * Delete blocks which needs to be reindexed + * Delete indexed blocks for an updated mining pool + * + * @param pool */ - private async $deleteBlocskToReindex(finalPoolDataUpdate: any[]) { + private async $deleteBlocksForPool(pool: PoolTag): Promise { if (config.MEMPOOL.AUTOMATIC_BLOCK_REINDEXING === false) { return; } - const blockCount = await BlocksRepository.$blockCount(null, null); - if (blockCount === 0) { - return; - } - - for (const updatedPool of finalPoolDataUpdate) { - const [pool]: any[] = await DB.query(`SELECT id, name from pools where slug = "${updatedPool.slug}"`); - if (pool.length > 0) { - logger.notice(`Deleting blocks from ${pool[0].name} mining pool for future re-indexing`, logger.tags.mining); - await DB.query(`DELETE FROM blocks WHERE pool_id = ${pool[0].id}`); - } - } - - // Ignore early days of Bitcoin as there were not mining pool yet - logger.notice(`Deleting blocks with unknown mining pool from height 130635 for future re-indexing`, logger.tags.mining); + // Get oldest blocks mined by the pool and assume pools-v2.json updates only concern most recent years + // Ignore early days of Bitcoin as there were no mining pool yet + const [oldestPoolBlock]: any[] = await DB.query(` + SELECT height + FROM blocks + WHERE pool_id = ? + ORDER BY height + LIMIT 1`, + [pool.id] + ); + const oldestBlockHeight = oldestPoolBlock.length ?? 0 > 0 ? oldestPoolBlock[0].height : 130635; const [unknownPool] = await DB.query(`SELECT id from pools where slug = "unknown"`); - await DB.query(`DELETE FROM blocks WHERE pool_id = ${unknownPool[0].id} AND height > 130635`); + this.uniqueLog(logger.notice, `Deleting blocks with unknown mining pool from height ${oldestBlockHeight} for re-indexing`); + await DB.query(` + DELETE FROM blocks + WHERE pool_id = ? AND height >= ${oldestBlockHeight}`, + [unknownPool[0].id] + ); + logger.notice(`Deleting blocks from ${pool.name} mining pool for re-indexing`); + await DB.query(` + DELETE FROM blocks + WHERE pool_id = ?`, + [pool.id] + ); + } - logger.notice(`Truncating hashrates for future re-indexing`, logger.tags.mining); - await DB.query(`DELETE FROM hashrates`); + private async $deleteUnknownBlocks(): Promise { + const [unknownPool] = await DB.query(`SELECT id from pools where slug = "unknown"`); + this.uniqueLog(logger.notice, `Deleting blocks with unknown mining pool from height 130635 for re-indexing`); + await DB.query(` + DELETE FROM blocks + WHERE pool_id = ? AND height >= 130635`, + [unknownPool[0].id] + ); } } diff --git a/backend/src/api/transaction-utils.ts b/backend/src/api/transaction-utils.ts index fb5aeea42..fb69419fc 100644 --- a/backend/src/api/transaction-utils.ts +++ b/backend/src/api/transaction-utils.ts @@ -14,6 +14,7 @@ class TransactionUtils { vout: tx.vout .map((vout) => ({ scriptpubkey_address: vout.scriptpubkey_address, + scriptpubkey_asm: vout.scriptpubkey_asm, value: vout.value })) .filter((vout) => vout.value) diff --git a/backend/src/config.ts b/backend/src/config.ts index 2cda8d85b..8ccd7e2e4 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -32,6 +32,7 @@ interface IConfig { ADVANCED_GBT_AUDIT: boolean; ADVANCED_GBT_MEMPOOL: boolean; CPFP_INDEXING: boolean; + MAX_BLOCKS_BULK_QUERY: number; }; ESPLORA: { REST_API_URL: string; @@ -147,12 +148,13 @@ const defaults: IConfig = { 'USER_AGENT': 'mempool', 'STDOUT_LOG_MIN_PRIORITY': 'debug', 'AUTOMATIC_BLOCK_REINDEXING': false, - 'POOLS_JSON_URL': 'https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json', + 'POOLS_JSON_URL': 'https://raw.githubusercontent.com/mempool/mining-pools/master/pools-v2.json', 'POOLS_JSON_TREE_URL': 'https://api.github.com/repos/mempool/mining-pools/git/trees/master', 'AUDIT': false, 'ADVANCED_GBT_AUDIT': false, 'ADVANCED_GBT_MEMPOOL': false, 'CPFP_INDEXING': false, + 'MAX_BLOCKS_BULK_QUERY': 0, }, 'ESPLORA': { 'REST_API_URL': 'http://127.0.0.1:3000', diff --git a/backend/src/database.ts b/backend/src/database.ts index c2fb0980b..a504eb0fa 100644 --- a/backend/src/database.ts +++ b/backend/src/database.ts @@ -24,7 +24,8 @@ import { FieldPacket, OkPacket, PoolOptions, ResultSetHeader, RowDataPacket } fr 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'); + const stack = new Error().stack; + logger.err(`Trying to use DB feature but config.DATABASE.ENABLED is set to false, please open an issue.\nStack trace: ${stack}}`); } } diff --git a/backend/src/index.ts b/backend/src/index.ts index 919c039c3..e96d7e4da 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -36,6 +36,8 @@ 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 mining from './api/mining/mining'; +import chainTips from './api/chain-tips'; import { AxiosError } from 'axios'; class Server { @@ -82,11 +84,8 @@ class Server { if (config.DATABASE.ENABLED) { await DB.checkDbConnection(); try { - if (process.env.npm_config_reindex !== undefined) { // Re-index requests - const tables = process.env.npm_config_reindex.split(','); - logger.warn(`Indexed data for "${process.env.npm_config_reindex}" tables will be erased in 5 seconds (using '--reindex')`); - await Common.sleep$(5000); - await databaseMigration.$truncateIndexedData(tables); + if (process.env.npm_config_reindex_blocks === 'true') { // Re-index requests + await databaseMigration.$blocksReindexingTruncate(); } await databaseMigration.$initializeOrMigrateDatabase(); if (Common.indexingEnabled()) { @@ -133,6 +132,7 @@ class Server { } priceUpdater.$run(); + await chainTips.updateOrphanedBlocks(); this.setUpHttpApiRoutes(); diff --git a/backend/src/indexer.ts b/backend/src/indexer.ts index 22f3ce319..41c8024e0 100644 --- a/backend/src/indexer.ts +++ b/backend/src/indexer.ts @@ -8,18 +8,67 @@ import bitcoinClient from './api/bitcoin/bitcoin-client'; import priceUpdater from './tasks/price-updater'; import PricesRepository from './repositories/PricesRepository'; +export interface CoreIndex { + name: string; + synced: boolean; + best_block_height: number; +} + class Indexer { runIndexer = true; indexerRunning = false; tasksRunning: string[] = []; + coreIndexes: CoreIndex[] = []; - public reindex() { + /** + * Check which core index is available for indexing + */ + public async checkAvailableCoreIndexes(): Promise { + const updatedCoreIndexes: CoreIndex[] = []; + + const indexes: any = await bitcoinClient.getIndexInfo(); + for (const indexName in indexes) { + const newState = { + name: indexName, + synced: indexes[indexName].synced, + best_block_height: indexes[indexName].best_block_height, + }; + logger.info(`Core index '${indexName}' is ${indexes[indexName].synced ? 'synced' : 'not synced'}. Best block height is ${indexes[indexName].best_block_height}`); + updatedCoreIndexes.push(newState); + + if (indexName === 'coinstatsindex' && newState.synced === true) { + const previousState = this.isCoreIndexReady('coinstatsindex'); + // if (!previousState || previousState.synced === false) { + this.runSingleTask('coinStatsIndex'); + // } + } + } + + this.coreIndexes = updatedCoreIndexes; + } + + /** + * Return the best block height if a core index is available, or 0 if not + * + * @param name + * @returns + */ + public isCoreIndexReady(name: string): CoreIndex | null { + for (const index of this.coreIndexes) { + if (index.name === name && index.synced === true) { + return index; + } + } + return null; + } + + public reindex(): void { if (Common.indexingEnabled()) { this.runIndexer = true; } } - public async runSingleTask(task: 'blocksPrices') { + public async runSingleTask(task: 'blocksPrices' | 'coinStatsIndex'): Promise { if (!Common.indexingEnabled()) { return; } @@ -28,20 +77,27 @@ class Indexer { this.tasksRunning.push(task); const lastestPriceId = await PricesRepository.$getLatestPriceId(); if (priceUpdater.historyInserted === false || lastestPriceId === null) { - logger.debug(`Blocks prices indexer is waiting for the price updater to complete`) + logger.debug(`Blocks prices indexer is waiting for the price updater to complete`); setTimeout(() => { - this.tasksRunning = this.tasksRunning.filter(runningTask => runningTask != task) + this.tasksRunning = this.tasksRunning.filter(runningTask => runningTask !== task); this.runSingleTask('blocksPrices'); }, 10000); } else { - logger.debug(`Blocks prices indexer will run now`) + logger.debug(`Blocks prices indexer will run now`); await mining.$indexBlockPrices(); - this.tasksRunning = this.tasksRunning.filter(runningTask => runningTask != task) + this.tasksRunning = this.tasksRunning.filter(runningTask => runningTask !== task); } } + + if (task === 'coinStatsIndex' && !this.tasksRunning.includes(task)) { + this.tasksRunning.push(task); + logger.debug(`Indexing coinStatsIndex now`); + await mining.$indexCoinStatsIndex(); + this.tasksRunning = this.tasksRunning.filter(runningTask => runningTask !== task); + } } - public async $run() { + public async $run(): Promise { if (!Common.indexingEnabled() || this.runIndexer === false || this.indexerRunning === true || mempool.hasPriority() ) { @@ -57,7 +113,9 @@ class Indexer { this.runIndexer = false; this.indexerRunning = true; - logger.debug(`Running mining indexer`); + logger.info(`Running mining indexer`); + + await this.checkAvailableCoreIndexes(); try { await priceUpdater.$run(); @@ -93,7 +151,7 @@ class Indexer { setTimeout(() => this.reindex(), runEvery); } - async $resetHashratesIndexingState() { + async $resetHashratesIndexingState(): Promise { try { await HashratesRepository.$setLatestRun('last_hashrates_indexing', 0); await HashratesRepository.$setLatestRun('last_weekly_hashrates_indexing', 0); diff --git a/backend/src/mempool.interfaces.ts b/backend/src/mempool.interfaces.ts index 6b258c173..cb95be98a 100644 --- a/backend/src/mempool.interfaces.ts +++ b/backend/src/mempool.interfaces.ts @@ -1,4 +1,5 @@ import { IEsploraApi } from './api/bitcoin/esplora-api.interface'; +import { OrphanedBlock } from './api/chain-tips'; import { HeapNode } from "./utils/pairing-heap"; export interface PoolTag { @@ -64,6 +65,7 @@ interface VinStrippedToScriptsig { interface VoutStrippedToScriptPubkey { scriptpubkey_address: string | undefined; + scriptpubkey_asm: string | undefined; value: number; } @@ -160,6 +162,27 @@ export interface BlockExtension { avgFeeRate?: number; coinbaseRaw?: string; usd?: number | null; + medianTimestamp?: number; + blockTime?: number; + orphans?: OrphanedBlock[] | null; + coinbaseAddress?: string | null; + coinbaseSignature?: string | null; + coinbaseSignatureAscii?: string | null; + virtualSize?: number; + avgTxSize?: number; + totalInputs?: number; + totalOutputs?: number; + totalOutputAmt?: number; + medianFeeAmt?: number | null; + feePercentiles?: number[] | null, + segwitTotalTxs?: number; + segwitTotalSize?: number; + segwitTotalWeight?: number; + header?: string; + utxoSetChange?: number; + // Requires coinstatsindex, will be set to NULL otherwise + utxoSetSize?: number | null; + totalInputAmt?: number | null; } export interface BlockExtended extends IEsploraApi.Block { diff --git a/backend/src/repositories/BlocksRepository.ts b/backend/src/repositories/BlocksRepository.ts index 355187e21..86dc006ff 100644 --- a/backend/src/repositories/BlocksRepository.ts +++ b/backend/src/repositories/BlocksRepository.ts @@ -18,17 +18,27 @@ class BlocksRepository { public async $saveBlockInDatabase(block: BlockExtended) { try { const query = `INSERT INTO blocks( - height, hash, blockTimestamp, size, - weight, tx_count, coinbase_raw, difficulty, - pool_id, fees, fee_span, median_fee, - reward, version, bits, nonce, - merkle_root, previous_block_hash, avg_fee, avg_fee_rate + height, hash, blockTimestamp, size, + weight, tx_count, coinbase_raw, difficulty, + pool_id, fees, fee_span, median_fee, + reward, version, bits, nonce, + merkle_root, previous_block_hash, avg_fee, avg_fee_rate, + median_timestamp, header, coinbase_address, + coinbase_signature, utxoset_size, utxoset_change, avg_tx_size, + total_inputs, total_outputs, total_input_amt, total_output_amt, + fee_percentiles, segwit_total_txs, segwit_total_size, segwit_total_weight, + median_fee_amt, coinbase_signature_ascii ) VALUE ( ?, ?, FROM_UNIXTIME(?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, - ?, ?, ?, ? + ?, ?, ?, ?, + FROM_UNIXTIME(?), ?, ?, + ?, ?, ?, ?, + ?, ?, ?, ?, + ?, ?, ?, ?, + ?, ? )`; const params: any[] = [ @@ -52,6 +62,23 @@ class BlocksRepository { block.previousblockhash, block.extras.avgFee, block.extras.avgFeeRate, + block.extras.medianTimestamp, + block.extras.header, + block.extras.coinbaseAddress, + block.extras.coinbaseSignature, + block.extras.utxoSetSize, + block.extras.utxoSetChange, + block.extras.avgTxSize, + block.extras.totalInputs, + block.extras.totalOutputs, + block.extras.totalInputAmt, + block.extras.totalOutputAmt, + block.extras.feePercentiles ? JSON.stringify(block.extras.feePercentiles) : null, + block.extras.segwitTotalTxs, + block.extras.segwitTotalSize, + block.extras.segwitTotalWeight, + block.extras.medianFeeAmt, + block.extras.coinbaseSignatureAscii, ]; await DB.query(query, params); @@ -65,6 +92,33 @@ class BlocksRepository { } } + /** + * Save newly indexed data from core coinstatsindex + * + * @param utxoSetSize + * @param totalInputAmt + */ + public async $updateCoinStatsIndexData(blockHash: string, utxoSetSize: number, + totalInputAmt: number + ) : Promise { + try { + const query = ` + UPDATE blocks + SET utxoset_size = ?, total_input_amt = ? + WHERE hash = ? + `; + const params: any[] = [ + utxoSetSize, + totalInputAmt, + blockHash + ]; + await DB.query(query, params); + } catch (e: any) { + logger.err('Cannot update indexed block coinstatsindex. Reason: ' + (e instanceof Error ? e.message : e)); + throw e; + } + } + /** * Get all block height that have not been indexed between [startHeight, endHeight] */ @@ -310,32 +364,17 @@ class BlocksRepository { public async $getBlockByHeight(height: number): Promise { try { const [rows]: any[] = await DB.query(`SELECT - blocks.height, - hash, + blocks.*, hash as id, UNIX_TIMESTAMP(blocks.blockTimestamp) as blockTimestamp, - size, - weight, - tx_count, - coinbase_raw, - difficulty, + UNIX_TIMESTAMP(blocks.median_timestamp) as medianTime, pools.id as pool_id, pools.name as pool_name, pools.link as pool_link, pools.slug as pool_slug, pools.addresses as pool_addresses, pools.regexes as pool_regexes, - fees, - fee_span, - median_fee, - reward, - version, - bits, - nonce, - merkle_root, - previous_block_hash as previousblockhash, - avg_fee, - avg_fee_rate + previous_block_hash as previousblockhash FROM blocks JOIN pools ON blocks.pool_id = pools.id WHERE blocks.height = ${height} @@ -346,6 +385,7 @@ class BlocksRepository { } rows[0].fee_span = JSON.parse(rows[0].fee_span); + rows[0].fee_percentiles = JSON.parse(rows[0].fee_percentiles); return rows[0]; } catch (e) { logger.err(`Cannot get indexed block ${height}. Reason: ` + (e instanceof Error ? e.message : e)); @@ -521,7 +561,7 @@ class BlocksRepository { CAST(AVG(blocks.height) as INT) as avgHeight, CAST(AVG(UNIX_TIMESTAMP(blockTimestamp)) as INT) as timestamp, CAST(AVG(fees) as INT) as avgFees, - prices.* + prices.USD FROM blocks JOIN blocks_prices on blocks_prices.height = blocks.height JOIN prices on prices.id = blocks_prices.price_id @@ -550,7 +590,7 @@ class BlocksRepository { CAST(AVG(blocks.height) as INT) as avgHeight, CAST(AVG(UNIX_TIMESTAMP(blockTimestamp)) as INT) as timestamp, CAST(AVG(reward) as INT) as avgRewards, - prices.* + prices.USD FROM blocks JOIN blocks_prices on blocks_prices.height = blocks.height JOIN prices on prices.id = blocks_prices.price_id @@ -694,7 +734,6 @@ class BlocksRepository { logger.err('Cannot fetch CPFP unindexed blocks. Reason: ' + (e instanceof Error ? e.message : e)); throw e; } - return []; } /** @@ -741,7 +780,7 @@ class BlocksRepository { try { let query = `INSERT INTO blocks_prices(height, price_id) VALUES`; for (const price of blockPrices) { - query += ` (${price.height}, ${price.priceId}),` + query += ` (${price.height}, ${price.priceId}),`; } query = query.slice(0, -1); await DB.query(query); @@ -754,6 +793,43 @@ class BlocksRepository { } } } + + /** + * Get all indexed blocsk with missing coinstatsindex data + */ + public async $getBlocksMissingCoinStatsIndex(maxHeight: number, minHeight: number): Promise { + try { + const [blocks] = await DB.query(` + SELECT height, hash + FROM blocks + WHERE height >= ${minHeight} AND height <= ${maxHeight} AND + (utxoset_size IS NULL OR total_input_amt IS NULL) + `); + return blocks; + } catch (e) { + logger.err(`Cannot get blocks with missing coinstatsindex. Reason: ` + (e instanceof Error ? e.message : e)); + throw e; + } + } + + /** + * Save indexed median fee to avoid recomputing it later + * + * @param id + * @param feePercentiles + */ + public async $saveFeePercentilesForBlockId(id: string, feePercentiles: number[]): Promise { + try { + await DB.query(` + UPDATE blocks SET fee_percentiles = ?, median_fee_amt = ? + WHERE hash = ?`, + [JSON.stringify(feePercentiles), feePercentiles[3], id] + ); + } catch (e) { + logger.err(`Cannot update block fee_percentiles. Reason: ` + (e instanceof Error ? e.message : e)); + throw e; + } + } } export default new BlocksRepository(); diff --git a/backend/src/repositories/BlocksSummariesRepository.ts b/backend/src/repositories/BlocksSummariesRepository.ts index 1406a1d07..2724ddcf5 100644 --- a/backend/src/repositories/BlocksSummariesRepository.ts +++ b/backend/src/repositories/BlocksSummariesRepository.ts @@ -80,6 +80,48 @@ class BlocksSummariesRepository { logger.err('Cannot delete indexed blocks summaries. Reason: ' + (e instanceof Error ? e.message : e)); } } + + /** + * Get the fee percentiles if the block has already been indexed, [] otherwise + * + * @param id + */ + public async $getFeePercentilesByBlockId(id: string): Promise { + try { + const [rows]: any[] = await DB.query(` + SELECT transactions + FROM blocks_summaries + WHERE id = ?`, + [id] + ); + if (rows === null || rows.length === 0) { + return null; + } + + const transactions = JSON.parse(rows[0].transactions); + if (transactions === null) { + return null; + } + + transactions.shift(); // Ignore coinbase + transactions.sort((a: any, b: any) => a.fee - b.fee); + const fees = transactions.map((t: any) => t.fee); + + return [ + fees[0] ?? 0, // min + fees[Math.max(0, Math.floor(fees.length * 0.1) - 1)] ?? 0, // 10th + fees[Math.max(0, Math.floor(fees.length * 0.25) - 1)] ?? 0, // 25th + fees[Math.max(0, Math.floor(fees.length * 0.5) - 1)] ?? 0, // median + fees[Math.max(0, Math.floor(fees.length * 0.75) - 1)] ?? 0, // 75th + fees[Math.max(0, Math.floor(fees.length * 0.9) - 1)] ?? 0, // 90th + fees[fees.length - 1] ?? 0, // max + ]; + + } catch (e) { + logger.err(`Cannot get block summaries transactions. Reason: ` + (e instanceof Error ? e.message : e)); + return null; + } + } } export default new BlocksSummariesRepository(); diff --git a/backend/src/repositories/PoolsRepository.ts b/backend/src/repositories/PoolsRepository.ts index 56cc2b3bc..236955d65 100644 --- a/backend/src/repositories/PoolsRepository.ts +++ b/backend/src/repositories/PoolsRepository.ts @@ -1,4 +1,5 @@ import { Common } from '../api/common'; +import poolsParser from '../api/pools-parser'; import config from '../config'; import DB from '../database'; import logger from '../logger'; @@ -17,7 +18,11 @@ class PoolsRepository { * Get unknown pool tagging info */ public async $getUnknownPool(): Promise { - const [rows] = await DB.query('SELECT id, name, slug FROM pools where name = "Unknown"'); + let [rows]: any[] = await DB.query('SELECT id, name, slug FROM pools where name = "Unknown"'); + if (rows && rows.length === 0 && config.DATABASE.ENABLED) { + await poolsParser.$insertUnknownPool(); + [rows] = await DB.query('SELECT id, name, slug FROM pools where name = "Unknown"'); + } return rows[0]; } @@ -59,7 +64,7 @@ class PoolsRepository { /** * Get basic pool info and block count between two timestamp */ - public async $getPoolsInfoBetween(from: number, to: number): Promise { + public async $getPoolsInfoBetween(from: number, to: number): Promise { const query = `SELECT COUNT(height) as blockCount, pools.id as poolId, pools.name as poolName FROM pools LEFT JOIN blocks on pools.id = blocks.pool_id AND blocks.blockTimestamp BETWEEN FROM_UNIXTIME(?) AND FROM_UNIXTIME(?) @@ -75,9 +80,9 @@ class PoolsRepository { } /** - * Get mining pool statistics for one pool + * Get a mining pool info */ - public async $getPool(slug: string): Promise { + public async $getPool(slug: string, parse: boolean = true): Promise { const query = ` SELECT * FROM pools @@ -90,10 +95,12 @@ class PoolsRepository { return null; } - rows[0].regexes = JSON.parse(rows[0].regexes); + if (parse) { + rows[0].regexes = JSON.parse(rows[0].regexes); + } if (['testnet', 'signet'].includes(config.MEMPOOL.NETWORK)) { - rows[0].addresses = []; // pools.json only contains mainnet addresses - } else { + rows[0].addresses = []; // pools-v2.json only contains mainnet addresses + } else if (parse) { rows[0].addresses = JSON.parse(rows[0].addresses); } @@ -103,6 +110,116 @@ class PoolsRepository { throw e; } } + + /** + * Get a mining pool info by its unique id + */ + public async $getPoolByUniqueId(id: number, parse: boolean = true): Promise { + const query = ` + SELECT * + FROM pools + WHERE pools.unique_id = ?`; + + try { + const [rows]: any[] = await DB.query(query, [id]); + + if (rows.length < 1) { + return null; + } + + if (parse) { + rows[0].regexes = JSON.parse(rows[0].regexes); + } + if (['testnet', 'signet'].includes(config.MEMPOOL.NETWORK)) { + rows[0].addresses = []; // pools.json only contains mainnet addresses + } else if (parse) { + rows[0].addresses = JSON.parse(rows[0].addresses); + } + + return rows[0]; + } catch (e) { + logger.err('Cannot get pool from db. Reason: ' + (e instanceof Error ? e.message : e)); + throw e; + } + } + + /** + * Insert a new mining pool in the database + * + * @param pool + */ + public async $insertNewMiningPool(pool: any, slug: string): Promise { + try { + await DB.query(` + INSERT INTO pools + SET name = ?, link = ?, addresses = ?, regexes = ?, slug = ?, unique_id = ?`, + [pool.name, pool.link, JSON.stringify(pool.addresses), JSON.stringify(pool.regexes), slug, pool.id] + ); + } catch (e: any) { + logger.err(`Cannot insert new mining pool into db. Reason: ` + (e instanceof Error ? e.message : e)); + } + } + + /** + * Rename an existing mining pool + * + * @param dbId + * @param newSlug + * @param newName + */ + public async $renameMiningPool(dbId: number, newSlug: string, newName: string): Promise { + try { + await DB.query(` + UPDATE pools + SET slug = ?, name = ? + WHERE id = ?`, + [newSlug, newName, dbId] + ); + } catch (e: any) { + logger.err(`Cannot rename mining pool id ${dbId}. Reason: ` + (e instanceof Error ? e.message : e)); + } + } + + /** + * Update an exisiting mining pool link + * + * @param dbId + * @param newLink + */ + public async $updateMiningPoolLink(dbId: number, newLink: string): Promise { + try { + await DB.query(` + UPDATE pools + SET link = ? + WHERE id = ?`, + [newLink, dbId] + ); + } catch (e: any) { + logger.err(`Cannot update link for mining pool id ${dbId}. Reason: ` + (e instanceof Error ? e.message : e)); + } + + } + + /** + * Update an existing mining pool addresses or coinbase tags + * + * @param dbId + * @param addresses + * @param regexes + */ + public async $updateMiningPoolTags(dbId: number, addresses: string, regexes: string): Promise { + try { + await DB.query(` + UPDATE pools + SET addresses = ?, regexes = ? + WHERE id = ?`, + [JSON.stringify(addresses), JSON.stringify(regexes), dbId] + ); + } catch (e: any) { + logger.err(`Cannot update mining pool id ${dbId}. Reason: ` + (e instanceof Error ? e.message : e)); + } + } + } export default new PoolsRepository(); diff --git a/backend/src/repositories/PricesRepository.ts b/backend/src/repositories/PricesRepository.ts index 639f16dc6..83336eaff 100644 --- a/backend/src/repositories/PricesRepository.ts +++ b/backend/src/repositories/PricesRepository.ts @@ -28,6 +28,16 @@ export interface Conversion { exchangeRates: ExchangeRates; } +export const MAX_PRICES = { + USD: 100000000, + EUR: 100000000, + GBP: 100000000, + CAD: 100000000, + CHF: 100000000, + AUD: 100000000, + JPY: 10000000000, +}; + class PricesRepository { public async $savePrices(time: number, prices: IConversionRates): Promise { if (prices.USD === 0) { @@ -36,6 +46,14 @@ class PricesRepository { return; } + // Sanity check + for (const currency of Object.keys(prices)) { + if (prices[currency] < -1 || prices[currency] > MAX_PRICES[currency]) { // We use -1 to mark a "missing data, so it's a valid entry" + logger.info(`Ignore BTC${currency} price of ${prices[currency]}`); + prices[currency] = 0; + } + } + try { await DB.query(` INSERT INTO prices(time, USD, EUR, GBP, CAD, CHF, AUD, JPY) @@ -86,9 +104,48 @@ class PricesRepository { return rates[0]; } - public async $getHistoricalPrice(): Promise { + public async $getNearestHistoricalPrice(timestamp: number | undefined): Promise { try { - const [rates]: any[] = await DB.query(`SELECT *, UNIX_TIMESTAMP(time) as time FROM prices ORDER BY time DESC`); + const [rates]: any[] = await DB.query(` + SELECT *, UNIX_TIMESTAMP(time) AS time + FROM prices + WHERE UNIX_TIMESTAMP(time) < ? + ORDER BY time DESC + LIMIT 1`, + [timestamp] + ); + if (!rates) { + throw Error(`Cannot get single historical price from the database`); + } + + // Compute fiat exchange rates + const latestPrice = await this.$getLatestConversionRates(); + const exchangeRates: ExchangeRates = { + USDEUR: Math.round(latestPrice.EUR / latestPrice.USD * 100) / 100, + USDGBP: Math.round(latestPrice.GBP / latestPrice.USD * 100) / 100, + USDCAD: Math.round(latestPrice.CAD / latestPrice.USD * 100) / 100, + USDCHF: Math.round(latestPrice.CHF / latestPrice.USD * 100) / 100, + USDAUD: Math.round(latestPrice.AUD / latestPrice.USD * 100) / 100, + USDJPY: Math.round(latestPrice.JPY / latestPrice.USD * 100) / 100, + }; + + return { + prices: rates, + exchangeRates: exchangeRates + }; + } catch (e) { + logger.err(`Cannot fetch single historical prices from the db. Reason ${e instanceof Error ? e.message : e}`); + return null; + } + } + + public async $getHistoricalPrices(): Promise { + try { + const [rates]: any[] = await DB.query(` + SELECT *, UNIX_TIMESTAMP(time) AS time + FROM prices + ORDER BY time DESC + `); if (!rates) { throw Error(`Cannot get average historical price from the database`); } @@ -109,7 +166,7 @@ class PricesRepository { exchangeRates: exchangeRates }; } catch (e) { - logger.err(`Cannot fetch averaged historical prices from the db. Reason ${e instanceof Error ? e.message : e}`); + logger.err(`Cannot fetch historical prices from the db. Reason ${e instanceof Error ? e.message : e}`); return null; } } diff --git a/backend/src/rpc-api/commands.ts b/backend/src/rpc-api/commands.ts index ea9bd7bf0..78f5e12f4 100644 --- a/backend/src/rpc-api/commands.ts +++ b/backend/src/rpc-api/commands.ts @@ -88,5 +88,7 @@ module.exports = { verifyTxOutProof: 'verifytxoutproof', // bitcoind v0.11.0+ walletLock: 'walletlock', walletPassphrase: 'walletpassphrase', - walletPassphraseChange: 'walletpassphrasechange' -} + walletPassphraseChange: 'walletpassphrasechange', + getTxoutSetinfo: 'gettxoutsetinfo', + getIndexInfo: 'getindexinfo', +}; diff --git a/backend/src/tasks/pools-updater.ts b/backend/src/tasks/pools-updater.ts index 086a00cea..32de85f3a 100644 --- a/backend/src/tasks/pools-updater.ts +++ b/backend/src/tasks/pools-updater.ts @@ -8,7 +8,7 @@ import { SocksProxyAgent } from 'socks-proxy-agent'; import * as https from 'https'; /** - * Maintain the most recent version of pools.json + * Maintain the most recent version of pools-v2.json */ class PoolsUpdater { lastRun: number = 0; @@ -31,14 +31,8 @@ class PoolsUpdater { this.lastRun = now; - if (config.SOCKS5PROXY.ENABLED) { - logger.info(`Updating latest mining pools from ${this.poolsUrl} over the Tor network`, logger.tags.mining); - } else { - logger.info(`Updating latest mining pools from ${this.poolsUrl} over clearnet`, logger.tags.mining); - } - try { - const githubSha = await this.fetchPoolsSha(); // Fetch pools.json sha from github + const githubSha = await this.fetchPoolsSha(); // Fetch pools-v2.json sha from github if (githubSha === undefined) { return; } @@ -47,32 +41,57 @@ class PoolsUpdater { this.currentSha = await this.getShaFromDb(); } - logger.debug(`Pools.json sha | Current: ${this.currentSha} | Github: ${githubSha}`); + logger.debug(`pools-v2.json sha | Current: ${this.currentSha} | Github: ${githubSha}`); if (this.currentSha !== undefined && this.currentSha === githubSha) { return; } + // See backend README for more details about the mining pools update process + if (this.currentSha !== undefined && // If we don't have any mining pool, download it at least once + config.MEMPOOL.AUTOMATIC_BLOCK_REINDEXING !== true && // Automatic pools update is disabled + !process.env.npm_config_update_pools // We're not manually updating mining pool + ) { + logger.warn(`Updated mining pools data is available (${githubSha}) but AUTOMATIC_BLOCK_REINDEXING is disabled`); + logger.info(`You can update your mining pools using the --update-pools command flag. You may want to clear your nginx cache as well if applicable`); + return; + } + + const network = config.SOCKS5PROXY.ENABLED ? 'tor' : 'clearnet'; if (this.currentSha === undefined) { - logger.info(`Downloading pools.json for the first time from ${this.poolsUrl}`, logger.tags.mining); + logger.info(`Downloading pools-v2.json for the first time from ${this.poolsUrl} over ${network}`, logger.tags.mining); } else { - logger.warn(`Pools.json is outdated, fetch latest from ${this.poolsUrl}`, logger.tags.mining); + logger.warn(`pools-v2.json is outdated, fetch latest from ${this.poolsUrl} over ${network}`, logger.tags.mining); } const poolsJson = await this.query(this.poolsUrl); if (poolsJson === undefined) { return; } - await poolsParser.migratePoolsJson(poolsJson); - await this.updateDBSha(githubSha); - logger.notice(`PoolsUpdater completed`, logger.tags.mining); + poolsParser.setMiningPools(poolsJson); + + if (config.DATABASE.ENABLED === false) { // Don't run db operations + logger.info('Mining pools-v2.json import completed (no database)'); + return; + } + + try { + await DB.query('START TRANSACTION;'); + await poolsParser.migratePoolsJson(); + await this.updateDBSha(githubSha); + await DB.query('COMMIT;'); + } catch (e) { + logger.err(`Could not migrate mining pools, rolling back. Exception: ${JSON.stringify(e)}`, logger.tags.mining); + await DB.query('ROLLBACK;'); + } + logger.notice('PoolsUpdater completed'); } catch (e) { this.lastRun = now - (oneWeek - oneDay); // Try again in 24h instead of waiting next week - logger.err(`PoolsUpdater failed. Will try again in 24h. Reason: ${e instanceof Error ? e.message : e}`, logger.tags.mining); + logger.err(`PoolsUpdater failed. Will try again in 24h. Exception: ${JSON.stringify(e)}`, logger.tags.mining); } } /** - * Fetch our latest pools.json sha from the db + * Fetch our latest pools-v2.json sha from the db */ private async updateDBSha(githubSha: string): Promise { this.currentSha = githubSha; @@ -81,46 +100,46 @@ class PoolsUpdater { 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), logger.tags.mining); + logger.err('Cannot save github pools-v2.json sha into the db. Reason: ' + (e instanceof Error ? e.message : e), logger.tags.mining); } } } /** - * Fetch our latest pools.json sha from the db + * Fetch our latest pools-v2.json sha from the db */ private async getShaFromDb(): Promise { try { const [rows]: any[] = await DB.query('SELECT string FROM state WHERE name="pools_json_sha"'); return (rows.length > 0 ? rows[0].string : undefined); } catch (e) { - logger.err('Cannot fetch pools.json sha from db. Reason: ' + (e instanceof Error ? e.message : e), logger.tags.mining); + logger.err('Cannot fetch pools-v2.json sha from db. Reason: ' + (e instanceof Error ? e.message : e), logger.tags.mining); return undefined; } } /** - * Fetch our latest pools.json sha from github + * Fetch our latest pools-v2.json sha from github */ private async fetchPoolsSha(): Promise { const response = await this.query(this.treeUrl); if (response !== undefined) { for (const file of response['tree']) { - if (file['path'] === 'pools.json') { + if (file['path'] === 'pools-v2.json') { return file['sha']; } } } - logger.err(`Cannot find "pools.json" in git tree (${this.treeUrl})`, logger.tags.mining); + logger.err(`Cannot find "pools-v2.json" in git tree (${this.treeUrl})`, logger.tags.mining); return undefined; } /** * Http request wrapper */ - private async query(path): Promise { + private async query(path): Promise { type axiosOptions = { headers: { 'User-Agent': string diff --git a/backend/src/tasks/price-updater.ts b/backend/src/tasks/price-updater.ts index 939a1ea85..b39e152ae 100644 --- a/backend/src/tasks/price-updater.ts +++ b/backend/src/tasks/price-updater.ts @@ -3,7 +3,7 @@ import path from 'path'; import config from '../config'; import logger from '../logger'; import { IConversionRates } from '../mempool.interfaces'; -import PricesRepository from '../repositories/PricesRepository'; +import PricesRepository, { MAX_PRICES } from '../repositories/PricesRepository'; import BitfinexApi from './price-feeds/bitfinex-api'; import BitflyerApi from './price-feeds/bitflyer-api'; import CoinbaseApi from './price-feeds/coinbase-api'; @@ -46,13 +46,13 @@ class PriceUpdater { public getEmptyPricesObj(): IConversionRates { return { - USD: 0, - EUR: 0, - GBP: 0, - CAD: 0, - CHF: 0, - AUD: 0, - JPY: 0, + USD: -1, + EUR: -1, + GBP: -1, + CAD: -1, + CHF: -1, + AUD: -1, + JPY: -1, }; } @@ -115,7 +115,7 @@ class PriceUpdater { if (feed.currencies.includes(currency)) { try { const price = await feed.$fetchPrice(currency); - if (price > 0) { + if (price > -1 && price < MAX_PRICES[currency]) { prices.push(price); } logger.debug(`${feed.name} BTC/${currency} price: ${price}`, logger.tags.mining); @@ -239,7 +239,7 @@ class PriceUpdater { for (const currency of this.currencies) { const price = historicalEntry[time][currency]; - if (price > 0) { + if (price > -1 && price < MAX_PRICES[currency]) { grouped[time][currency].push(typeof price === 'string' ? parseInt(price, 10) : price); } } diff --git a/docker/README.md b/docker/README.md index 69bb96030..468d8069b 100644 --- a/docker/README.md +++ b/docker/README.md @@ -102,15 +102,16 @@ Below we list all settings from `mempool-config.json` and the corresponding over "MEMPOOL_BLOCKS_AMOUNT": 8, "BLOCKS_SUMMARIES_INDEXING": false, "USE_SECOND_NODE_FOR_MINFEE": false, - "EXTERNAL_ASSETS": ["https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json"], + "EXTERNAL_ASSETS": [], "STDOUT_LOG_MIN_PRIORITY": "info", "INDEXING_BLOCKS_AMOUNT": false, "AUTOMATIC_BLOCK_REINDEXING": false, - "POOLS_JSON_URL": "https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json", + "POOLS_JSON_URL": "https://raw.githubusercontent.com/mempool/mining-pools/master/pools-v2.json", "POOLS_JSON_TREE_URL": "https://api.github.com/repos/mempool/mining-pools/git/trees/master", "ADVANCED_GBT_AUDIT": false, "ADVANCED_GBT_MEMPOOL": false, "CPFP_INDEXING": false, + "MAX_BLOCKS_BULK_QUERY": 0, }, ``` @@ -141,6 +142,7 @@ Corresponding `docker-compose.yml` overrides: MEMPOOL_ADVANCED_GBT_AUDIT: "" MEMPOOL_ADVANCED_GBT_MEMPOOL: "" MEMPOOL_CPFP_INDEXING: "" + MAX_BLOCKS_BULK_QUERY: "" ... ``` diff --git a/docker/backend/mempool-config.json b/docker/backend/mempool-config.json index 904370f3e..d2aa75c69 100644 --- a/docker/backend/mempool-config.json +++ b/docker/backend/mempool-config.json @@ -25,7 +25,8 @@ "AUDIT": __MEMPOOL_AUDIT__, "ADVANCED_GBT_AUDIT": __MEMPOOL_ADVANCED_GBT_AUDIT__, "ADVANCED_GBT_MEMPOOL": __MEMPOOL_ADVANCED_GBT_MEMPOOL__, - "CPFP_INDEXING": __MEMPOOL_CPFP_INDEXING__ + "CPFP_INDEXING": __MEMPOOL_CPFP_INDEXING__, + "MAX_BLOCKS_BULK_QUERY": __MEMPOOL__MAX_BLOCKS_BULK_QUERY__ }, "CORE_RPC": { "HOST": "__CORE_RPC_HOST__", diff --git a/docker/backend/start.sh b/docker/backend/start.sh index 58b19898a..ee5069386 100755 --- a/docker/backend/start.sh +++ b/docker/backend/start.sh @@ -24,12 +24,13 @@ __MEMPOOL_USER_AGENT__=${MEMPOOL_USER_AGENT:=mempool} __MEMPOOL_STDOUT_LOG_MIN_PRIORITY__=${MEMPOOL_STDOUT_LOG_MIN_PRIORITY:=info} __MEMPOOL_INDEXING_BLOCKS_AMOUNT__=${MEMPOOL_INDEXING_BLOCKS_AMOUNT:=false} __MEMPOOL_AUTOMATIC_BLOCK_REINDEXING__=${MEMPOOL_AUTOMATIC_BLOCK_REINDEXING:=false} -__MEMPOOL_POOLS_JSON_URL__=${MEMPOOL_POOLS_JSON_URL:=https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json} +__MEMPOOL_POOLS_JSON_URL__=${MEMPOOL_POOLS_JSON_URL:=https://raw.githubusercontent.com/mempool/mining-pools/master/pools-v2.json} __MEMPOOL_POOLS_JSON_TREE_URL__=${MEMPOOL_POOLS_JSON_TREE_URL:=https://api.github.com/repos/mempool/mining-pools/git/trees/master} __MEMPOOL_AUDIT__=${MEMPOOL_AUDIT:=false} __MEMPOOL_ADVANCED_GBT_AUDIT__=${MEMPOOL_ADVANCED_GBT_AUDIT:=false} __MEMPOOL_ADVANCED_GBT_MEMPOOL__=${MEMPOOL_ADVANCED_GBT_MEMPOOL:=false} __MEMPOOL_CPFP_INDEXING__=${MEMPOOL_CPFP_INDEXING:=false} +__MEMPOOL_MAX_BLOCKS_BULK_QUERY__=${MEMPOOL_MAX_BLOCKS_BULK_QUERY:=0} # CORE_RPC __CORE_RPC_HOST__=${CORE_RPC_HOST:=127.0.0.1} @@ -142,6 +143,7 @@ sed -i "s!__MEMPOOL_AUDIT__!${__MEMPOOL_AUDIT__}!g" mempool-config.json sed -i "s!__MEMPOOL_ADVANCED_GBT_MEMPOOL__!${__MEMPOOL_ADVANCED_GBT_MEMPOOL__}!g" mempool-config.json sed -i "s!__MEMPOOL_ADVANCED_GBT_AUDIT__!${__MEMPOOL_ADVANCED_GBT_AUDIT__}!g" mempool-config.json sed -i "s!__MEMPOOL_CPFP_INDEXING__!${__MEMPOOL_CPFP_INDEXING__}!g" mempool-config.json +sed -i "s!__MEMPOOL_MAX_BLOCKS_BULK_QUERY__!${__MEMPOOL_MAX_BLOCKS_BULK_QUERY__}!g" mempool-config.json sed -i "s/__CORE_RPC_HOST__/${__CORE_RPC_HOST__}/g" mempool-config.json sed -i "s/__CORE_RPC_PORT__/${__CORE_RPC_PORT__}/g" mempool-config.json diff --git a/frontend/src/app/components/about/about.component.html b/frontend/src/app/components/about/about.component.html index 876bec028..03323b6ed 100644 --- a/frontend/src/app/components/about/about.component.html +++ b/frontend/src/app/components/about/about.component.html @@ -352,7 +352,7 @@ diff --git a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts index 7c71d36fe..b46f7a3e7 100644 --- a/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts +++ b/frontend/src/app/components/block-overview-graph/block-overview-graph.component.ts @@ -5,6 +5,7 @@ import BlockScene from './block-scene'; import TxSprite from './tx-sprite'; import TxView from './tx-view'; import { Position } from './sprite-types'; +import { Price } from 'src/app/services/price.service'; @Component({ selector: 'app-block-overview-graph', @@ -21,6 +22,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On @Input() mirrorTxid: string | void; @Input() unavailable: boolean = false; @Input() auditHighlighting: boolean = false; + @Input() blockConversion: Price; @Output() txClickEvent = new EventEmitter(); @Output() txHoverEvent = new EventEmitter(); @Output() readyEvent = new EventEmitter(); diff --git a/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.html b/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.html index 826eaaf8f..2fa626a95 100644 --- a/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.html +++ b/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.html @@ -16,11 +16,11 @@ Amount - + Fee - {{ fee | number }} sat   + {{ fee | number }} sat   Fee rate diff --git a/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.ts b/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.ts index 6702c4d62..1bd2b8714 100644 --- a/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.ts +++ b/frontend/src/app/components/block-overview-tooltip/block-overview-tooltip.component.ts @@ -1,6 +1,7 @@ import { Component, ElementRef, ViewChild, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core'; import { TransactionStripped } from '../../interfaces/websocket.interface'; import { Position } from '../../components/block-overview-graph/sprite-types.js'; +import { Price } from 'src/app/services/price.service'; @Component({ selector: 'app-block-overview-tooltip', @@ -12,6 +13,7 @@ export class BlockOverviewTooltipComponent implements OnChanges { @Input() cursorPosition: Position; @Input() clickable: boolean; @Input() auditEnabled: boolean = false; + @Input() blockConversion: Price; txid = ''; fee = 0; diff --git a/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.ts b/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.ts index ca1853633..2d8a6f858 100644 --- a/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.ts +++ b/frontend/src/app/components/block-rewards-graph/block-rewards-graph.component.ts @@ -1,19 +1,17 @@ import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core'; import { EChartsOption, graphic } from 'echarts'; -import { Observable, Subscription } from 'rxjs'; +import { Observable } from 'rxjs'; import { map, share, startWith, switchMap, tap } from 'rxjs/operators'; import { ApiService } from '../../services/api.service'; import { SeoService } from '../../services/seo.service'; import { formatNumber } from '@angular/common'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { download, formatterXAxis, formatterXAxisLabel, formatterXAxisTimeCategory } from '../../shared/graphs.utils'; +import { download, formatterXAxis } from '../../shared/graphs.utils'; import { MiningService } from '../../services/mining.service'; -import { StateService } from '../../services/state.service'; import { StorageService } from '../../services/storage.service'; import { ActivatedRoute } from '@angular/router'; import { FiatShortenerPipe } from '../../shared/pipes/fiat-shortener.pipe'; import { FiatCurrencyPipe } from '../../shared/pipes/fiat-currency.pipe'; -import { fiatCurrencies } from '../../app.constants'; @Component({ selector: 'app-block-rewards-graph', @@ -47,7 +45,6 @@ export class BlockRewardsGraphComponent implements OnInit { timespan = ''; chartInstance: any = undefined; - currencySubscription: Subscription; currency: string; constructor( @@ -56,19 +53,12 @@ export class BlockRewardsGraphComponent implements OnInit { private apiService: ApiService, private formBuilder: UntypedFormBuilder, private miningService: MiningService, - private stateService: StateService, private storageService: StorageService, private route: ActivatedRoute, private fiatShortenerPipe: FiatShortenerPipe, private fiatCurrencyPipe: FiatCurrencyPipe, ) { - this.currencySubscription = this.stateService.fiatCurrency$.subscribe((fiat) => { - if (fiat && fiatCurrencies[fiat]?.indexed) { - this.currency = fiat; - } else { - this.currency = 'USD'; - } - }); + this.currency = 'USD'; } ngOnInit(): void { diff --git a/frontend/src/app/components/block/block-preview.component.html b/frontend/src/app/components/block/block-preview.component.html index 7300182f3..29da36373 100644 --- a/frontend/src/app/components/block/block-preview.component.html +++ b/frontend/src/app/components/block/block-preview.component.html @@ -8,7 +8,7 @@

Genesis - {{ blockHeight }} + {{ blockHeight }}

{{ blockHash.slice(0,32) }}

diff --git a/frontend/src/app/components/block/block.component.html b/frontend/src/app/components/block/block.component.html index bb4d2082c..4c7e4684a 100644 --- a/frontend/src/app/components/block/block.component.html +++ b/frontend/src/app/components/block/block.component.html @@ -108,6 +108,7 @@ [blockLimit]="stateService.blockVSize" [orientation]="'top'" [flip]="false" + [blockConversion]="blockConversion" (txClickEvent)="onTxClick($event)" > diff --git a/frontend/src/app/components/block/block.component.ts b/frontend/src/app/components/block/block.component.ts index 9e476ac61..35f47de85 100644 --- a/frontend/src/app/components/block/block.component.ts +++ b/frontend/src/app/components/block/block.component.ts @@ -443,9 +443,9 @@ export class BlockComponent implements OnInit, OnDestroy { } this.priceSubscription = block$.pipe( switchMap((block) => { - return this.priceService.getPrices().pipe( - tap(() => { - this.blockConversion = this.priceService.getPriceForTimestamp(block.timestamp); + return this.priceService.getBlockPrice$(block.timestamp).pipe( + tap((price) => { + this.blockConversion = price; }) ); }) @@ -471,6 +471,7 @@ export class BlockComponent implements OnInit, OnDestroy { this.auditSubscription?.unsubscribe(); this.unsubscribeNextBlockSubscriptions(); this.childChangeSubscription?.unsubscribe(); + this.priceSubscription?.unsubscribe(); } unsubscribeNextBlockSubscriptions() { diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html index 400016d02..746c5fa5c 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.html @@ -1,8 +1,8 @@
+ *ngIf="static || (loadingBlocks$ | async) === false; else loadingBlocksTemplate">
- +
- {{ i }} - transaction - {{ i }} - transactions + {{ i }} transaction + {{ i }} transactions
@@ -59,19 +57,19 @@
- +
- +
- -
+ +
+ [ngStyle]="convertStyleForLoadingBlock(blockStyles[i])">
diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss index 64bfd2379..5db452470 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.scss @@ -137,6 +137,10 @@ opacity: 1; } +.loading .bitcoin-block.mined-block { + background: #2d3348; +} + @keyframes opacityPulse { 0% {opacity: 0.7;} 50% {opacity: 1.0;} diff --git a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts index fb37cf72a..3feaf6c2d 100644 --- a/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts +++ b/frontend/src/app/components/blockchain-blocks/blockchain-blocks.component.ts @@ -22,6 +22,8 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { @Input() offset: number = 0; @Input() height: number = 0; @Input() count: number = 8; + @Input() loadingTip: boolean = false; + @Input() connected: boolean = true; specialBlocks = specialBlocks; network = ''; @@ -288,6 +290,13 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy { }; } + convertStyleForLoadingBlock(style) { + return { + ...style, + background: "#2d3348", + }; + } + getStyleForLoadingBlock(index: number, animateEnterFrom: number = 0) { const addLeft = animateEnterFrom || 0; diff --git a/frontend/src/app/components/blockchain/blockchain.component.html b/frontend/src/app/components/blockchain/blockchain.component.html index ad2e5e86a..0c4a1cbb7 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.html +++ b/frontend/src/app/components/blockchain/blockchain.component.html @@ -6,7 +6,7 @@ - +
diff --git a/frontend/src/app/components/blockchain/blockchain.component.ts b/frontend/src/app/components/blockchain/blockchain.component.ts index 0ad3625ea..ab9875a4c 100644 --- a/frontend/src/app/components/blockchain/blockchain.component.ts +++ b/frontend/src/app/components/blockchain/blockchain.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, Input, OnChanges, SimpleChanges } from '@angular/core'; -import { Subscription } from 'rxjs'; +import { firstValueFrom, Subscription } from 'rxjs'; import { StateService } from '../../services/state.service'; @Component({ @@ -18,6 +18,9 @@ export class BlockchainComponent implements OnInit, OnDestroy { timeLtrSubscription: Subscription; timeLtr: boolean = this.stateService.timeLtr.value; ltrTransitionEnabled = false; + connectionStateSubscription: Subscription; + loadingTip: boolean = true; + connected: boolean = true; constructor( public stateService: StateService, @@ -28,10 +31,17 @@ export class BlockchainComponent implements OnInit, OnDestroy { this.timeLtrSubscription = this.stateService.timeLtr.subscribe((ltr) => { this.timeLtr = !!ltr; }); + this.connectionStateSubscription = this.stateService.connectionState$.subscribe(state => { + this.connected = (state === 2); + }) + firstValueFrom(this.stateService.chainTip$).then(tip => { + this.loadingTip = false; + }); } ngOnDestroy() { this.timeLtrSubscription.unsubscribe(); + this.connectionStateSubscription.unsubscribe(); } trackByPageFn(index: number, item: { index: number }) { diff --git a/frontend/src/app/components/qrcode/qrcode.component.html b/frontend/src/app/components/qrcode/qrcode.component.html index d7886b907..56f32f42c 100644 --- a/frontend/src/app/components/qrcode/qrcode.component.html +++ b/frontend/src/app/components/qrcode/qrcode.component.html @@ -1,4 +1,4 @@
- +
diff --git a/frontend/src/app/components/qrcode/qrcode.component.ts b/frontend/src/app/components/qrcode/qrcode.component.ts index e8ebac904..dad7522c6 100644 --- a/frontend/src/app/components/qrcode/qrcode.component.ts +++ b/frontend/src/app/components/qrcode/qrcode.component.ts @@ -12,6 +12,7 @@ export class QrcodeComponent implements AfterViewInit { @Input() data: string; @Input() size = 125; @Input() imageUrl: string; + @Input() border = 0; @ViewChild('canvas') canvas: ElementRef; qrcodeObject: any; diff --git a/frontend/src/app/components/search-form/search-results/search-results.component.html b/frontend/src/app/components/search-form/search-results/search-results.component.html index a13228170..b0d043f53 100644 --- a/frontend/src/app/components/search-form/search-results/search-results.component.html +++ b/frontend/src/app/components/search-form/search-results/search-results.component.html @@ -1,30 +1,30 @@ + +Go to "{{ x }}" diff --git a/frontend/src/app/components/start/start.component.ts b/frontend/src/app/components/start/start.component.ts index ff66e7b97..c7b8a83bc 100644 --- a/frontend/src/app/components/start/start.component.ts +++ b/frontend/src/app/components/start/start.component.ts @@ -21,6 +21,7 @@ export class StartComponent implements OnInit, OnDestroy { timeLtr: boolean = this.stateService.timeLtr.value; chainTipSubscription: Subscription; chainTip: number = -1; + tipIsSet: boolean = false; markBlockSubscription: Subscription; blockCounterSubscription: Subscription; @ViewChild('blockchainContainer') blockchainContainer: ElementRef; @@ -58,6 +59,7 @@ export class StartComponent implements OnInit, OnDestroy { }); this.chainTipSubscription = this.stateService.chainTip$.subscribe((height) => { this.chainTip = height; + this.tipIsSet = true; this.updatePages(); if (this.pendingMark != null) { this.scrollToBlock(this.pendingMark); @@ -66,7 +68,7 @@ export class StartComponent implements OnInit, OnDestroy { }); this.markBlockSubscription = this.stateService.markBlock$.subscribe((mark) => { if (mark?.blockHeight != null) { - if (this.chainTip >=0) { + if (this.tipIsSet) { if (!this.blockInViewport(mark.blockHeight)) { this.scrollToBlock(mark.blockHeight); } @@ -123,7 +125,7 @@ export class StartComponent implements OnInit, OnDestroy { this.minScrollWidth = this.firstPageWidth + (this.pageWidth * 2); if (firstVisibleBlock != null) { - this.scrollToBlock(firstVisibleBlock, offset); + this.scrollToBlock(firstVisibleBlock, offset + (this.isMobile ? this.blockWidth : 0)); } else { this.updatePages(); } @@ -178,8 +180,10 @@ export class StartComponent implements OnInit, OnDestroy { setTimeout(() => { this.scrollToBlock(height, blockOffset); }, 50); return; } - const targetHeight = this.isMobile ? height - 1 : height; - const viewingPageIndex = this.getPageIndexOf(targetHeight); + if (this.isMobile) { + blockOffset -= this.blockWidth; + } + const viewingPageIndex = this.getPageIndexOf(height); const pages = []; this.pageIndex = Math.max(viewingPageIndex - 1, 0); let viewingPage = this.getPageAt(viewingPageIndex); @@ -189,7 +193,7 @@ export class StartComponent implements OnInit, OnDestroy { viewingPage = this.getPageAt(viewingPageIndex); } const left = viewingPage.offset - this.getConvertedScrollOffset(); - const blockIndex = viewingPage.height - targetHeight; + const blockIndex = viewingPage.height - height; const targetOffset = (this.blockWidth * blockIndex) + left; let deltaOffset = targetOffset - blockOffset; diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts index 06a4c5836..4d036e131 100644 --- a/frontend/src/app/components/transaction/transaction.component.ts +++ b/frontend/src/app/components/transaction/transaction.component.ts @@ -327,9 +327,9 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { this.fetchRbfHistory$.next(this.tx.txid); } - this.priceService.getPrices().pipe( - tap(() => { - this.blockConversion = this.priceService.getPriceForTimestamp(tx.status.block_time); + this.priceService.getBlockPrice$(tx.status.block_time, true).pipe( + tap((price) => { + this.blockConversion = price; }) ).subscribe(); diff --git a/frontend/src/app/components/transactions-list/transactions-list.component.ts b/frontend/src/app/components/transactions-list/transactions-list.component.ts index bfdaa02bc..6422d8507 100644 --- a/frontend/src/app/components/transactions-list/transactions-list.component.ts +++ b/frontend/src/app/components/transactions-list/transactions-list.component.ts @@ -6,7 +6,7 @@ import { Outspend, Transaction, Vin, Vout } from '../../interfaces/electrs.inter import { ElectrsApiService } from '../../services/electrs-api.service'; import { environment } from '../../../environments/environment'; import { AssetsService } from '../../services/assets.service'; -import { filter, map, tap, switchMap } from 'rxjs/operators'; +import { filter, map, tap, switchMap, shareReplay } from 'rxjs/operators'; import { BlockExtended } from '../../interfaces/node-api.interface'; import { ApiService } from '../../services/api.service'; import { PriceService } from 'src/app/services/price.service'; @@ -150,10 +150,8 @@ export class TransactionsListComponent implements OnInit, OnChanges { tx['addressValue'] = addressIn - addressOut; } - this.priceService.getPrices().pipe( - tap(() => { - tx['price'] = this.priceService.getPriceForTimestamp(tx.status.block_time); - }) + this.priceService.getBlockPrice$(tx.status.block_time).pipe( + tap((price) => tx['price'] = price) ).subscribe(); }); const txIds = this.transactions.filter((tx) => !tx._outspends).map((tx) => tx.txid); diff --git a/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html b/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html index 25e9ccc1f..395c38f88 100644 --- a/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html +++ b/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -56,7 +56,7 @@

Confidential

-

+

diff --git a/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.ts b/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.ts index 54c58ffab..da8d91ab3 100644 --- a/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.ts +++ b/frontend/src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.ts @@ -1,5 +1,6 @@ -import { Component, ElementRef, ViewChild, Input, OnChanges, ChangeDetectionStrategy } from '@angular/core'; -import { TransactionStripped } from '../../interfaces/websocket.interface'; +import { Component, ElementRef, ViewChild, Input, OnChanges, OnInit } from '@angular/core'; +import { tap } from 'rxjs'; +import { Price, PriceService } from 'src/app/services/price.service'; interface Xput { type: 'input' | 'output' | 'fee'; @@ -14,6 +15,7 @@ interface Xput { pegin?: boolean; pegout?: string; confidential?: boolean; + timestamp?: number; } @Component({ @@ -27,12 +29,21 @@ export class TxBowtieGraphTooltipComponent implements OnChanges { @Input() isConnector: boolean = false; tooltipPosition = { x: 0, y: 0 }; + blockConversion: Price; @ViewChild('tooltip') tooltipElement: ElementRef; - constructor() {} + constructor(private priceService: PriceService) {} ngOnChanges(changes): void { + if (changes.line?.currentValue) { + this.priceService.getBlockPrice$(changes.line?.currentValue.timestamp, true).pipe( + tap((price) => { + this.blockConversion = price; + }) + ).subscribe(); + } + if (changes.cursorPosition && changes.cursorPosition.currentValue) { let x = Math.max(10, changes.cursorPosition.currentValue.x - 50); let y = changes.cursorPosition.currentValue.y + 20; diff --git a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts index 49d97dd40..9c4991590 100644 --- a/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts +++ b/frontend/src/app/components/tx-bowtie-graph/tx-bowtie-graph.component.ts @@ -29,6 +29,7 @@ interface Xput { pegin?: boolean; pegout?: string; confidential?: boolean; + timestamp?: number; } @Component({ @@ -152,6 +153,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges { index: i, pegout: v?.pegout?.scriptpubkey_address, confidential: (this.isLiquid && v?.value === undefined), + timestamp: this.tx.status.block_time } as Xput; }); @@ -171,6 +173,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges { coinbase: v?.is_coinbase, pegin: v?.is_pegin, confidential: (this.isLiquid && v?.prevout?.value === undefined), + timestamp: this.tx.status.block_time } as Xput; }); @@ -196,8 +199,8 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges { this.outputs = this.initLines('out', voutWithFee, totalValue, this.maxStrands); this.middle = { - path: `M ${(this.width / 2) - this.midWidth} ${(this.height / 2) + 0.5} L ${(this.width / 2) + this.midWidth} ${(this.height / 2) + 0.5}`, - style: `stroke-width: ${this.combinedWeight + 1}; stroke: ${this.gradient[1]}` + path: `M ${(this.width / 2) - this.midWidth} ${(this.height / 2) + 0.25} L ${(this.width / 2) + this.midWidth} ${(this.height / 2) + 0.25}`, + style: `stroke-width: ${this.combinedWeight + 0.5}; stroke: ${this.gradient[1]}` }; this.hasLine = this.inputs.reduce((line, put) => line || !put.zeroValue, false) @@ -254,7 +257,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges { const lineParams = weights.map((w, i) => { return { weight: w, - thickness: xputs[i].value === 0 ? this.zeroValueThickness : Math.max(this.minWeight - 1, w) + 1, + thickness: xputs[i].value === 0 ? this.zeroValueThickness : Math.min(this.combinedWeight + 0.5, Math.max(this.minWeight - 1, w) + 1), offset: 0, innerY: 0, outerY: 0, @@ -266,7 +269,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges { // bounds of the middle segment const innerTop = (this.height / 2) - (this.combinedWeight / 2); - const innerBottom = innerTop + this.combinedWeight; + const innerBottom = innerTop + this.combinedWeight + 0.5; // tracks the visual bottom of the endpoints of the previous line let lastOuter = 0; let lastInner = innerTop; @@ -291,7 +294,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges { // set the vertical position of the (center of the) outer side of the line line.outerY = lastOuter + (line.thickness / 2); - line.innerY = Math.min(innerBottom + (line.thickness / 2), Math.max(innerTop + (line.thickness / 2), lastInner + (line.weight / 2))); + line.innerY = Math.min(innerBottom - (line.thickness / 2), Math.max(innerTop + (line.thickness / 2), lastInner + (line.weight / 2))); // special case to center single input/outputs if (xputs.length === 1) { diff --git a/frontend/src/app/docs/api-docs/api-docs.component.html b/frontend/src/app/docs/api-docs/api-docs.component.html index e7fb5af63..47332abc3 100644 --- a/frontend/src/app/docs/api-docs/api-docs.component.html +++ b/frontend/src/app/docs/api-docs/api-docs.component.html @@ -10,7 +10,7 @@
-

mempool.space merely provides data about the Bitcoin network. It cannot help you with retrieving funds, confirming your transaction quicker, etc.

For any such requests, you need to get in touch with the entity that helped make the transaction (wallet software, exchange company, etc).

+

mempool.space merely provides data about the Bitcoin network. It cannot help you with retrieving funds, confirming your transaction quicker, etc.

For any such requests, you need to get in touch with the entity that helped make the transaction (wallet software, exchange company, etc).

diff --git a/frontend/src/app/fiat/fiat.component.html b/frontend/src/app/fiat/fiat.component.html index a1bf79978..998153d29 100644 --- a/frontend/src/app/fiat/fiat.component.html +++ b/frontend/src/app/fiat/fiat.component.html @@ -1,7 +1,7 @@ {{ ( - (blockConversion.price[currency] > 0 ? blockConversion.price[currency] : null) ?? + (blockConversion.price[currency] >= 0 ? blockConversion.price[currency] : null) ?? (blockConversion.price['USD'] * blockConversion.exchangeRates['USD' + currency]) ?? 0 ) * value / 100000000 | fiatCurrency : digitsInfo : currency }} diff --git a/frontend/src/app/lightning/channel/closing-type/closing-type.component.ts b/frontend/src/app/lightning/channel/closing-type/closing-type.component.ts index 5aa6158d3..b6313250f 100644 --- a/frontend/src/app/lightning/channel/closing-type/closing-type.component.ts +++ b/frontend/src/app/lightning/channel/closing-type/closing-type.component.ts @@ -17,19 +17,19 @@ export class ClosingTypeComponent implements OnChanges { getLabelFromType(type: number): { label: string; class: string } { switch (type) { case 1: return { - label: 'Mutually closed', + label: $localize`Mutually closed`, class: 'success', }; case 2: return { - label: 'Force closed', + label: $localize`Force closed`, class: 'warning', }; case 3: return { - label: 'Force closed with penalty', + label: $localize`Force closed with penalty`, class: 'danger', }; default: return { - label: 'Unknown', + label: $localize`:@@e5d8bb389c702588877f039d72178f219453a72d:Unknown`, class: 'secondary', }; } diff --git a/frontend/src/app/lightning/channels-statistics/channels-statistics.component.html b/frontend/src/app/lightning/channels-statistics/channels-statistics.component.html index 44e19b8f6..31b4c33af 100644 --- a/frontend/src/app/lightning/channels-statistics/channels-statistics.component.html +++ b/frontend/src/app/lightning/channels-statistics/channels-statistics.component.html @@ -1,9 +1,9 @@
avg + [ngClass]="{'inactive': mode === 'avg'}">avg | med + [ngClass]="{'inactive': mode === 'med'}">med
diff --git a/frontend/src/app/lightning/node-fee-chart/node-fee-chart.component.ts b/frontend/src/app/lightning/node-fee-chart/node-fee-chart.component.ts index f0370d3e1..242ecc6ed 100644 --- a/frontend/src/app/lightning/node-fee-chart/node-fee-chart.component.ts +++ b/frontend/src/app/lightning/node-fee-chart/node-fee-chart.component.ts @@ -167,7 +167,7 @@ export class NodeFeeChartComponent implements OnInit { padding: 10, data: [ { - name: 'Outgoing Fees', + name: $localize`Outgoing Fees`, inactiveColor: 'rgb(110, 112, 121)', textStyle: { color: 'white', @@ -175,7 +175,7 @@ export class NodeFeeChartComponent implements OnInit { icon: 'roundRect', }, { - name: 'Incoming Fees', + name: $localize`Incoming Fees`, inactiveColor: 'rgb(110, 112, 121)', textStyle: { color: 'white', @@ -205,7 +205,7 @@ export class NodeFeeChartComponent implements OnInit { series: outgoingData.length === 0 ? undefined : [ { zlevel: 0, - name: 'Outgoing Fees', + name: $localize`Outgoing Fees`, data: outgoingData.map(bucket => ({ value: bucket.capacity, label: bucket.label, @@ -219,7 +219,7 @@ export class NodeFeeChartComponent implements OnInit { }, { zlevel: 0, - name: 'Incoming Fees', + name: $localize`Incoming Fees`, data: incomingData.map(bucket => ({ value: -bucket.capacity, label: bucket.label, diff --git a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts index 20ce5cc6f..0ff9f4af1 100644 --- a/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts +++ b/frontend/src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts @@ -130,7 +130,7 @@ export class NodesNetworksChartComponent implements OnInit { }, text: $localize`:@@b420668a91f8ebaf6e6409c4ba87f1d45961d2bd:Lightning Nodes Per Network`, left: 'center', - top: 11, + top: 0, zlevel: 10, }; } @@ -227,8 +227,8 @@ export class NodesNetworksChartComponent implements OnInit { title: title, animation: false, grid: { - height: this.widget ? 100 : undefined, - top: this.widget ? 10 : 40, + height: this.widget ? 90 : undefined, + top: this.widget ? 20 : 40, bottom: this.widget ? 0 : 70, right: (isMobile() && this.widget) ? 35 : this.right, left: (isMobile() && this.widget) ? 40 :this.left, diff --git a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts index 916483781..b93ee1f3d 100644 --- a/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts +++ b/frontend/src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts @@ -121,7 +121,7 @@ export class LightningStatisticsChartComponent implements OnInit { }, text: $localize`:@@ea8db27e6db64f8b940711948c001a1100e5fe9f:Lightning Network Capacity`, left: 'center', - top: 11, + top: 0, zlevel: 10, }; } @@ -137,8 +137,8 @@ export class LightningStatisticsChartComponent implements OnInit { ]), ], grid: { - height: this.widget ? 100 : undefined, - top: this.widget ? 10 : 40, + height: this.widget ? 90 : undefined, + top: this.widget ? 20 : 40, bottom: this.widget ? 0 : 70, right: (isMobile() && this.widget) ? 35 : this.right, left: (isMobile() && this.widget) ? 40 :this.left, diff --git a/frontend/src/app/services/api.service.ts b/frontend/src/app/services/api.service.ts index 2c74de361..840fd5070 100644 --- a/frontend/src/app/services/api.service.ts +++ b/frontend/src/app/services/api.service.ts @@ -305,7 +305,10 @@ export class ApiService { ); } - getHistoricalPrice$(): Observable { - return this.httpClient.get( this.apiBaseUrl + this.apiBasePath + '/api/v1/historical-price'); + getHistoricalPrice$(timestamp: number | undefined): Observable { + return this.httpClient.get( + this.apiBaseUrl + this.apiBasePath + '/api/v1/historical-price' + + (timestamp ? `?timestamp=${timestamp}` : '') + ); } } diff --git a/frontend/src/app/services/cache.service.ts b/frontend/src/app/services/cache.service.ts index be37164dd..15ef99859 100644 --- a/frontend/src/app/services/cache.service.ts +++ b/frontend/src/app/services/cache.service.ts @@ -62,7 +62,12 @@ export class CacheService { for (let i = 0; i < chunkSize; i++) { this.blockLoading[maxHeight - i] = true; } - const result = await firstValueFrom(this.apiService.getBlocks$(maxHeight)); + let result; + try { + result = await firstValueFrom(this.apiService.getBlocks$(maxHeight)); + } catch (e) { + console.log("failed to load blocks: ", e.message); + } for (let i = 0; i < chunkSize; i++) { delete this.blockLoading[maxHeight - i]; } diff --git a/frontend/src/app/services/price.service.ts b/frontend/src/app/services/price.service.ts index fe6d67bb6..e3ec93c8b 100644 --- a/frontend/src/app/services/price.service.ts +++ b/frontend/src/app/services/price.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; -import { map, Observable, of, shareReplay } from 'rxjs'; +import { map, Observable, of, share, shareReplay, tap } from 'rxjs'; import { ApiService } from './api.service'; +import { StateService } from './state.service'; // nodejs backend interfaces export interface ApiPrice { @@ -40,13 +41,20 @@ export interface ConversionDict { providedIn: 'root' }) export class PriceService { + priceObservable$: Observable; + singlePriceObservable$: Observable; + + lastQueriedTimestamp: number; + lastPriceHistoryUpdate: number; + historicalPrice: ConversionDict = { prices: null, exchangeRates: null, }; constructor( - private apiService: ApiService + private apiService: ApiService, + private stateService: StateService ) { } @@ -61,65 +69,90 @@ export class PriceService { }; } - /** - * Fetch prices from the nodejs backend only once - */ - getPrices(): Observable { - if (this.historicalPrice.prices) { - return of(null); + getBlockPrice$(blockTimestamp: number, singlePrice = false): Observable { + if (this.stateService.env.BASE_MODULE !== 'mempool') { + return of(undefined); } - return this.apiService.getHistoricalPrice$().pipe( - map((conversion: Conversion) => { - if (!this.historicalPrice.prices) { - this.historicalPrice.prices = Object(); - } - for (const price of conversion.prices) { - this.historicalPrice.prices[price.time] = { - USD: price.USD, EUR: price.EUR, GBP: price.GBP, CAD: price.CAD, - CHF: price.CHF, AUD: price.AUD, JPY: price.JPY - }; - } - this.historicalPrice.exchangeRates = conversion.exchangeRates; - return; - }), - shareReplay(), - ); - } + const now = new Date().getTime() / 1000; - /** - * Note: The first block with a price we have is block 68952 (using MtGox price history) - * - * @param blockTimestamp - */ - getPriceForTimestamp(blockTimestamp: number): Price | null { - if (!blockTimestamp) { - return undefined; - } - - const priceTimestamps = Object.keys(this.historicalPrice.prices); - priceTimestamps.push(Number.MAX_SAFE_INTEGER.toString()); - priceTimestamps.sort().reverse(); - - // Small trick here. Because latest blocks have higher timestamps than our - // latest price timestamp (we only insert once every hour), we have no price for them. - // Therefore we want to fallback to the websocket price by returning an undefined `price` field. - // Since this.historicalPrice.prices[Number.MAX_SAFE_INTEGER] does not exists - // it will return `undefined` and automatically use the websocket price. - // This way we can differenciate blocks without prices like the genesis block - // vs ones without a price (yet) like the latest blocks - - for (const t of priceTimestamps) { - const priceTimestamp = parseInt(t, 10); - if (blockTimestamp > priceTimestamp) { - return { - price: this.historicalPrice.prices[priceTimestamp], - exchangeRates: this.historicalPrice.exchangeRates, - }; + /** + * Query nearest price for a specific blockTimestamp. The observable is invalidated if we + * query a different timestamp than the last one + */ + if (singlePrice) { + if (!this.singlePriceObservable$ || (this.singlePriceObservable$ && blockTimestamp !== this.lastQueriedTimestamp)) { + this.singlePriceObservable$ = this.apiService.getHistoricalPrice$(blockTimestamp).pipe(shareReplay()); + this.lastQueriedTimestamp = blockTimestamp; } + + return this.singlePriceObservable$.pipe( + map((conversion) => { + if (conversion.prices.length <= 0) { + return this.getEmptyPrice(); + } + return { + price: { + USD: conversion.prices[0].USD, EUR: conversion.prices[0].EUR, GBP: conversion.prices[0].GBP, CAD: conversion.prices[0].CAD, + CHF: conversion.prices[0].CHF, AUD: conversion.prices[0].AUD, JPY: conversion.prices[0].JPY + }, + exchangeRates: conversion.exchangeRates, + }; + }) + ); } - return this.getEmptyPrice(); + /** + * Query all price history only once. The observable is invalidated after 1 hour + */ + else { + if (!this.priceObservable$ || (this.priceObservable$ && (now - this.lastPriceHistoryUpdate > 3600))) { + this.priceObservable$ = this.apiService.getHistoricalPrice$(undefined).pipe(shareReplay()); + this.lastPriceHistoryUpdate = new Date().getTime() / 1000; + } + + return this.priceObservable$.pipe( + map((conversion) => { + if (!blockTimestamp) { + return undefined; + } + + const historicalPrice = { + prices: {}, + exchangeRates: conversion.exchangeRates, + }; + for (const price of conversion.prices) { + historicalPrice.prices[price.time] = { + USD: price.USD, EUR: price.EUR, GBP: price.GBP, CAD: price.CAD, + CHF: price.CHF, AUD: price.AUD, JPY: price.JPY + }; + } + + const priceTimestamps = Object.keys(historicalPrice.prices); + priceTimestamps.push(Number.MAX_SAFE_INTEGER.toString()); + priceTimestamps.sort().reverse(); + + // Small trick here. Because latest blocks have higher timestamps than our + // latest price timestamp (we only insert once every hour), we have no price for them. + // Therefore we want to fallback to the websocket price by returning an undefined `price` field. + // Since historicalPrice.prices[Number.MAX_SAFE_INTEGER] does not exists + // it will return `undefined` and automatically use the websocket price. + // This way we can differenciate blocks without prices like the genesis block + // vs ones without a price (yet) like the latest blocks + + for (const t of priceTimestamps) { + const priceTimestamp = parseInt(t, 10); + if (blockTimestamp > priceTimestamp) { + return { + price: historicalPrice.prices[priceTimestamp], + exchangeRates: historicalPrice.exchangeRates, + }; + } + } + + return this.getEmptyPrice(); + }) + ); + } } } - diff --git a/frontend/src/locale/messages.de.xlf b/frontend/src/locale/messages.de.xlf index 3af25e4a2..e22f0c7db 100644 --- a/frontend/src/locale/messages.de.xlf +++ b/frontend/src/locale/messages.de.xlf @@ -359,11 +359,11 @@ src/app/components/block/block.component.html - 303,304 + 310,311 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 26,27 + 46,47 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -384,11 +384,11 @@ src/app/components/block/block.component.html - 304,305 + 311,312 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 27,28 + 47,48 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -598,7 +598,7 @@ src/app/components/pool-ranking/pool-ranking.component.html - 94,96 + 94,95 @@ -777,14 +777,22 @@ src/app/components/about/about.component.html 385,389 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 88 + src/app/dashboard/dashboard.component.html - 150,152 + 157,159 src/app/docs/docs/docs.component.html 51 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 97 + Terms of Service shared.terms-of-service @@ -795,14 +803,22 @@ src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html 113,120 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 90 + src/app/dashboard/dashboard.component.html - 152,154 + 159,161 src/app/docs/docs/docs.component.html 53 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 99 + Privacy Policy shared.privacy-policy @@ -990,7 +1006,7 @@ src/app/dashboard/dashboard.component.html - 124,125 + 124,126 @@ -1038,7 +1054,7 @@ src/app/components/transaction/transaction.component.html - 158,160 + 152,154 src/app/components/transactions-list/transactions-list.component.html @@ -1054,11 +1070,11 @@ src/app/components/block/block.component.html - 245,246 + 252,253 src/app/components/transaction/transaction.component.html - 288,290 + 282,284 transaction.version @@ -1108,7 +1124,7 @@ src/app/components/transactions-list/transactions-list.component.html - 294,295 + 296,297 Transaction singular confirmation count shared.confirmation-count.singular @@ -1130,7 +1146,7 @@ src/app/components/transactions-list/transactions-list.component.html - 295,296 + 297,298 Transaction plural confirmation count shared.confirmation-count.plural @@ -1142,10 +1158,6 @@ src/app/bisq/bisq-transaction/bisq-transaction.component.html 43,45 - - src/app/components/transaction/transaction.component.html - 65,67 - Transaction included in block transaction.included-in-block @@ -1158,11 +1170,11 @@ src/app/components/transaction/transaction.component.html - 77,80 + 71,74 src/app/components/transaction/transaction.component.html - 135,138 + 129,132 Transaction features transaction.features @@ -1190,11 +1202,11 @@ src/app/components/transaction/transaction.component.html - 262,267 + 256,261 src/app/components/transaction/transaction.component.html - 406,412 + 400,406 transaction.details @@ -1211,11 +1223,11 @@ src/app/components/transaction/transaction.component.html - 249,253 + 243,247 src/app/components/transaction/transaction.component.html - 377,383 + 371,377 Transaction inputs and outputs transaction.inputs-and-outputs @@ -1233,7 +1245,7 @@ src/app/components/transaction/transaction.component.ts - 241,240 + 244,243 @@ -1253,7 +1265,7 @@ src/app/components/transaction/transaction.component.html - 159,160 + 153,154 src/app/dashboard/dashboard.component.html @@ -1269,7 +1281,7 @@ src/app/components/transaction/transaction.component.html - 72,73 + 66,67 Transaction Confirmed state transaction.confirmed @@ -1569,7 +1581,7 @@ src/app/components/amount/amount.component.html - 6,9 + 18,21 src/app/components/asset-circulation/asset-circulation.component.html @@ -1585,7 +1597,7 @@ src/app/components/transactions-list/transactions-list.component.html - 302,304 + 304,306 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -2049,7 +2061,7 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 161 + 165 @@ -2065,7 +2077,7 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 163 + 167 @@ -2077,7 +2089,7 @@ src/app/components/block-fees-graph/block-fees-graph.component.ts - 62 + 67 src/app/components/graphs/graphs.component.html @@ -2090,15 +2102,15 @@ Blöcke am indizieren src/app/components/block-fees-graph/block-fees-graph.component.ts - 110,105 + 116,111 src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 108,103 + 113,108 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 115,110 + 116,111 src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -2143,7 +2155,7 @@ src/app/components/transaction/transaction.component.html - 478 + 472 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -2169,11 +2181,11 @@ src/app/components/transaction/transaction.component.html - 478,479 + 472 src/app/components/transactions-list/transactions-list.component.html - 286,287 + 288 sat shared.sat @@ -2187,11 +2199,11 @@ src/app/components/transaction/transaction.component.html - 161,165 + 155,159 src/app/components/transaction/transaction.component.html - 481,483 + 475,477 src/app/lightning/channel/channel-box/channel-box.component.html @@ -2221,19 +2233,19 @@ src/app/components/block/block.component.html - 123,126 + 124,127 src/app/components/block/block.component.html - 127 + 128,130 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 12,14 + 19,22 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 15,17 + 30,33 src/app/components/fees-box/fees-box.component.html @@ -2273,27 +2285,27 @@ src/app/components/transaction/transaction.component.html - 173,174 + 167,168 src/app/components/transaction/transaction.component.html - 184,185 + 178,179 src/app/components/transaction/transaction.component.html - 195,196 + 189,190 src/app/components/transaction/transaction.component.html - 483,486 + 477,480 src/app/components/transaction/transaction.component.html - 494,496 + 488,490 src/app/components/transactions-list/transactions-list.component.html - 286 + 286,287 src/app/dashboard/dashboard.component.html @@ -2301,7 +2313,7 @@ src/app/dashboard/dashboard.component.html - 206,210 + 213,217 sat/vB shared.sat-vbyte @@ -2315,11 +2327,11 @@ src/app/components/transaction/transaction.component.html - 160,162 + 154,156 src/app/components/transaction/transaction.component.html - 274,277 + 268,271 Transaction Virtual Size transaction.vsize @@ -2335,7 +2347,7 @@ Match - Treffer + Übereinstimmung src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 38 @@ -2366,7 +2378,7 @@ Recently broadcasted - Jüngst ausgestrahlt + Kürzlich gesendet src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 41 @@ -2432,7 +2444,7 @@ src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 60 + 65 src/app/components/graphs/graphs.component.html @@ -2462,11 +2474,11 @@ Größe src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 180,179 + 184,183 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 226,224 + 239,237 src/app/components/block/block.component.html @@ -2494,7 +2506,7 @@ src/app/components/transaction/transaction.component.html - 270,272 + 264,266 src/app/dashboard/dashboard.component.html @@ -2506,11 +2518,11 @@ Gewicht src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 188,187 + 192,191 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 257,254 + 270,267 src/app/components/block/block-preview.component.html @@ -2522,7 +2534,19 @@ src/app/components/transaction/transaction.component.html - 278,280 + 272,274 + + + + Size per weight + Grösse nach Gewicht + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 200,199 + + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 282,279 @@ -2538,15 +2562,6 @@ shared.block-title - - - - - src/app/components/block/block-preview.component.html - 11,12 - - shared.block-title - Median fee Mediangebühr @@ -2556,7 +2571,7 @@ src/app/components/block/block.component.html - 126,127 + 127,128 src/app/components/mempool-block/mempool-block.component.html @@ -2573,11 +2588,11 @@ src/app/components/block/block.component.html - 131,133 + 138,140 src/app/components/block/block.component.html - 157,160 + 164,167 src/app/components/mempool-block/mempool-block.component.html @@ -2595,7 +2610,7 @@ src/app/components/block/block.component.html - 166,168 + 173,175 block.miner @@ -2608,7 +2623,7 @@ src/app/components/block/block.component.ts - 234 + 242 @@ -2661,6 +2676,14 @@ src/app/components/blocks-list/blocks-list.component.html 60,63 + + src/app/components/pool-ranking/pool-ranking.component.html + 121,124 + + + src/app/lightning/channel/closing-type/closing-type.component.ts + 32 + src/app/lightning/node/node.component.html 52,55 @@ -2684,7 +2707,7 @@ Gebührenspanne src/app/components/block/block.component.html - 122,123 + 123,124 src/app/components/mempool-block/mempool-block.component.html @@ -2697,7 +2720,7 @@ Basierend auf einer durchschnittlichen nativen Segwit-Transaktion von 140 vByte src/app/components/block/block.component.html - 127,129 + 131,136 src/app/components/fees-box/fees-box.component.html @@ -2721,16 +2744,16 @@ Transaction fee tooltip - - Subsidy + fees: - Subvention + Gebühr + + Subsidy + fees + Subvention + Gebühren src/app/components/block/block.component.html - 146,149 + 153,156 src/app/components/block/block.component.html - 161,165 + 168,172 Total subsidy and fees in a block block.subsidy-and-fees @@ -2740,7 +2763,7 @@ Erwartet src/app/components/block/block.component.html - 209 + 216 block.expected @@ -2749,11 +2772,11 @@ beta src/app/components/block/block.component.html - 209,210 + 216,217 src/app/components/block/block.component.html - 215,217 + 222,224 beta @@ -2762,7 +2785,7 @@ Tatsächlich src/app/components/block/block.component.html - 211,215 + 218,222 block.actual @@ -2771,7 +2794,7 @@ Erwarteter Block src/app/components/block/block.component.html - 215 + 222 block.expected-block @@ -2780,7 +2803,7 @@ Tatsächlicher Block src/app/components/block/block.component.html - 224 + 231 block.actual-block @@ -2789,7 +2812,7 @@ Bits src/app/components/block/block.component.html - 249,251 + 256,258 block.bits @@ -2798,7 +2821,7 @@ Merkle root src/app/components/block/block.component.html - 253,255 + 260,262 block.merkle-root @@ -2807,7 +2830,7 @@ Schwierigkeit src/app/components/block/block.component.html - 264,267 + 271,274 src/app/components/difficulty-adjustments-table/difficulty-adjustments-table.component.html @@ -2836,7 +2859,7 @@ Nonce src/app/components/block/block.component.html - 268,270 + 275,277 block.nonce @@ -2845,7 +2868,7 @@ Block-Header Hex src/app/components/block/block.component.html - 272,273 + 279,280 block.header @@ -2854,7 +2877,7 @@ Prüfung src/app/components/block/block.component.html - 290,294 + 297,301 Toggle Audit block.toggle-audit @@ -2864,11 +2887,11 @@ Details src/app/components/block/block.component.html - 297,301 + 304,308 src/app/components/transaction/transaction.component.html - 254,259 + 248,253 src/app/lightning/channel/channel.component.html @@ -2890,11 +2913,11 @@ Fehler beim Laden der Daten. src/app/components/block/block.component.html - 316,318 + 323,325 src/app/components/block/block.component.html - 355,359 + 362,366 src/app/lightning/channel/channel-preview.component.html @@ -2919,7 +2942,7 @@ Weshalb dieser leere Block? src/app/components/block/block.component.html - 377,383 + 384,390 block.empty-block-explanation @@ -3028,7 +3051,7 @@ src/app/dashboard/dashboard.component.html - 212,216 + 219,223 dashboard.txs @@ -3267,7 +3290,7 @@ src/app/dashboard/dashboard.component.html - 239,240 + 246,247 dashboard.incoming-transactions @@ -3280,7 +3303,7 @@ src/app/dashboard/dashboard.component.html - 242,245 + 249,252 dashboard.backend-is-synchronizing @@ -3293,7 +3316,7 @@ src/app/dashboard/dashboard.component.html - 247,252 + 254,259 vB/s shared.vbytes-per-second @@ -3307,7 +3330,7 @@ src/app/dashboard/dashboard.component.html - 210,211 + 217,218 Unconfirmed count dashboard.unconfirmed @@ -3683,6 +3706,32 @@ dashboard.adjustments + + Broadcast Transaction + Transaktion senden + + src/app/components/mining-dashboard/mining-dashboard.component.html + 92 + + + src/app/components/push-transaction/push-transaction.component.html + 2 + + + src/app/components/push-transaction/push-transaction.component.html + 8 + + + src/app/dashboard/dashboard.component.html + 161,169 + + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 102 + + Broadcast Transaction + shared.broadcast-transaction + Pools luck (1 week) Poolglück (1 Woche) @@ -3750,7 +3799,7 @@ src/app/components/pool-ranking/pool-ranking.component.html - 136,138 + 152,154 master-page.blocks @@ -3780,12 +3829,25 @@ mining.rank + + Avg Health + Durchschn. Gesundheit + + src/app/components/pool-ranking/pool-ranking.component.html + 96,97 + + + src/app/components/pool-ranking/pool-ranking.component.html + 96,98 + + latest-blocks.avg_health + Empty blocks Leere Blöcke src/app/components/pool-ranking/pool-ranking.component.html - 95,98 + 97,100 mining.empty-blocks @@ -3794,7 +3856,7 @@ Alle Miner src/app/components/pool-ranking/pool-ranking.component.html - 113,114 + 129,130 mining.all-miners @@ -3803,7 +3865,7 @@ Pools Glück (1w) src/app/components/pool-ranking/pool-ranking.component.html - 130,132 + 146,148 mining.miners-luck @@ -3812,7 +3874,7 @@ Anzahl der Pools (1w) src/app/components/pool-ranking/pool-ranking.component.html - 142,144 + 158,160 mining.miners-count @@ -3821,7 +3883,7 @@ Mining Pools src/app/components/pool-ranking/pool-ranking.component.ts - 57 + 58 @@ -4048,24 +4110,6 @@ latest-blocks.coinbasetag - - Broadcast Transaction - Transaktion senden - - src/app/components/push-transaction/push-transaction.component.html - 2 - - - src/app/components/push-transaction/push-transaction.component.html - 8 - - - src/app/dashboard/dashboard.component.html - 154,162 - - Broadcast Transaction - shared.broadcast-transaction - Transaction hex Transaktion hex @@ -4075,7 +4119,7 @@ src/app/components/transaction/transaction.component.html - 296,297 + 290,291 transaction.hex @@ -4200,6 +4244,78 @@ search-form.search-title + + Bitcoin Block Height + Bitcoin Blockhöhe + + src/app/components/search-form/search-results/search-results.component.html + 3 + + search.bitcoin-block-height + + + Bitcoin Transaction + Bitcoin Transaktion + + src/app/components/search-form/search-results/search-results.component.html + 9 + + search.bitcoin-transaction + + + Bitcoin Address + Bitcoin Adresse + + src/app/components/search-form/search-results/search-results.component.html + 15 + + search.bitcoin-address + + + Bitcoin Block + Bitcoin Block + + src/app/components/search-form/search-results/search-results.component.html + 21 + + search.bitcoin-block + + + Bitcoin Addresses + Bitcoin Adressen + + src/app/components/search-form/search-results/search-results.component.html + 27 + + search.bitcoin-addresses + + + Lightning Nodes + Lightning Nodes + + src/app/components/search-form/search-results/search-results.component.html + 35 + + search.lightning-nodes + + + Lightning Channels + Lightning Kanäle + + src/app/components/search-form/search-results/search-results.component.html + 43 + + search.lightning-channels + + + Go to "" + Gehe zu &quot;&quot; + + src/app/components/search-form/search-results/search-results.component.html + 52 + + search.go-to + Mempool by vBytes (sat/vByte) Mempool in vBytes (sat/vByte) @@ -4484,7 +4600,7 @@ src/app/components/transactions-list/transactions-list.component.html - 298,301 + 300,303 Transaction unconfirmed state transaction.unconfirmed @@ -4494,7 +4610,7 @@ Zuerst gesehen src/app/components/transaction/transaction.component.html - 108,109 + 102,103 src/app/lightning/node/node.component.html @@ -4528,7 +4644,7 @@ Vorauss. Zeit bis Schürfung src/app/components/transaction/transaction.component.html - 115,116 + 109,110 Transaction ETA transaction.eta @@ -4538,7 +4654,7 @@ In mehreren Stunden (oder mehr) src/app/components/transaction/transaction.component.html - 121,124 + 115,118 Transaction ETA in several hours or more transaction.eta.in-several-hours @@ -4548,11 +4664,11 @@ Nachfahre src/app/components/transaction/transaction.component.html - 168,170 + 162,164 src/app/components/transaction/transaction.component.html - 179,181 + 173,175 Descendant transaction.descendant @@ -4562,7 +4678,7 @@ Vorfahr src/app/components/transaction/transaction.component.html - 190,192 + 184,186 Transaction Ancestor transaction.ancestor @@ -4572,11 +4688,11 @@ Fluss src/app/components/transaction/transaction.component.html - 208,211 + 202,205 src/app/components/transaction/transaction.component.html - 346,350 + 340,344 Transaction flow transaction.flow @@ -4586,7 +4702,7 @@ Diagramm ausblenden src/app/components/transaction/transaction.component.html - 211,216 + 205,210 hide-diagram @@ -4595,7 +4711,7 @@ Mehr anzeigen src/app/components/transaction/transaction.component.html - 231,233 + 225,227 src/app/components/transactions-list/transactions-list.component.html @@ -4612,7 +4728,7 @@ Weniger anzeigen src/app/components/transaction/transaction.component.html - 233,239 + 227,233 src/app/components/transactions-list/transactions-list.component.html @@ -4625,7 +4741,7 @@ Diagramm anzeigen src/app/components/transaction/transaction.component.html - 253,254 + 247,248 show-diagram @@ -4634,7 +4750,7 @@ Sperrzeit src/app/components/transaction/transaction.component.html - 292,294 + 286,288 transaction.locktime @@ -4643,7 +4759,7 @@ Transaktion nicht gefunden. src/app/components/transaction/transaction.component.html - 455,456 + 449,450 transaction.error.transaction-not-found @@ -4652,7 +4768,7 @@ Warten bis sie im Mempool erscheint... src/app/components/transaction/transaction.component.html - 456,461 + 450,455 transaction.error.waiting-for-it-to-appear @@ -4661,7 +4777,7 @@ Effektiver Gebührensatz src/app/components/transaction/transaction.component.html - 491,494 + 485,488 Effective transaction fee rate transaction.effective-fee-rate @@ -4810,7 +4926,7 @@ Mehr Inputs anzeigen, um Gebührendaten anzuzeigen src/app/components/transactions-list/transactions-list.component.html - 288,291 + 290,293 transactions-list.load-to-reveal-fee-info @@ -4819,7 +4935,7 @@ verbleiben src/app/components/transactions-list/transactions-list.component.html - 330,331 + 332,333 x-remaining @@ -5070,21 +5186,12 @@ dashboard.latest-transactions - - USD - USD - - src/app/dashboard/dashboard.component.html - 126,127 - - dashboard.latest-transactions.USD - Minimum fee Mindestgebühr src/app/dashboard/dashboard.component.html - 203,204 + 210,211 Minimum mempool fee dashboard.minimum-fee @@ -5094,7 +5201,7 @@ Streichung src/app/dashboard/dashboard.component.html - 204,205 + 211,212 Purgin below fee dashboard.purging @@ -5104,7 +5211,7 @@ Speichernutzung src/app/dashboard/dashboard.component.html - 216,217 + 223,224 Memory usage dashboard.memory-usage @@ -5114,10 +5221,19 @@ L-BTC im Umlauf src/app/dashboard/dashboard.component.html - 230,232 + 237,239 dashboard.lbtc-pegs-in-circulation + + mempool.space merely provides data about the Bitcoin network. It cannot help you with retrieving funds, confirming your transaction quicker, etc. + mempool.space liefert lediglich Daten zum Bitcoin Netzwerk. Es kann dir nicht helfen beim Geld holen, Transaktionbestätigung beschleunigen etc. + + src/app/docs/api-docs/api-docs.component.html + 13 + + faq.big-disclaimer + REST API service REST-API-Dienst @@ -5452,7 +5568,7 @@ src/app/lightning/node-statistics/node-statistics.component.html - 47,50 + 46,49 src/app/lightning/nodes-list/nodes-list.component.html @@ -5599,6 +5715,30 @@ 37 + + Mutually closed + Gegenseitig geschlossen + + src/app/lightning/channel/closing-type/closing-type.component.ts + 20 + + + + Force closed + Zwangsgeschlossen + + src/app/lightning/channel/closing-type/closing-type.component.ts + 24 + + + + Force closed with penalty + Zwangsgeschlossen mit Strafzahlung + + src/app/lightning/channel/closing-type/closing-type.component.ts + 28 + + Open Offen @@ -5725,6 +5865,24 @@ shared.sats + + avg + durchschn. + + src/app/lightning/channels-statistics/channels-statistics.component.html + 3,5 + + statistics.average-small + + + med + mittel + + src/app/lightning/channels-statistics/channels-statistics.component.html + 6,9 + + statistics.median-small + Avg Capacity Durchschnittskapazität @@ -5853,11 +6011,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 17,18 + 16,17 src/app/lightning/node-statistics/node-statistics.component.html - 54,57 + 53,56 src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html @@ -5927,11 +6085,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 29,30 + 28,29 src/app/lightning/node-statistics/node-statistics.component.html - 61,64 + 60,63 src/app/lightning/nodes-list/nodes-list.component.html @@ -6095,6 +6253,30 @@ lightning.node-fee-distribution + + Outgoing Fees + Ausgehende Gebühren + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 170 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 208 + + + + Incoming Fees + Einkommende Gebühren + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 178 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 222 + + Percentage change past week Prozentuale Änderung letzte Woche @@ -6104,11 +6286,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 18,20 + 17,19 src/app/lightning/node-statistics/node-statistics.component.html - 30,32 + 29,31 mining.percentage-change-last-week @@ -6356,7 +6538,7 @@ Keine Geolokationsdaten verfügbar src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts - 218,213 + 219,214 diff --git a/frontend/src/locale/messages.fa.xlf b/frontend/src/locale/messages.fa.xlf index 2fac31501..38a471409 100644 --- a/frontend/src/locale/messages.fa.xlf +++ b/frontend/src/locale/messages.fa.xlf @@ -359,11 +359,11 @@ src/app/components/block/block.component.html - 303,304 + 310,311 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 26,27 + 46,47 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -384,11 +384,11 @@ src/app/components/block/block.component.html - 304,305 + 311,312 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 27,28 + 47,48 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -598,7 +598,7 @@ src/app/components/pool-ranking/pool-ranking.component.html - 94,96 + 94,95 @@ -777,14 +777,22 @@ src/app/components/about/about.component.html 385,389 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 88 + src/app/dashboard/dashboard.component.html - 150,152 + 157,159 src/app/docs/docs/docs.component.html 51 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 97 + Terms of Service shared.terms-of-service @@ -795,14 +803,22 @@ src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html 113,120 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 90 + src/app/dashboard/dashboard.component.html - 152,154 + 159,161 src/app/docs/docs/docs.component.html 53 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 99 + Privacy Policy shared.privacy-policy @@ -990,7 +1006,7 @@ src/app/dashboard/dashboard.component.html - 124,125 + 124,126 @@ -1038,7 +1054,7 @@ src/app/components/transaction/transaction.component.html - 158,160 + 152,154 src/app/components/transactions-list/transactions-list.component.html @@ -1054,11 +1070,11 @@ src/app/components/block/block.component.html - 245,246 + 252,253 src/app/components/transaction/transaction.component.html - 288,290 + 282,284 transaction.version @@ -1108,7 +1124,7 @@ src/app/components/transactions-list/transactions-list.component.html - 294,295 + 296,297 Transaction singular confirmation count shared.confirmation-count.singular @@ -1130,7 +1146,7 @@ src/app/components/transactions-list/transactions-list.component.html - 295,296 + 297,298 Transaction plural confirmation count shared.confirmation-count.plural @@ -1142,10 +1158,6 @@ src/app/bisq/bisq-transaction/bisq-transaction.component.html 43,45 - - src/app/components/transaction/transaction.component.html - 65,67 - Transaction included in block transaction.included-in-block @@ -1158,11 +1170,11 @@ src/app/components/transaction/transaction.component.html - 77,80 + 71,74 src/app/components/transaction/transaction.component.html - 135,138 + 129,132 Transaction features transaction.features @@ -1190,11 +1202,11 @@ src/app/components/transaction/transaction.component.html - 262,267 + 256,261 src/app/components/transaction/transaction.component.html - 406,412 + 400,406 transaction.details @@ -1211,11 +1223,11 @@ src/app/components/transaction/transaction.component.html - 249,253 + 243,247 src/app/components/transaction/transaction.component.html - 377,383 + 371,377 Transaction inputs and outputs transaction.inputs-and-outputs @@ -1233,7 +1245,7 @@ src/app/components/transaction/transaction.component.ts - 241,240 + 244,243 @@ -1253,7 +1265,7 @@ src/app/components/transaction/transaction.component.html - 159,160 + 153,154 src/app/dashboard/dashboard.component.html @@ -1269,7 +1281,7 @@ src/app/components/transaction/transaction.component.html - 72,73 + 66,67 Transaction Confirmed state transaction.confirmed @@ -1569,7 +1581,7 @@ src/app/components/amount/amount.component.html - 6,9 + 18,21 src/app/components/asset-circulation/asset-circulation.component.html @@ -1585,7 +1597,7 @@ src/app/components/transactions-list/transactions-list.component.html - 302,304 + 304,306 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -2049,7 +2061,7 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 161 + 165 @@ -2065,7 +2077,7 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 163 + 167 @@ -2077,7 +2089,7 @@ src/app/components/block-fees-graph/block-fees-graph.component.ts - 62 + 67 src/app/components/graphs/graphs.component.html @@ -2090,15 +2102,15 @@ فهرست‌بندی بلاک‌ها src/app/components/block-fees-graph/block-fees-graph.component.ts - 110,105 + 116,111 src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 108,103 + 113,108 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 115,110 + 116,111 src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -2143,7 +2155,7 @@ src/app/components/transaction/transaction.component.html - 478 + 472 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -2169,11 +2181,11 @@ src/app/components/transaction/transaction.component.html - 478,479 + 472 src/app/components/transactions-list/transactions-list.component.html - 286,287 + 288 sat shared.sat @@ -2187,11 +2199,11 @@ src/app/components/transaction/transaction.component.html - 161,165 + 155,159 src/app/components/transaction/transaction.component.html - 481,483 + 475,477 src/app/lightning/channel/channel-box/channel-box.component.html @@ -2221,19 +2233,19 @@ src/app/components/block/block.component.html - 123,126 + 124,127 src/app/components/block/block.component.html - 127 + 128,130 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 12,14 + 19,22 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 15,17 + 30,33 src/app/components/fees-box/fees-box.component.html @@ -2273,27 +2285,27 @@ src/app/components/transaction/transaction.component.html - 173,174 + 167,168 src/app/components/transaction/transaction.component.html - 184,185 + 178,179 src/app/components/transaction/transaction.component.html - 195,196 + 189,190 src/app/components/transaction/transaction.component.html - 483,486 + 477,480 src/app/components/transaction/transaction.component.html - 494,496 + 488,490 src/app/components/transactions-list/transactions-list.component.html - 286 + 286,287 src/app/dashboard/dashboard.component.html @@ -2301,7 +2313,7 @@ src/app/dashboard/dashboard.component.html - 206,210 + 213,217 sat/vB shared.sat-vbyte @@ -2315,18 +2327,18 @@ src/app/components/transaction/transaction.component.html - 160,162 + 154,156 src/app/components/transaction/transaction.component.html - 274,277 + 268,271 Transaction Virtual Size transaction.vsize Audit status - وضعیت رسیدگی + وضعیت بررسی src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 36 @@ -2335,7 +2347,7 @@ Match - مطابق + همتا src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 38 @@ -2417,7 +2429,7 @@ Match rate - نرخ برابری + نرخ همتایی src/app/components/block-prediction-graph/block-prediction-graph.component.ts 189,187 @@ -2432,7 +2444,7 @@ src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 60 + 65 src/app/components/graphs/graphs.component.html @@ -2462,11 +2474,11 @@ اندازه src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 180,179 + 184,183 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 226,224 + 239,237 src/app/components/block/block.component.html @@ -2494,7 +2506,7 @@ src/app/components/transaction/transaction.component.html - 270,272 + 264,266 src/app/dashboard/dashboard.component.html @@ -2506,11 +2518,11 @@ وزن src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 188,187 + 192,191 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 257,254 + 270,267 src/app/components/block/block-preview.component.html @@ -2522,7 +2534,19 @@ src/app/components/transaction/transaction.component.html - 278,280 + 272,274 + + + + Size per weight + اندازه بر وزن + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 200,199 + + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 282,279 @@ -2538,15 +2562,6 @@ shared.block-title - - - - - src/app/components/block/block-preview.component.html - 11,12 - - shared.block-title - Median fee کارمزد میانه @@ -2556,7 +2571,7 @@ src/app/components/block/block.component.html - 126,127 + 127,128 src/app/components/mempool-block/mempool-block.component.html @@ -2573,11 +2588,11 @@ src/app/components/block/block.component.html - 131,133 + 138,140 src/app/components/block/block.component.html - 157,160 + 164,167 src/app/components/mempool-block/mempool-block.component.html @@ -2595,7 +2610,7 @@ src/app/components/block/block.component.html - 166,168 + 173,175 block.miner @@ -2608,7 +2623,7 @@ src/app/components/block/block.component.ts - 234 + 242 @@ -2661,6 +2676,14 @@ src/app/components/blocks-list/blocks-list.component.html 60,63 + + src/app/components/pool-ranking/pool-ranking.component.html + 121,124 + + + src/app/lightning/channel/closing-type/closing-type.component.ts + 32 + src/app/lightning/node/node.component.html 52,55 @@ -2684,7 +2707,7 @@ بازه‌ی کارمزد src/app/components/block/block.component.html - 122,123 + 123,124 src/app/components/mempool-block/mempool-block.component.html @@ -2697,7 +2720,7 @@ بر اساس میانگین تراکنش سگویتی اصیل با اندازه 140 ساتوشی بر بایت مجازی src/app/components/block/block.component.html - 127,129 + 131,136 src/app/components/fees-box/fees-box.component.html @@ -2721,25 +2744,26 @@ Transaction fee tooltip - - Subsidy + fees: - یارانه بلاک + کارمزدها + + Subsidy + fees + یارانه + کارمزدها src/app/components/block/block.component.html - 146,149 + 153,156 src/app/components/block/block.component.html - 161,165 + 168,172 Total subsidy and fees in a block block.subsidy-and-fees Expected + پیش‌بینی شده src/app/components/block/block.component.html - 209 + 216 block.expected @@ -2748,11 +2772,11 @@ آزمایشی src/app/components/block/block.component.html - 209,210 + 216,217 src/app/components/block/block.component.html - 215,217 + 222,224 beta @@ -2761,23 +2785,25 @@ واقعی src/app/components/block/block.component.html - 211,215 + 218,222 block.actual Expected Block + بلاک پیش‌بینی شده src/app/components/block/block.component.html - 215 + 222 block.expected-block Actual Block + بلاک واقعی src/app/components/block/block.component.html - 224 + 231 block.actual-block @@ -2786,7 +2812,7 @@ بیت src/app/components/block/block.component.html - 249,251 + 256,258 block.bits @@ -2795,7 +2821,7 @@ ریشه درخت مرکل src/app/components/block/block.component.html - 253,255 + 260,262 block.merkle-root @@ -2804,7 +2830,7 @@ سختی شبکه src/app/components/block/block.component.html - 264,267 + 271,274 src/app/components/difficulty-adjustments-table/difficulty-adjustments-table.component.html @@ -2833,7 +2859,7 @@ نانس src/app/components/block/block.component.html - 268,270 + 275,277 block.nonce @@ -2842,16 +2868,16 @@ سربرگ بلاک به صورت Hex src/app/components/block/block.component.html - 272,273 + 279,280 block.header Audit - رسیدگی + بررسی src/app/components/block/block.component.html - 290,294 + 297,301 Toggle Audit block.toggle-audit @@ -2861,11 +2887,11 @@ جزئیات src/app/components/block/block.component.html - 297,301 + 304,308 src/app/components/transaction/transaction.component.html - 254,259 + 248,253 src/app/lightning/channel/channel.component.html @@ -2887,11 +2913,11 @@ خطا در بارگذاری داده‌ها. src/app/components/block/block.component.html - 316,318 + 323,325 src/app/components/block/block.component.html - 355,359 + 362,366 src/app/lightning/channel/channel-preview.component.html @@ -2916,7 +2942,7 @@ چرا این بلاک خالی است؟ src/app/components/block/block.component.html - 377,383 + 384,390 block.empty-block-explanation @@ -3025,7 +3051,7 @@ src/app/dashboard/dashboard.component.html - 212,216 + 219,223 dashboard.txs @@ -3264,7 +3290,7 @@ src/app/dashboard/dashboard.component.html - 239,240 + 246,247 dashboard.incoming-transactions @@ -3277,7 +3303,7 @@ src/app/dashboard/dashboard.component.html - 242,245 + 249,252 dashboard.backend-is-synchronizing @@ -3290,7 +3316,7 @@ src/app/dashboard/dashboard.component.html - 247,252 + 254,259 vB/s shared.vbytes-per-second @@ -3304,7 +3330,7 @@ src/app/dashboard/dashboard.component.html - 210,211 + 217,218 Unconfirmed count dashboard.unconfirmed @@ -3554,7 +3580,7 @@ Graphs - گراف‌ها + نمودارها src/app/components/liquid-master-page/liquid-master-page.component.html 71,74 @@ -3680,6 +3706,32 @@ dashboard.adjustments + + Broadcast Transaction + انتشار تراکنش + + src/app/components/mining-dashboard/mining-dashboard.component.html + 92 + + + src/app/components/push-transaction/push-transaction.component.html + 2 + + + src/app/components/push-transaction/push-transaction.component.html + 8 + + + src/app/dashboard/dashboard.component.html + 161,169 + + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 102 + + Broadcast Transaction + shared.broadcast-transaction + Pools luck (1 week) شانس استخرها (1 هفته‌ای) @@ -3747,7 +3799,7 @@ src/app/components/pool-ranking/pool-ranking.component.html - 136,138 + 152,154 master-page.blocks @@ -3777,12 +3829,25 @@ mining.rank + + Avg Health + متوسط سلامت + + src/app/components/pool-ranking/pool-ranking.component.html + 96,97 + + + src/app/components/pool-ranking/pool-ranking.component.html + 96,98 + + latest-blocks.avg_health + Empty blocks بلاک‌های خالی src/app/components/pool-ranking/pool-ranking.component.html - 95,98 + 97,100 mining.empty-blocks @@ -3791,7 +3856,7 @@ همه ماینرها src/app/components/pool-ranking/pool-ranking.component.html - 113,114 + 129,130 mining.all-miners @@ -3800,7 +3865,7 @@ شانس استخرها (1 هفته) src/app/components/pool-ranking/pool-ranking.component.html - 130,132 + 146,148 mining.miners-luck @@ -3809,7 +3874,7 @@ تعداد استخرها (1 هفته) src/app/components/pool-ranking/pool-ranking.component.html - 142,144 + 158,160 mining.miners-count @@ -3818,7 +3883,7 @@ استخرهای استخراج src/app/components/pool-ranking/pool-ranking.component.ts - 57 + 58 @@ -4045,24 +4110,6 @@ latest-blocks.coinbasetag - - Broadcast Transaction - انتشار تراکنش - - src/app/components/push-transaction/push-transaction.component.html - 2 - - - src/app/components/push-transaction/push-transaction.component.html - 8 - - - src/app/dashboard/dashboard.component.html - 154,162 - - Broadcast Transaction - shared.broadcast-transaction - Transaction hex تراکنش به صورت Hex @@ -4072,7 +4119,7 @@ src/app/components/transaction/transaction.component.html - 296,297 + 290,291 transaction.hex @@ -4197,6 +4244,78 @@ search-form.search-title + + Bitcoin Block Height + طول بلاک بیت‌کوین + + src/app/components/search-form/search-results/search-results.component.html + 3 + + search.bitcoin-block-height + + + Bitcoin Transaction + تراکنش بیت‌کوین + + src/app/components/search-form/search-results/search-results.component.html + 9 + + search.bitcoin-transaction + + + Bitcoin Address + آدرس بیت‌کوین + + src/app/components/search-form/search-results/search-results.component.html + 15 + + search.bitcoin-address + + + Bitcoin Block + بلاک بیت‌کوین + + src/app/components/search-form/search-results/search-results.component.html + 21 + + search.bitcoin-block + + + Bitcoin Addresses + آدرس بیت‌کوین + + src/app/components/search-form/search-results/search-results.component.html + 27 + + search.bitcoin-addresses + + + Lightning Nodes + گره لایتنینگ + + src/app/components/search-form/search-results/search-results.component.html + 35 + + search.lightning-nodes + + + Lightning Channels + کانال لایتنینگ + + src/app/components/search-form/search-results/search-results.component.html + 43 + + search.lightning-channels + + + Go to "" + برو به &quot;&quot; + + src/app/components/search-form/search-results/search-results.component.html + 52 + + search.go-to + Mempool by vBytes (sat/vByte) وضعیت ممپول به vByte (ساتوشی بر vByte) @@ -4481,7 +4600,7 @@ src/app/components/transactions-list/transactions-list.component.html - 298,301 + 300,303 Transaction unconfirmed state transaction.unconfirmed @@ -4491,7 +4610,7 @@ اولین زمان دیده‌شدن src/app/components/transaction/transaction.component.html - 108,109 + 102,103 src/app/lightning/node/node.component.html @@ -4525,7 +4644,7 @@ تخمین src/app/components/transaction/transaction.component.html - 115,116 + 109,110 Transaction ETA transaction.eta @@ -4535,7 +4654,7 @@ در چند (یا چندین) ساعت آینده src/app/components/transaction/transaction.component.html - 121,124 + 115,118 Transaction ETA in several hours or more transaction.eta.in-several-hours @@ -4545,11 +4664,11 @@ نواده src/app/components/transaction/transaction.component.html - 168,170 + 162,164 src/app/components/transaction/transaction.component.html - 179,181 + 173,175 Descendant transaction.descendant @@ -4559,7 +4678,7 @@ والد src/app/components/transaction/transaction.component.html - 190,192 + 184,186 Transaction Ancestor transaction.ancestor @@ -4569,11 +4688,11 @@ جریان src/app/components/transaction/transaction.component.html - 208,211 + 202,205 src/app/components/transaction/transaction.component.html - 346,350 + 340,344 Transaction flow transaction.flow @@ -4583,7 +4702,7 @@ پنهان‌کردن نمودار src/app/components/transaction/transaction.component.html - 211,216 + 205,210 hide-diagram @@ -4592,7 +4711,7 @@ بیشتر src/app/components/transaction/transaction.component.html - 231,233 + 225,227 src/app/components/transactions-list/transactions-list.component.html @@ -4609,7 +4728,7 @@ کمتر src/app/components/transaction/transaction.component.html - 233,239 + 227,233 src/app/components/transactions-list/transactions-list.component.html @@ -4622,7 +4741,7 @@ نمایش نمودار src/app/components/transaction/transaction.component.html - 253,254 + 247,248 show-diagram @@ -4631,7 +4750,7 @@ قفل‌زمانی src/app/components/transaction/transaction.component.html - 292,294 + 286,288 transaction.locktime @@ -4640,7 +4759,7 @@ تراکنش پیدا نشد. src/app/components/transaction/transaction.component.html - 455,456 + 449,450 transaction.error.transaction-not-found @@ -4649,7 +4768,7 @@ منتظر دیده‌شدن در mempool... src/app/components/transaction/transaction.component.html - 456,461 + 450,455 transaction.error.waiting-for-it-to-appear @@ -4658,7 +4777,7 @@ نرخ کارمزد مؤثر src/app/components/transaction/transaction.component.html - 491,494 + 485,488 Effective transaction fee rate transaction.effective-fee-rate @@ -4807,7 +4926,7 @@ نمایش ورودی‌های بیشتر برای افشای داده‌های کارمزد src/app/components/transactions-list/transactions-list.component.html - 288,291 + 290,293 transactions-list.load-to-reveal-fee-info @@ -4816,7 +4935,7 @@ عدد باقی مانده است src/app/components/transactions-list/transactions-list.component.html - 330,331 + 332,333 x-remaining @@ -5067,21 +5186,12 @@ dashboard.latest-transactions - - USD - USD - - src/app/dashboard/dashboard.component.html - 126,127 - - dashboard.latest-transactions.USD - Minimum fee حداقل کارمزد src/app/dashboard/dashboard.component.html - 203,204 + 210,211 Minimum mempool fee dashboard.minimum-fee @@ -5091,7 +5201,7 @@ آستانه حذف src/app/dashboard/dashboard.component.html - 204,205 + 211,212 Purgin below fee dashboard.purging @@ -5101,7 +5211,7 @@ حافظه مصرف‌شده src/app/dashboard/dashboard.component.html - 216,217 + 223,224 Memory usage dashboard.memory-usage @@ -5111,10 +5221,19 @@ مقدار L-BTC در گردش src/app/dashboard/dashboard.component.html - 230,232 + 237,239 dashboard.lbtc-pegs-in-circulation + + mempool.space merely provides data about the Bitcoin network. It cannot help you with retrieving funds, confirming your transaction quicker, etc. + ممپول صرفا داده‌هایی درباره شبکه بیت‌کوین ارائه می‌کند. نمی‌توانید از آن برای دریافت وجه، سریع‌ کردن تأیید شدن تراکنش‌هایتان یا چنین کارهایی استفاده کنید. + + src/app/docs/api-docs/api-docs.component.html + 13 + + faq.big-disclaimer + REST API service خدمات REST API @@ -5449,7 +5568,7 @@ src/app/lightning/node-statistics/node-statistics.component.html - 47,50 + 46,49 src/app/lightning/nodes-list/nodes-list.component.html @@ -5596,6 +5715,30 @@ 37 + + Mutually closed + بسته‌شده با همکاری + + src/app/lightning/channel/closing-type/closing-type.component.ts + 20 + + + + Force closed + بسته‌شده بدون همکاری + + src/app/lightning/channel/closing-type/closing-type.component.ts + 24 + + + + Force closed with penalty + بسته‌شده بدون همکاری با جریمه + + src/app/lightning/channel/closing-type/closing-type.component.ts + 28 + + Open باز @@ -5722,6 +5865,24 @@ shared.sats + + avg + متوسط + + src/app/lightning/channels-statistics/channels-statistics.component.html + 3,5 + + statistics.average-small + + + med + میانه + + src/app/lightning/channels-statistics/channels-statistics.component.html + 6,9 + + statistics.median-small + Avg Capacity متوسط ظرفیت @@ -5850,11 +6011,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 17,18 + 16,17 src/app/lightning/node-statistics/node-statistics.component.html - 54,57 + 53,56 src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html @@ -5924,11 +6085,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 29,30 + 28,29 src/app/lightning/node-statistics/node-statistics.component.html - 61,64 + 60,63 src/app/lightning/nodes-list/nodes-list.component.html @@ -6092,6 +6253,30 @@ lightning.node-fee-distribution + + Outgoing Fees + کارمزدهای خروجی + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 170 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 208 + + + + Incoming Fees + کارمزدهای ورودی + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 178 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 222 + + Percentage change past week درصد تغییر هفته گذشته @@ -6101,11 +6286,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 18,20 + 17,19 src/app/lightning/node-statistics/node-statistics.component.html - 30,32 + 29,31 mining.percentage-change-last-week @@ -6353,7 +6538,7 @@ اطلاعات جغرافیایی در دسترس نیست src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts - 218,213 + 219,214 @@ -6531,7 +6716,7 @@ Tor Capacity - ظرفیت Tor + ‏ظرفیت Tor src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 20,22 diff --git a/frontend/src/locale/messages.hu.xlf b/frontend/src/locale/messages.hu.xlf index 979573d35..2cbb07923 100644 --- a/frontend/src/locale/messages.hu.xlf +++ b/frontend/src/locale/messages.hu.xlf @@ -11,6 +11,7 @@ Slide of + a oldal node_modules/src/carousel/carousel.ts 175,181 @@ -147,6 +148,7 @@ + node_modules/src/progressbar/progressbar.ts 30,33 @@ -357,11 +359,11 @@ src/app/components/block/block.component.html - 290,291 + 310,311 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 26,27 + 46,47 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -382,11 +384,11 @@ src/app/components/block/block.component.html - 291,292 + 311,312 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 27,28 + 47,48 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -424,7 +426,7 @@ src/app/components/block/block.component.html - 40,41 + 38,39 block.hash @@ -449,7 +451,7 @@ src/app/components/block/block.component.html - 44,46 + 42,44 src/app/components/blocks-list/blocks-list.component.html @@ -592,11 +594,11 @@ src/app/components/master-page/master-page.component.html - 49,51 + 48,50 src/app/components/pool-ranking/pool-ranking.component.html - 94,96 + 94,95 @@ -737,6 +739,7 @@ View more » + Továbbiak » src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html 92,97 @@ -774,14 +777,22 @@ src/app/components/about/about.component.html 385,389 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 88 + src/app/dashboard/dashboard.component.html - 150,152 + 157,159 src/app/docs/docs/docs.component.html 51 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 97 + Terms of Service shared.terms-of-service @@ -792,14 +803,22 @@ src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html 113,120 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 90 + src/app/dashboard/dashboard.component.html - 152,154 + 159,161 src/app/docs/docs/docs.component.html 53 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 99 + Privacy Policy shared.privacy-policy @@ -987,7 +1006,7 @@ src/app/dashboard/dashboard.component.html - 124,125 + 124,126 @@ -1035,7 +1054,7 @@ src/app/components/transaction/transaction.component.html - 158,160 + 152,154 src/app/components/transactions-list/transactions-list.component.html @@ -1051,11 +1070,11 @@ src/app/components/block/block.component.html - 246,247 + 252,253 src/app/components/transaction/transaction.component.html - 288,290 + 282,284 transaction.version @@ -1105,7 +1124,7 @@ src/app/components/transactions-list/transactions-list.component.html - 294,295 + 296,297 Transaction singular confirmation count shared.confirmation-count.singular @@ -1127,7 +1146,7 @@ src/app/components/transactions-list/transactions-list.component.html - 295,296 + 297,298 Transaction plural confirmation count shared.confirmation-count.plural @@ -1139,10 +1158,6 @@ src/app/bisq/bisq-transaction/bisq-transaction.component.html 43,45 - - src/app/components/transaction/transaction.component.html - 65,67 - Transaction included in block transaction.included-in-block @@ -1155,11 +1170,11 @@ src/app/components/transaction/transaction.component.html - 77,80 + 71,74 src/app/components/transaction/transaction.component.html - 135,138 + 129,132 Transaction features transaction.features @@ -1187,11 +1202,11 @@ src/app/components/transaction/transaction.component.html - 262,267 + 256,261 src/app/components/transaction/transaction.component.html - 406,412 + 400,406 transaction.details @@ -1208,11 +1223,11 @@ src/app/components/transaction/transaction.component.html - 249,253 + 243,247 src/app/components/transaction/transaction.component.html - 377,383 + 371,377 Transaction inputs and outputs transaction.inputs-and-outputs @@ -1230,7 +1245,7 @@ src/app/components/transaction/transaction.component.ts - 241,240 + 244,243 @@ -1250,7 +1265,7 @@ src/app/components/transaction/transaction.component.html - 159,160 + 153,154 src/app/dashboard/dashboard.component.html @@ -1266,7 +1281,7 @@ src/app/components/transaction/transaction.component.html - 72,73 + 66,67 Transaction Confirmed state transaction.confirmed @@ -1459,6 +1474,7 @@ Community Integrations + Közösségi Integrációk src/app/components/about/about.component.html 191,193 @@ -1527,11 +1543,12 @@ src/app/components/master-page/master-page.component.html - 58,61 + 57,60 Multisig of + a -ből/ból Multisig src/app/components/address-labels/address-labels.component.ts 107 @@ -1563,7 +1580,7 @@ src/app/components/amount/amount.component.html - 6,9 + 18,21 src/app/components/asset-circulation/asset-circulation.component.html @@ -1579,7 +1596,7 @@ src/app/components/transactions-list/transactions-list.component.html - 302,304 + 304,306 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -1605,6 +1622,7 @@ of transaction + a tranzakció src/app/components/address/address.component.html 59 @@ -1613,6 +1631,7 @@ of transactions + a tranzakciók src/app/components/address/address.component.html 60 @@ -1659,7 +1678,7 @@ src/app/components/assets/assets.component.html - 29,31 + 31,33 src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html @@ -1787,6 +1806,7 @@ Group of assets + Csoportnyi asset src/app/components/assets/asset-group/asset-group.component.html 8,9 @@ -1819,6 +1839,7 @@ Featured + Kiemelt src/app/components/assets/assets-nav/assets-nav.component.html 9 @@ -1879,7 +1900,7 @@ src/app/components/assets/assets.component.html - 30,31 + 32,33 Asset ticker header @@ -1892,7 +1913,7 @@ src/app/components/assets/assets.component.html - 31,34 + 33,36 Asset Issuer Domain header @@ -1905,7 +1926,7 @@ src/app/components/assets/assets.component.html - 32,36 + 34,38 Asset ID header @@ -1914,7 +1935,7 @@ Hiba történt az assetok adainak betöltésekor. src/app/components/assets/assets.component.html - 48,53 + 50,55 Asset data load error @@ -2010,6 +2031,7 @@ Block Fee Rates + Blokk Díj Ráta src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.html 6,8 @@ -2026,6 +2048,7 @@ At block: + Blokknál: src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts 188 @@ -2036,11 +2059,12 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 161 + 165 Around block: + blokk körül src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts 190 @@ -2051,18 +2075,19 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 163 + 167 Block Fees + Blokk Díjjak src/app/components/block-fees-graph/block-fees-graph.component.html 6,7 src/app/components/block-fees-graph/block-fees-graph.component.ts - 62 + 67 src/app/components/graphs/graphs.component.html @@ -2072,17 +2097,18 @@ Indexing blocks + Blokkok indexelése src/app/components/block-fees-graph/block-fees-graph.component.ts - 110,105 + 116,111 src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 108,103 + 113,108 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 115,110 + 116,111 src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -2107,6 +2133,7 @@ not available + nem elérhető src/app/components/block-overview-graph/block-overview-graph.component.html 5 @@ -2126,7 +2153,7 @@ src/app/components/transaction/transaction.component.html - 476 + 472 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -2152,11 +2179,11 @@ src/app/components/transaction/transaction.component.html - 476,477 + 472 src/app/components/transactions-list/transactions-list.component.html - 286,287 + 288 sat shared.sat @@ -2170,11 +2197,11 @@ src/app/components/transaction/transaction.component.html - 161,165 + 155,159 src/app/components/transaction/transaction.component.html - 479,481 + 475,477 src/app/lightning/channel/channel-box/channel-box.component.html @@ -2186,7 +2213,7 @@ src/app/lightning/channels-list/channels-list.component.html - 38,39 + 41,42 Transaction fee rate transaction.fee-rate @@ -2204,19 +2231,19 @@ src/app/components/block/block.component.html - 125,128 + 124,127 src/app/components/block/block.component.html - 129 + 128,130 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 12,14 + 19,22 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 15,17 + 30,33 src/app/components/fees-box/fees-box.component.html @@ -2256,27 +2283,27 @@ src/app/components/transaction/transaction.component.html - 173,174 + 167,168 src/app/components/transaction/transaction.component.html - 184,185 + 178,179 src/app/components/transaction/transaction.component.html - 195,196 + 189,190 src/app/components/transaction/transaction.component.html - 481,484 + 477,480 src/app/components/transaction/transaction.component.html - 492,494 + 488,490 src/app/components/transactions-list/transactions-list.component.html - 286 + 286,287 src/app/dashboard/dashboard.component.html @@ -2284,7 +2311,7 @@ src/app/dashboard/dashboard.component.html - 204,208 + 213,217 sat/vB shared.sat-vbyte @@ -2298,17 +2325,18 @@ src/app/components/transaction/transaction.component.html - 160,162 + 154,156 src/app/components/transaction/transaction.component.html - 274,277 + 268,271 Transaction Virtual Size transaction.vsize Audit status + Ellenőrzési állapot src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 36 @@ -2317,6 +2345,7 @@ Match + Találat src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 38 @@ -2325,6 +2354,7 @@ Removed + Eltávolítva src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 39 @@ -2333,6 +2363,7 @@ Marginal fee rate + Legkissebb díj ráta src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 40 @@ -2345,6 +2376,7 @@ Recently broadcasted + Nemrég közvetítve src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 41 @@ -2353,6 +2385,7 @@ Added + Hozzáadva src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 42 @@ -2361,6 +2394,7 @@ Block Prediction Accuracy + Blokk Előrejelzés Pontossága src/app/components/block-prediction-graph/block-prediction-graph.component.html 6,8 @@ -2377,6 +2411,7 @@ No data to display yet. Try again later. + Nincs megjeleníthető adat. Próbálkozz később. src/app/components/block-prediction-graph/block-prediction-graph.component.ts 108,103 @@ -2392,6 +2427,7 @@ Match rate + Találati ráta src/app/components/block-prediction-graph/block-prediction-graph.component.ts 189,187 @@ -2399,13 +2435,14 @@ Block Rewards + Blokk Jutalmak src/app/components/block-rewards-graph/block-rewards-graph.component.html 7,8 src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 60 + 65 src/app/components/graphs/graphs.component.html @@ -2415,6 +2452,7 @@ Block Sizes and Weights + Blokk Méret és Súly src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.html 5,7 @@ -2434,15 +2472,15 @@ Méret src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 180,179 + 184,183 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 226,224 + 239,237 src/app/components/block/block.component.html - 50,52 + 48,50 src/app/components/blocks-list/blocks-list.component.html @@ -2466,7 +2504,7 @@ src/app/components/transaction/transaction.component.html - 270,272 + 264,266 src/app/dashboard/dashboard.component.html @@ -2478,11 +2516,11 @@ Súly src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 188,187 + 192,191 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 257,254 + 270,267 src/app/components/block/block-preview.component.html @@ -2490,15 +2528,27 @@ src/app/components/block/block.component.html - 54,56 + 52,54 src/app/components/transaction/transaction.component.html - 278,280 + 272,274 + + + + Size per weight + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 200,199 + + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 282,279 Block + Blokk src/app/components/block/block-preview.component.html 3,7 @@ -2509,14 +2559,6 @@ shared.block-title - - - - src/app/components/block/block-preview.component.html - 11,12 - - shared.block-title - Median fee Átlag díj @@ -2526,7 +2568,7 @@ src/app/components/block/block.component.html - 128,129 + 127,128 src/app/components/mempool-block/mempool-block.component.html @@ -2543,11 +2585,11 @@ src/app/components/block/block.component.html - 133,135 + 138,140 src/app/components/block/block.component.html - 159,162 + 164,167 src/app/components/mempool-block/mempool-block.component.html @@ -2565,7 +2607,7 @@ src/app/components/block/block.component.html - 168,170 + 173,175 block.miner @@ -2578,7 +2620,7 @@ src/app/components/block/block.component.ts - 227 + 242 @@ -2603,24 +2645,42 @@ Previous Block - - Block health + + Health + Állapot src/app/components/block/block.component.html - 58,61 + 56 - block.health + + src/app/components/blocks-list/blocks-list.component.html + 18,19 + + + src/app/components/blocks-list/blocks-list.component.html + 18,19 + + latest-blocks.health Unknown + Ismeretlen src/app/components/block/block.component.html - 69,72 + 67,70 src/app/components/blocks-list/blocks-list.component.html 60,63 + + src/app/components/pool-ranking/pool-ranking.component.html + 121,124 + + + src/app/lightning/channel/closing-type/closing-type.component.ts + 32 + src/app/lightning/node/node.component.html 52,55 @@ -2644,7 +2704,7 @@ Díj fesztáv src/app/components/block/block.component.html - 124,125 + 123,124 src/app/components/mempool-block/mempool-block.component.html @@ -2657,7 +2717,7 @@ Az átlag 140 vBájtnyi native segwit tranzakción alapulvéve src/app/components/block/block.component.html - 129,131 + 131,136 src/app/components/fees-box/fees-box.component.html @@ -2681,49 +2741,66 @@ Transaction fee tooltip - - Subsidy + fees: - Blokk támogatás + Díj: + + Subsidy + fees + Támogatás + Díjak src/app/components/block/block.component.html - 148,151 + 153,156 src/app/components/block/block.component.html - 163,167 + 168,172 Total subsidy and fees in a block block.subsidy-and-fees - - Projected + + Expected + Várható src/app/components/block/block.component.html - 210,212 + 216 - block.projected + block.expected + + + beta + béta + + src/app/components/block/block.component.html + 216,217 + + + src/app/components/block/block.component.html + 222,224 + + beta Actual + Aktuális src/app/components/block/block.component.html - 212,216 + 218,222 block.actual - - Projected Block + + Expected Block + Várt Blokk src/app/components/block/block.component.html - 216,218 + 222 - block.projected-block + block.expected-block Actual Block + Aktuális Blokk src/app/components/block/block.component.html - 225,227 + 231 block.actual-block @@ -2732,7 +2809,7 @@ Bits src/app/components/block/block.component.html - 250,252 + 256,258 block.bits @@ -2741,7 +2818,7 @@ Merkle törzs src/app/components/block/block.component.html - 254,256 + 260,262 block.merkle-root @@ -2750,7 +2827,7 @@ Nehézség src/app/components/block/block.component.html - 265,268 + 271,274 src/app/components/difficulty-adjustments-table/difficulty-adjustments-table.component.html @@ -2779,7 +2856,7 @@ Nounce src/app/components/block/block.component.html - 269,271 + 275,277 block.nonce @@ -2788,20 +2865,30 @@ Blokk Fejcím Hex src/app/components/block/block.component.html - 273,274 + 279,280 block.header + + Audit + Ellenőrzés + + src/app/components/block/block.component.html + 297,301 + + Toggle Audit + block.toggle-audit + Details Részletek src/app/components/block/block.component.html - 284,288 + 304,308 src/app/components/transaction/transaction.component.html - 254,259 + 248,253 src/app/lightning/channel/channel.component.html @@ -2820,13 +2907,14 @@ Error loading data. + Hiba történt az adatok betöltésekor. src/app/components/block/block.component.html - 303,305 + 323,325 src/app/components/block/block.component.html - 339,343 + 362,366 src/app/lightning/channel/channel-preview.component.html @@ -2848,14 +2936,16 @@ Why is this block empty? + Miért üres ez a blokk? src/app/components/block/block.component.html - 361,367 + 384,390 block.empty-block-explanation Pool + Pool src/app/components/blocks-list/blocks-list.component.html 14 @@ -2895,18 +2985,6 @@ latest-blocks.mined - - Health - - src/app/components/blocks-list/blocks-list.component.html - 18,19 - - - src/app/components/blocks-list/blocks-list.component.html - 18,19 - - latest-blocks.health - Reward Jutalom @@ -2970,7 +3048,7 @@ src/app/dashboard/dashboard.component.html - 210,214 + 219,223 dashboard.txs @@ -2984,6 +3062,7 @@ Adjusted + Módosított src/app/components/difficulty-adjustments-table/difficulty-adjustments-table.component.html 6,8 @@ -2992,6 +3071,7 @@ Change + Váltás src/app/components/difficulty-adjustments-table/difficulty-adjustments-table.component.html 8,11 @@ -3101,6 +3181,7 @@ Next Halving + Következő Felezés src/app/components/difficulty/difficulty.component.html 50,52 @@ -3117,6 +3198,7 @@ No Priority + Nem Sürgősség src/app/components/fees-box/fees-box.component.html 4,7 @@ -3129,6 +3211,7 @@ Usually places your transaction in between the second and third mempool blocks + Általában a második vagy a harmadik blokkba helyezi a tranzakciódat a mempoolban src/app/components/fees-box/fees-box.component.html 8,9 @@ -3137,6 +3220,7 @@ Low Priority + Alacsony src/app/components/fees-box/fees-box.component.html 8,9 @@ -3157,6 +3241,7 @@ Medium Priority + Közepes src/app/components/fees-box/fees-box.component.html 9,10 @@ -3169,6 +3254,7 @@ Places your transaction in the first mempool block + Ez az első mempoolban lévő blokkba helyezi a tranzakciódat src/app/components/fees-box/fees-box.component.html 10,14 @@ -3177,6 +3263,7 @@ High Priority + Elsőbbségi src/app/components/fees-box/fees-box.component.html 10,15 @@ -3196,7 +3283,7 @@ src/app/dashboard/dashboard.component.html - 237,238 + 246,247 dashboard.incoming-transactions @@ -3209,7 +3296,7 @@ src/app/dashboard/dashboard.component.html - 240,243 + 249,252 dashboard.backend-is-synchronizing @@ -3222,7 +3309,7 @@ src/app/dashboard/dashboard.component.html - 245,250 + 254,259 vB/s shared.vbytes-per-second @@ -3236,7 +3323,7 @@ src/app/dashboard/dashboard.component.html - 208,209 + 217,218 Unconfirmed count dashboard.unconfirmed @@ -3253,6 +3340,7 @@ Mining + Bányászat src/app/components/graphs/graphs.component.html 8 @@ -3261,6 +3349,7 @@ Pools Ranking + Pool Rangsorolás src/app/components/graphs/graphs.component.html 11 @@ -3273,6 +3362,7 @@ Pools Dominance + Pool Fölény src/app/components/graphs/graphs.component.html 13 @@ -3285,6 +3375,7 @@ Hashrate & Difficulty + Hashráta és Nehézség src/app/components/graphs/graphs.component.html 15,16 @@ -3293,6 +3384,7 @@ Lightning + Villám src/app/components/graphs/graphs.component.html 31 @@ -3301,6 +3393,7 @@ Lightning Nodes Per Network + Villám Nodeok Hálózatonként src/app/components/graphs/graphs.component.html 34 @@ -3321,6 +3414,7 @@ Lightning Network Capacity + Villám Hálózati Kapacítás src/app/components/graphs/graphs.component.html 36 @@ -3341,6 +3435,7 @@ Lightning Nodes Per ISP + Villám Node Szolgáltatónként src/app/components/graphs/graphs.component.html 38 @@ -3353,6 +3448,7 @@ Lightning Nodes Per Country + Villám Nodeok Országonként src/app/components/graphs/graphs.component.html 40 @@ -3369,6 +3465,7 @@ Lightning Nodes World Map + Villám Node Világ Térkép src/app/components/graphs/graphs.component.html 42 @@ -3385,6 +3482,7 @@ Lightning Nodes Channels World Map + Villám Node Csatorna Világ Térkép src/app/components/graphs/graphs.component.html 44 @@ -3397,6 +3495,7 @@ Hashrate + Hashráta src/app/components/hashrate-chart/hashrate-chart.component.html 8,10 @@ -3425,6 +3524,7 @@ Hashrate & Difficulty + Hashráta és Nehézség src/app/components/hashrate-chart/hashrate-chart.component.html 27,29 @@ -3437,6 +3537,7 @@ Hashrate (MA) + Hashráta (MA) src/app/components/hashrate-chart/hashrate-chart.component.ts 292,291 @@ -3476,7 +3577,7 @@ src/app/components/master-page/master-page.component.html - 52,54 + 51,53 src/app/components/statistics/statistics.component.ts @@ -3486,6 +3587,7 @@ Mining Dashboard + Bányászatipult src/app/components/master-page/master-page.component.html 41,43 @@ -3498,9 +3600,10 @@ Lightning Explorer + Villám Felfedező src/app/components/master-page/master-page.component.html - 44,45 + 44,47 src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts @@ -3508,20 +3611,12 @@ master-page.lightning - - beta - - src/app/components/master-page/master-page.component.html - 45,48 - - beta - Documentation Dokumentáció src/app/components/master-page/master-page.component.html - 55,57 + 54,56 src/app/docs/docs/docs.component.html @@ -3563,6 +3658,7 @@ Reward stats + Jutalmi statisztikák src/app/components/mining-dashboard/mining-dashboard.component.html 10 @@ -3571,6 +3667,7 @@ (144 blocks) + (144 blokk) src/app/components/mining-dashboard/mining-dashboard.component.html 11 @@ -3592,12 +3689,39 @@ Adjustments + Módosítás src/app/components/mining-dashboard/mining-dashboard.component.html 67 dashboard.adjustments + + Broadcast Transaction + Tranzakció Küldése + + src/app/components/mining-dashboard/mining-dashboard.component.html + 92 + + + src/app/components/push-transaction/push-transaction.component.html + 2 + + + src/app/components/push-transaction/push-transaction.component.html + 8 + + + src/app/dashboard/dashboard.component.html + 161,169 + + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 102 + + Broadcast Transaction + shared.broadcast-transaction + Pools luck (1 week) @@ -3608,6 +3732,7 @@ Pools luck + Pool szerencse src/app/components/pool-ranking/pool-ranking.component.html 9,11 @@ -3632,6 +3757,7 @@ Pools count + Poolok száma src/app/components/pool-ranking/pool-ranking.component.html 17,19 @@ -3648,6 +3774,7 @@ Blocks (1w) + Blokkok (1hé) src/app/components/pool-ranking/pool-ranking.component.html 25 @@ -3658,7 +3785,7 @@ src/app/components/pool-ranking/pool-ranking.component.html - 136,138 + 152,154 master-page.blocks @@ -3687,19 +3814,34 @@ mining.rank - - Empty blocks + + Avg Health + Átlagos Állapot src/app/components/pool-ranking/pool-ranking.component.html - 95,98 + 96,97 + + + src/app/components/pool-ranking/pool-ranking.component.html + 96,98 + + latest-blocks.avg_health + + + Empty blocks + Üres blokkok + + src/app/components/pool-ranking/pool-ranking.component.html + 97,100 mining.empty-blocks All miners + Minden bányász src/app/components/pool-ranking/pool-ranking.component.html - 113,114 + 129,130 mining.all-miners @@ -3707,7 +3849,7 @@ Pools Luck (1w) src/app/components/pool-ranking/pool-ranking.component.html - 130,132 + 146,148 mining.miners-luck @@ -3715,19 +3857,21 @@ Pools Count (1w) src/app/components/pool-ranking/pool-ranking.component.html - 142,144 + 158,160 mining.miners-count Mining Pools + Bányászati Poolok src/app/components/pool-ranking/pool-ranking.component.ts - 57 + 58 blocks + blokk src/app/components/pool-ranking/pool-ranking.component.ts 165,163 @@ -3739,6 +3883,7 @@ mining pool + bányászó pool src/app/components/pool/pool-preview.component.html 3,5 @@ -3747,6 +3892,7 @@ Tags + Címkék src/app/components/pool/pool-preview.component.html 18,19 @@ -3825,6 +3971,7 @@ Estimated + Becsült src/app/components/pool/pool.component.html 96,97 @@ -3933,6 +4080,7 @@ Coinbase tag + Érmebázis címke src/app/components/pool/pool.component.html 215,217 @@ -3943,24 +4091,6 @@ latest-blocks.coinbasetag - - Broadcast Transaction - Tranzakció Küldése - - src/app/components/push-transaction/push-transaction.component.html - 2 - - - src/app/components/push-transaction/push-transaction.component.html - 8 - - - src/app/dashboard/dashboard.component.html - 154,161 - - Broadcast Transaction - shared.broadcast-transaction - Transaction hex @@ -3969,7 +4099,7 @@ src/app/components/transaction/transaction.component.html - 296,297 + 290,291 transaction.hex @@ -4019,6 +4149,7 @@ BTC/block + BTC/blokk src/app/components/reward-stats/reward-stats.component.html 21,24 @@ -4048,6 +4179,7 @@ sats/tx + sats/tx src/app/components/reward-stats/reward-stats.component.html 33,36 @@ -4057,6 +4189,7 @@ Reward Per Tx + Jutalom per Tx src/app/components/reward-stats/reward-stats.component.html 53,56 @@ -4084,6 +4217,70 @@ search-form.search-title + + Bitcoin Block Height + + src/app/components/search-form/search-results/search-results.component.html + 3 + + search.bitcoin-block-height + + + Bitcoin Transaction + + src/app/components/search-form/search-results/search-results.component.html + 9 + + search.bitcoin-transaction + + + Bitcoin Address + + src/app/components/search-form/search-results/search-results.component.html + 15 + + search.bitcoin-address + + + Bitcoin Block + + src/app/components/search-form/search-results/search-results.component.html + 21 + + search.bitcoin-block + + + Bitcoin Addresses + + src/app/components/search-form/search-results/search-results.component.html + 27 + + search.bitcoin-addresses + + + Lightning Nodes + + src/app/components/search-form/search-results/search-results.component.html + 35 + + search.lightning-nodes + + + Lightning Channels + + src/app/components/search-form/search-results/search-results.component.html + 43 + + search.lightning-channels + + + Go to "" + + src/app/components/search-form/search-results/search-results.component.html + 52 + + search.go-to + Mempool by vBytes (sat/vByte) Mempool vBájtonként (sat/vBájt) @@ -4350,6 +4547,7 @@ Replaced + Cserélve src/app/components/transaction/transaction.component.html 36,39 @@ -4366,7 +4564,7 @@ src/app/components/transactions-list/transactions-list.component.html - 298,301 + 300,303 Transaction unconfirmed state transaction.unconfirmed @@ -4376,7 +4574,7 @@ Először látva src/app/components/transaction/transaction.component.html - 108,109 + 102,103 src/app/lightning/node/node.component.html @@ -4410,7 +4608,7 @@ Hátralévő idő src/app/components/transaction/transaction.component.html - 115,116 + 109,110 Transaction ETA transaction.eta @@ -4420,7 +4618,7 @@ Több órán belül (vagy később) src/app/components/transaction/transaction.component.html - 121,124 + 115,118 Transaction ETA in several hours or more transaction.eta.in-several-hours @@ -4430,11 +4628,11 @@ Utód src/app/components/transaction/transaction.component.html - 168,170 + 162,164 src/app/components/transaction/transaction.component.html - 179,181 + 173,175 Descendant transaction.descendant @@ -4444,37 +4642,40 @@ Felmenő src/app/components/transaction/transaction.component.html - 190,192 + 184,186 Transaction Ancestor transaction.ancestor Flow + Áramlás src/app/components/transaction/transaction.component.html - 208,211 + 202,205 src/app/components/transaction/transaction.component.html - 346,350 + 340,344 Transaction flow transaction.flow Hide diagram + Diagram elrejtése src/app/components/transaction/transaction.component.html - 211,216 + 205,210 hide-diagram Show more + Továbbiak megjelenítése src/app/components/transaction/transaction.component.html - 231,233 + 225,227 src/app/components/transactions-list/transactions-list.component.html @@ -4488,9 +4689,10 @@ Show less + Kevesebb megjelenítése src/app/components/transaction/transaction.component.html - 233,239 + 227,233 src/app/components/transactions-list/transactions-list.component.html @@ -4500,9 +4702,10 @@ Show diagram + Diagram megjelenítése src/app/components/transaction/transaction.component.html - 253,254 + 247,248 show-diagram @@ -4511,7 +4714,7 @@ Zárolási idő src/app/components/transaction/transaction.component.html - 292,294 + 286,288 transaction.locktime @@ -4520,7 +4723,7 @@ Nem található tranzakció. src/app/components/transaction/transaction.component.html - 455,456 + 449,450 transaction.error.transaction-not-found @@ -4529,7 +4732,7 @@ Várakozás arra hogy a mempoolban feltünjön... src/app/components/transaction/transaction.component.html - 456,461 + 450,455 transaction.error.waiting-for-it-to-appear @@ -4538,7 +4741,7 @@ Effektív díj ráta src/app/components/transaction/transaction.component.html - 489,492 + 485,488 Effective transaction fee rate transaction.effective-fee-rate @@ -4610,6 +4813,7 @@ P2TR tapscript + P2TR tapscript src/app/components/transactions-list/transactions-list.component.html 132,134 @@ -4685,20 +4889,22 @@ Show more inputs to reveal fee data src/app/components/transactions-list/transactions-list.component.html - 288,291 + 290,293 transactions-list.load-to-reveal-fee-info remaining + hátramaradt src/app/components/transactions-list/transactions-list.component.html - 330,331 + 332,333 x-remaining other inputs + más bemenetek src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html 12 @@ -4707,6 +4913,7 @@ other outputs + más kiemenetek src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html 13 @@ -4715,6 +4922,7 @@ Input + Bemenet src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html 42 @@ -4727,6 +4935,7 @@ Output + Kiemenet src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html 43 @@ -4789,6 +4998,7 @@ Taproot + Taproot src/app/components/tx-features/tx-features.component.html 12 @@ -4931,21 +5141,12 @@ dashboard.latest-transactions - - USD - USA Dollár - - src/app/dashboard/dashboard.component.html - 126,127 - - dashboard.latest-transactions.USD - Minimum fee Minimum Díj src/app/dashboard/dashboard.component.html - 201,202 + 210,211 Minimum mempool fee dashboard.minimum-fee @@ -4955,7 +5156,7 @@ Törlés src/app/dashboard/dashboard.component.html - 202,203 + 211,212 Purgin below fee dashboard.purging @@ -4965,7 +5166,7 @@ Memória használat src/app/dashboard/dashboard.component.html - 214,215 + 223,224 Memory usage dashboard.memory-usage @@ -4975,15 +5176,24 @@ L-BTC forgalomban src/app/dashboard/dashboard.component.html - 228,230 + 237,239 dashboard.lbtc-pegs-in-circulation - - REST API service + + mempool.space merely provides data about the Bitcoin network. It cannot help you with retrieving funds, confirming your transaction quicker, etc. src/app/docs/api-docs/api-docs.component.html - 39,40 + 13 + + faq.big-disclaimer + + + REST API service + REST API szolgáltatás + + src/app/docs/api-docs/api-docs.component.html + 41,42 api-docs.title @@ -4992,11 +5202,11 @@ Végpont src/app/docs/api-docs/api-docs.component.html - 48,49 + 50,51 src/app/docs/api-docs/api-docs.component.html - 102,105 + 104,107 Api docs endpoint @@ -5005,11 +5215,11 @@ Leírás src/app/docs/api-docs/api-docs.component.html - 67,68 + 69,70 src/app/docs/api-docs/api-docs.component.html - 106,107 + 108,109 @@ -5017,7 +5227,7 @@ Alaphelyzeti push: művelet: 'kell', data: ['blocks', ...] hogy kifejezd mit szeretnél pusholni. Elérhető: blocks, mempool-blocks, live-2h-chart, and stats.Pusholjon tranzakciókat címekhez fogva: 'cím-követés': '3PbJ...bF9B' az összes új tranzakció fogadásához, amely ezt a címet tartalmazza bemenetként vagy kimenetként. Tranzakciók tömbjét adja vissza. cím-tranzakciókúj mempool tranzakciókhoz , és block-tranzakciók az új blokk megerősített tranzakciókhoz. src/app/docs/api-docs/api-docs.component.html - 107,108 + 109,110 api-docs.websocket.websocket @@ -5086,6 +5296,7 @@ Base fee + Bázis díj src/app/lightning/channel/channel-box/channel-box.component.html 29 @@ -5098,6 +5309,7 @@ mSats + mSats src/app/lightning/channel/channel-box/channel-box.component.html 35 @@ -5126,6 +5338,7 @@ Zero base fee + Zeró alapdíj src/app/lightning/channel/channel-box/channel-box.component.html 45 @@ -5142,6 +5355,7 @@ Non-zero base fee + Nem-nulla alapdíj src/app/lightning/channel/channel-box/channel-box.component.html 51 @@ -5150,6 +5364,7 @@ Min HTLC + Min HTLC src/app/lightning/channel/channel-box/channel-box.component.html 57 @@ -5158,6 +5373,7 @@ Max HTLC + Max HTLC src/app/lightning/channel/channel-box/channel-box.component.html 63 @@ -5166,6 +5382,7 @@ Timelock delta + Időzár delta src/app/lightning/channel/channel-box/channel-box.component.html 69 @@ -5174,18 +5391,20 @@ channels + csatorna src/app/lightning/channel/channel-box/channel-box.component.html 79 src/app/lightning/channels-list/channels-list.component.html - 120,121 + 123,124 lightning.x-channels Starting balance + Induló egyenleg src/app/lightning/channel/channel-close-box/channel-close-box.component.html 6 @@ -5195,6 +5414,7 @@ Closing balance + Záró egyenleg src/app/lightning/channel/channel-close-box/channel-close-box.component.html 12 @@ -5204,6 +5424,7 @@ lightning channel + villám csatorna src/app/lightning/channel/channel-preview.component.html 3,5 @@ -5212,6 +5433,7 @@ Inactive + Inaktív src/app/lightning/channel/channel-preview.component.html 10,11 @@ -5222,12 +5444,13 @@ src/app/lightning/channels-list/channels-list.component.html - 65,66 + 68,69 status.inactive Active + Aktív src/app/lightning/channel/channel-preview.component.html 11,12 @@ -5238,12 +5461,13 @@ src/app/lightning/channels-list/channels-list.component.html - 66,68 + 69,71 status.active Closed + Lezárt src/app/lightning/channel/channel-preview.component.html 12,14 @@ -5258,12 +5482,13 @@ src/app/lightning/channels-list/channels-list.component.html - 68,70 + 71,73 status.closed Created + Létrehozott src/app/lightning/channel/channel-preview.component.html 23,26 @@ -5276,6 +5501,7 @@ Capacity + Kapacítás src/app/lightning/channel/channel-preview.component.html 27,28 @@ -5286,7 +5512,7 @@ src/app/lightning/channels-list/channels-list.component.html - 40,43 + 43,46 src/app/lightning/node-statistics/node-statistics.component.html @@ -5294,7 +5520,7 @@ src/app/lightning/node-statistics/node-statistics.component.html - 47,50 + 46,49 src/app/lightning/nodes-list/nodes-list.component.html @@ -5328,6 +5554,7 @@ ppm + ppm src/app/lightning/channel/channel-preview.component.html 34,35 @@ -5348,6 +5575,7 @@ Lightning channel + Villám csatorna src/app/lightning/channel/channel.component.html 2,5 @@ -5360,6 +5588,7 @@ Last update + Utolsó frissítés src/app/lightning/channel/channel.component.html 33,34 @@ -5392,18 +5621,20 @@ Closing date + Zárási dátum src/app/lightning/channel/channel.component.html 37,38 src/app/lightning/channels-list/channels-list.component.html - 39,40 + 42,43 lightning.closing_date Closed by + Lezárva átala src/app/lightning/channel/channel.component.html 52,54 @@ -5412,6 +5643,7 @@ Opening transaction + Nyitó tranzakció src/app/lightning/channel/channel.component.html 84,85 @@ -5420,6 +5652,7 @@ Closing transaction + Záró tranzakció src/app/lightning/channel/channel.component.html 93,95 @@ -5428,13 +5661,37 @@ Channel: + Csatorna: src/app/lightning/channel/channel.component.ts 37 + + Mutually closed + Közösen lezárt + + src/app/lightning/channel/closing-type/closing-type.component.ts + 20 + + + + Force closed + + src/app/lightning/channel/closing-type/closing-type.component.ts + 24 + + + + Force closed with penalty + + src/app/lightning/channel/closing-type/closing-type.component.ts + 28 + + Open + Nyitás src/app/lightning/channels-list/channels-list.component.html 5,7 @@ -5443,17 +5700,19 @@ No channels to display + Nincs megjeleníthető csatorna src/app/lightning/channels-list/channels-list.component.html - 29,35 + 29,37 lightning.empty-channels-list Alias + Alias src/app/lightning/channels-list/channels-list.component.html - 35,37 + 38,40 src/app/lightning/group/group.component.html @@ -5487,29 +5746,32 @@ Status + Állapot src/app/lightning/channels-list/channels-list.component.html - 37,38 + 40,41 status Channel ID + Csatorna ID src/app/lightning/channels-list/channels-list.component.html - 41,45 + 44,48 channels.id sats + sats src/app/lightning/channels-list/channels-list.component.html - 60,64 + 63,67 src/app/lightning/channels-list/channels-list.component.html - 84,88 + 87,91 src/app/lightning/channels-statistics/channels-statistics.component.html @@ -5553,8 +5815,25 @@ shared.sats + + avg + + src/app/lightning/channels-statistics/channels-statistics.component.html + 3,5 + + statistics.average-small + + + med + + src/app/lightning/channels-statistics/channels-statistics.component.html + 6,9 + + statistics.median-small + Avg Capacity + Átlag Kapacítás src/app/lightning/channels-statistics/channels-statistics.component.html 13,15 @@ -5567,6 +5846,7 @@ Avg Fee Rate + Átlag Díj Ráta src/app/lightning/channels-statistics/channels-statistics.component.html 26,28 @@ -5587,6 +5867,7 @@ Avg Base Fee + Átlag Bázis Díj src/app/lightning/channels-statistics/channels-statistics.component.html 41,43 @@ -5607,6 +5888,7 @@ Med Capacity + Közepes Kapacítás src/app/lightning/channels-statistics/channels-statistics.component.html 59,61 @@ -5659,6 +5941,7 @@ Nodes + Nódok src/app/lightning/group/group-preview.component.html 25,29 @@ -5669,11 +5952,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 17,18 + 16,17 src/app/lightning/node-statistics/node-statistics.component.html - 54,57 + 53,56 src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html @@ -5695,6 +5978,7 @@ Liquidity + Likvidítás src/app/lightning/group/group-preview.component.html 29,31 @@ -5731,6 +6015,7 @@ Channels + Csatornák src/app/lightning/group/group-preview.component.html 40,43 @@ -5741,11 +6026,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 29,30 + 28,29 src/app/lightning/node-statistics/node-statistics.component.html - 61,64 + 60,63 src/app/lightning/nodes-list/nodes-list.component.html @@ -5791,6 +6076,7 @@ Average size + Átlagos méret src/app/lightning/group/group-preview.component.html 44,46 @@ -5803,6 +6089,7 @@ Location + Helység src/app/lightning/group/group.component.html 74,77 @@ -5901,6 +6188,28 @@ lightning.node-fee-distribution + + Outgoing Fees + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 170 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 208 + + + + Incoming Fees + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 178 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 222 + + Percentage change past week @@ -5909,16 +6218,17 @@ src/app/lightning/node-statistics/node-statistics.component.html - 18,20 + 17,19 src/app/lightning/node-statistics/node-statistics.component.html - 30,32 + 29,31 mining.percentage-change-last-week Lightning node + Villám node src/app/lightning/node/node-preview.component.html 3,5 @@ -5935,6 +6245,7 @@ Active capacity + Átlagos kapacítás src/app/lightning/node/node-preview.component.html 20,22 @@ -5959,6 +6270,7 @@ Country + Ország src/app/lightning/node/node-preview.component.html 44,47 @@ -5991,6 +6303,7 @@ Color + Szín src/app/lightning/node/node.component.html 79,81 @@ -5999,6 +6312,7 @@ ISP + ISP src/app/lightning/node/node.component.html 86,87 @@ -6077,6 +6391,7 @@ TLV extension records + TLV kiterjesztési esemény src/app/lightning/node/node.component.html 199,202 @@ -6085,6 +6400,7 @@ Open channels + Nyitott csatornák src/app/lightning/node/node.component.html 240,243 @@ -6093,6 +6409,7 @@ Closed channels + Lezárt csatornák src/app/lightning/node/node.component.html 244,247 @@ -6101,6 +6418,7 @@ Node: + Node: src/app/lightning/node/node.component.ts 60 @@ -6137,7 +6455,7 @@ No geolocation data available src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts - 218,213 + 219,214 @@ -6194,6 +6512,7 @@ Share + Megoszlás src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html 29,31 @@ -6206,6 +6525,7 @@ nodes + nódok src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts 103,102 @@ -6236,6 +6556,7 @@ ISP Count + ISP Szám src/app/lightning/nodes-per-country/nodes-per-country.component.html 34,38 @@ -6244,6 +6565,7 @@ Top ISP + Top ISP src/app/lightning/nodes-per-country/nodes-per-country.component.html 38,40 @@ -6252,6 +6574,7 @@ Lightning nodes in + Villám nódok itt src/app/lightning/nodes-per-country/nodes-per-country.component.ts 35 @@ -6259,6 +6582,7 @@ Clearnet Capacity + Clearnet Kapacítás src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 6,8 @@ -6279,6 +6603,7 @@ Unknown Capacity + Ismeretlen Kapacítás src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 13,15 @@ -6299,6 +6624,7 @@ Tor Capacity + Tor Kapacítás src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 20,22 @@ -6327,6 +6653,7 @@ BTC + BTC src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts 158,156 @@ -6338,6 +6665,7 @@ Lightning ISP + Villám ISP src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.html 3,5 @@ -6346,6 +6674,7 @@ Top country + Top ország src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.html 39,41 @@ -6358,6 +6687,7 @@ Top node + Top node src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.html 45,48 @@ -6385,6 +6715,7 @@ ASN + ASN src/app/lightning/nodes-per-isp/nodes-per-isp.component.html 11,14 @@ -6393,6 +6724,7 @@ Active nodes + Aktív nódok src/app/lightning/nodes-per-isp/nodes-per-isp.component.html 14,18 @@ -6432,6 +6764,7 @@ Oldest nodes + Legrégebbi nodeok src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.html 36 @@ -6440,6 +6773,7 @@ Top lightning nodes + Top villám nodeok src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.ts 22 @@ -6447,6 +6781,7 @@ Indexing in progress + Indexelés folyamatban src/app/lightning/statistics-chart/lightning-statistics-chart.component.html 52,55 diff --git a/frontend/src/locale/messages.ro.xlf b/frontend/src/locale/messages.ro.xlf index 1eddb2845..41cab4eea 100644 --- a/frontend/src/locale/messages.ro.xlf +++ b/frontend/src/locale/messages.ro.xlf @@ -11,6 +11,7 @@ Slide of + Pagina din node_modules/src/carousel/carousel.ts 175,181 @@ -147,6 +148,7 @@ + node_modules/src/progressbar/progressbar.ts 30,33 @@ -357,11 +359,11 @@ src/app/components/block/block.component.html - 290,291 + 310,311 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 26,27 + 46,47 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -382,11 +384,11 @@ src/app/components/block/block.component.html - 291,292 + 311,312 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 27,28 + 47,48 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -424,7 +426,7 @@ src/app/components/block/block.component.html - 40,41 + 38,39 block.hash @@ -449,7 +451,7 @@ src/app/components/block/block.component.html - 44,46 + 42,44 src/app/components/blocks-list/blocks-list.component.html @@ -592,11 +594,11 @@ src/app/components/master-page/master-page.component.html - 49,51 + 48,50 src/app/components/pool-ranking/pool-ranking.component.html - 94,96 + 94,95 @@ -775,14 +777,22 @@ src/app/components/about/about.component.html 385,389 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 88 + src/app/dashboard/dashboard.component.html - 150,152 + 157,159 src/app/docs/docs/docs.component.html 51 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 97 + Terms of Service shared.terms-of-service @@ -793,14 +803,22 @@ src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html 113,120 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 90 + src/app/dashboard/dashboard.component.html - 152,154 + 159,161 src/app/docs/docs/docs.component.html 53 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 99 + Privacy Policy shared.privacy-policy @@ -988,7 +1006,7 @@ src/app/dashboard/dashboard.component.html - 124,125 + 124,126 @@ -1036,7 +1054,7 @@ src/app/components/transaction/transaction.component.html - 158,160 + 152,154 src/app/components/transactions-list/transactions-list.component.html @@ -1052,11 +1070,11 @@ src/app/components/block/block.component.html - 246,247 + 252,253 src/app/components/transaction/transaction.component.html - 288,290 + 282,284 transaction.version @@ -1106,7 +1124,7 @@ src/app/components/transactions-list/transactions-list.component.html - 294,295 + 296,297 Transaction singular confirmation count shared.confirmation-count.singular @@ -1128,7 +1146,7 @@ src/app/components/transactions-list/transactions-list.component.html - 295,296 + 297,298 Transaction plural confirmation count shared.confirmation-count.plural @@ -1140,10 +1158,6 @@ src/app/bisq/bisq-transaction/bisq-transaction.component.html 43,45 - - src/app/components/transaction/transaction.component.html - 65,67 - Transaction included in block transaction.included-in-block @@ -1156,11 +1170,11 @@ src/app/components/transaction/transaction.component.html - 77,80 + 71,74 src/app/components/transaction/transaction.component.html - 135,138 + 129,132 Transaction features transaction.features @@ -1188,11 +1202,11 @@ src/app/components/transaction/transaction.component.html - 262,267 + 256,261 src/app/components/transaction/transaction.component.html - 406,412 + 400,406 transaction.details @@ -1209,11 +1223,11 @@ src/app/components/transaction/transaction.component.html - 249,253 + 243,247 src/app/components/transaction/transaction.component.html - 377,383 + 371,377 Transaction inputs and outputs transaction.inputs-and-outputs @@ -1231,7 +1245,7 @@ src/app/components/transaction/transaction.component.ts - 241,240 + 244,243 @@ -1251,7 +1265,7 @@ src/app/components/transaction/transaction.component.html - 159,160 + 153,154 src/app/dashboard/dashboard.component.html @@ -1267,7 +1281,7 @@ src/app/components/transaction/transaction.component.html - 72,73 + 66,67 Transaction Confirmed state transaction.confirmed @@ -1461,6 +1475,7 @@ Community Integrations + Integrări în comunitate src/app/components/about/about.component.html 191,193 @@ -1529,11 +1544,12 @@ src/app/components/master-page/master-page.component.html - 58,61 + 57,60 Multisig of + Multisig din src/app/components/address-labels/address-labels.component.ts 107 @@ -1565,7 +1581,7 @@ src/app/components/amount/amount.component.html - 6,9 + 18,21 src/app/components/asset-circulation/asset-circulation.component.html @@ -1581,7 +1597,7 @@ src/app/components/transactions-list/transactions-list.component.html - 302,304 + 304,306 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -1664,7 +1680,7 @@ src/app/components/assets/assets.component.html - 29,31 + 31,33 src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html @@ -1886,7 +1902,7 @@ src/app/components/assets/assets.component.html - 30,31 + 32,33 Asset ticker header @@ -1899,7 +1915,7 @@ src/app/components/assets/assets.component.html - 31,34 + 33,36 Asset Issuer Domain header @@ -1912,7 +1928,7 @@ src/app/components/assets/assets.component.html - 32,36 + 34,38 Asset ID header @@ -1921,7 +1937,7 @@ Eroare la încărcarea datelor despre active. src/app/components/assets/assets.component.html - 48,53 + 50,55 Asset data load error @@ -2045,7 +2061,7 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 161 + 165 @@ -2061,7 +2077,7 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 163 + 167 @@ -2073,7 +2089,7 @@ src/app/components/block-fees-graph/block-fees-graph.component.ts - 62 + 67 src/app/components/graphs/graphs.component.html @@ -2086,15 +2102,15 @@ Indexare blocuri src/app/components/block-fees-graph/block-fees-graph.component.ts - 110,105 + 116,111 src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 108,103 + 113,108 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 115,110 + 116,111 src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -2119,6 +2135,7 @@ not available + indisponibil src/app/components/block-overview-graph/block-overview-graph.component.html 5 @@ -2138,7 +2155,7 @@ src/app/components/transaction/transaction.component.html - 476 + 472 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -2164,11 +2181,11 @@ src/app/components/transaction/transaction.component.html - 476,477 + 472 src/app/components/transactions-list/transactions-list.component.html - 286,287 + 288 sat shared.sat @@ -2182,11 +2199,11 @@ src/app/components/transaction/transaction.component.html - 161,165 + 155,159 src/app/components/transaction/transaction.component.html - 479,481 + 475,477 src/app/lightning/channel/channel-box/channel-box.component.html @@ -2198,7 +2215,7 @@ src/app/lightning/channels-list/channels-list.component.html - 38,39 + 41,42 Transaction fee rate transaction.fee-rate @@ -2216,19 +2233,19 @@ src/app/components/block/block.component.html - 125,128 + 124,127 src/app/components/block/block.component.html - 129 + 128,130 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 12,14 + 19,22 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 15,17 + 30,33 src/app/components/fees-box/fees-box.component.html @@ -2268,27 +2285,27 @@ src/app/components/transaction/transaction.component.html - 173,174 + 167,168 src/app/components/transaction/transaction.component.html - 184,185 + 178,179 src/app/components/transaction/transaction.component.html - 195,196 + 189,190 src/app/components/transaction/transaction.component.html - 481,484 + 477,480 src/app/components/transaction/transaction.component.html - 492,494 + 488,490 src/app/components/transactions-list/transactions-list.component.html - 286 + 286,287 src/app/dashboard/dashboard.component.html @@ -2296,7 +2313,7 @@ src/app/dashboard/dashboard.component.html - 204,208 + 213,217 sat/vB shared.sat-vbyte @@ -2310,17 +2327,18 @@ src/app/components/transaction/transaction.component.html - 160,162 + 154,156 src/app/components/transaction/transaction.component.html - 274,277 + 268,271 Transaction Virtual Size transaction.vsize Audit status + Starea auditului src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 36 @@ -2329,6 +2347,7 @@ Match + Potrivire src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 38 @@ -2337,6 +2356,7 @@ Removed + Îndepărtat src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 39 @@ -2345,6 +2365,7 @@ Marginal fee rate + Rata comisionului marginal src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 40 @@ -2357,6 +2378,7 @@ Recently broadcasted + Recent transmis src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 41 @@ -2365,6 +2387,7 @@ Added + Adăugat src/app/components/block-overview-tooltip/block-overview-tooltip.component.html 42 @@ -2390,6 +2413,7 @@ No data to display yet. Try again later. + Nu există date de afișat încă. Încercați mai târziu. src/app/components/block-prediction-graph/block-prediction-graph.component.ts 108,103 @@ -2420,7 +2444,7 @@ src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 60 + 65 src/app/components/graphs/graphs.component.html @@ -2450,15 +2474,15 @@ Mărime src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 180,179 + 184,183 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 226,224 + 239,237 src/app/components/block/block.component.html - 50,52 + 48,50 src/app/components/blocks-list/blocks-list.component.html @@ -2482,7 +2506,7 @@ src/app/components/transaction/transaction.component.html - 270,272 + 264,266 src/app/dashboard/dashboard.component.html @@ -2494,11 +2518,11 @@ Greutate src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 188,187 + 192,191 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 257,254 + 270,267 src/app/components/block/block-preview.component.html @@ -2506,15 +2530,28 @@ src/app/components/block/block.component.html - 54,56 + 52,54 src/app/components/transaction/transaction.component.html - 278,280 + 272,274 + + + + Size per weight + Dimensiune pe greutate + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 200,199 + + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 282,279 Block + Bloc src/app/components/block/block-preview.component.html 3,7 @@ -2525,14 +2562,6 @@ shared.block-title - - - - src/app/components/block/block-preview.component.html - 11,12 - - shared.block-title - Median fee Comision median @@ -2542,7 +2571,7 @@ src/app/components/block/block.component.html - 128,129 + 127,128 src/app/components/mempool-block/mempool-block.component.html @@ -2559,11 +2588,11 @@ src/app/components/block/block.component.html - 133,135 + 138,140 src/app/components/block/block.component.html - 159,162 + 164,167 src/app/components/mempool-block/mempool-block.component.html @@ -2581,7 +2610,7 @@ src/app/components/block/block.component.html - 168,170 + 173,175 block.miner @@ -2594,7 +2623,7 @@ src/app/components/block/block.component.ts - 227 + 242 @@ -2619,24 +2648,42 @@ Previous Block - - Block health + + Health + Sănătate src/app/components/block/block.component.html - 58,61 + 56 - block.health + + src/app/components/blocks-list/blocks-list.component.html + 18,19 + + + src/app/components/blocks-list/blocks-list.component.html + 18,19 + + latest-blocks.health Unknown + Necunoscut src/app/components/block/block.component.html - 69,72 + 67,70 src/app/components/blocks-list/blocks-list.component.html 60,63 + + src/app/components/pool-ranking/pool-ranking.component.html + 121,124 + + + src/app/lightning/channel/closing-type/closing-type.component.ts + 32 + src/app/lightning/node/node.component.html 52,55 @@ -2660,7 +2707,7 @@ Interval comisioane src/app/components/block/block.component.html - 124,125 + 123,124 src/app/components/mempool-block/mempool-block.component.html @@ -2673,7 +2720,7 @@ Pe baza valorii medii a tranzacției segwit native de 140 vBytes src/app/components/block/block.component.html - 129,131 + 131,136 src/app/components/fees-box/fees-box.component.html @@ -2697,49 +2744,66 @@ Transaction fee tooltip - - Subsidy + fees: - Subvenție + comisioane: + + Subsidy + fees + Subvenție + comisioane src/app/components/block/block.component.html - 148,151 + 153,156 src/app/components/block/block.component.html - 163,167 + 168,172 Total subsidy and fees in a block block.subsidy-and-fees - - Projected + + Expected + Așteptat src/app/components/block/block.component.html - 210,212 + 216 - block.projected + block.expected + + + beta + beta + + src/app/components/block/block.component.html + 216,217 + + + src/app/components/block/block.component.html + 222,224 + + beta Actual + Real src/app/components/block/block.component.html - 212,216 + 218,222 block.actual - - Projected Block + + Expected Block + Bloc așteptat src/app/components/block/block.component.html - 216,218 + 222 - block.projected-block + block.expected-block Actual Block + Blocul real src/app/components/block/block.component.html - 225,227 + 231 block.actual-block @@ -2748,7 +2812,7 @@ Biți src/app/components/block/block.component.html - 250,252 + 256,258 block.bits @@ -2757,7 +2821,7 @@ Rădăcină Merkle src/app/components/block/block.component.html - 254,256 + 260,262 block.merkle-root @@ -2766,7 +2830,7 @@ Dificultate src/app/components/block/block.component.html - 265,268 + 271,274 src/app/components/difficulty-adjustments-table/difficulty-adjustments-table.component.html @@ -2795,7 +2859,7 @@ Număr arbitrar src/app/components/block/block.component.html - 269,271 + 275,277 block.nonce @@ -2804,20 +2868,30 @@ Valoarea Hex a antetului blocului src/app/components/block/block.component.html - 273,274 + 279,280 block.header + + Audit + Audit + + src/app/components/block/block.component.html + 297,301 + + Toggle Audit + block.toggle-audit + Details Detalii src/app/components/block/block.component.html - 284,288 + 304,308 src/app/components/transaction/transaction.component.html - 254,259 + 248,253 src/app/lightning/channel/channel.component.html @@ -2839,11 +2913,11 @@ Eroare la încărcarea datelor. src/app/components/block/block.component.html - 303,305 + 323,325 src/app/components/block/block.component.html - 339,343 + 362,366 src/app/lightning/channel/channel-preview.component.html @@ -2865,9 +2939,10 @@ Why is this block empty? + De ce acest bloc este gol? src/app/components/block/block.component.html - 361,367 + 384,390 block.empty-block-explanation @@ -2913,18 +2988,6 @@ latest-blocks.mined - - Health - - src/app/components/blocks-list/blocks-list.component.html - 18,19 - - - src/app/components/blocks-list/blocks-list.component.html - 18,19 - - latest-blocks.health - Reward Recompensă @@ -2988,7 +3051,7 @@ src/app/dashboard/dashboard.component.html - 210,214 + 219,223 dashboard.txs @@ -3227,7 +3290,7 @@ src/app/dashboard/dashboard.component.html - 237,238 + 246,247 dashboard.incoming-transactions @@ -3240,7 +3303,7 @@ src/app/dashboard/dashboard.component.html - 240,243 + 249,252 dashboard.backend-is-synchronizing @@ -3253,7 +3316,7 @@ src/app/dashboard/dashboard.component.html - 245,250 + 254,259 vB/s shared.vbytes-per-second @@ -3267,7 +3330,7 @@ src/app/dashboard/dashboard.component.html - 208,209 + 217,218 Unconfirmed count dashboard.unconfirmed @@ -3319,6 +3382,7 @@ Hashrate & Difficulty + Rată hash & Dificultate src/app/components/graphs/graphs.component.html 15,16 @@ -3327,6 +3391,7 @@ Lightning + Lightning src/app/components/graphs/graphs.component.html 31 @@ -3335,6 +3400,7 @@ Lightning Nodes Per Network + Noduri Lightning Per Rețea src/app/components/graphs/graphs.component.html 34 @@ -3355,6 +3421,7 @@ Lightning Network Capacity + Capacitatea rețelei Lightning src/app/components/graphs/graphs.component.html 36 @@ -3375,6 +3442,7 @@ Lightning Nodes Per ISP + Noduri Lightning Per ISP src/app/components/graphs/graphs.component.html 38 @@ -3387,6 +3455,7 @@ Lightning Nodes Per Country + Noduri Lightning per țară src/app/components/graphs/graphs.component.html 40 @@ -3403,6 +3472,7 @@ Lightning Nodes World Map + Harta lumii cu Noduri Lightning src/app/components/graphs/graphs.component.html 42 @@ -3419,6 +3489,7 @@ Lightning Nodes Channels World Map + Harta lumii cu canale ale nodurilor Lightning src/app/components/graphs/graphs.component.html 44 @@ -3516,7 +3587,7 @@ src/app/components/master-page/master-page.component.html - 52,54 + 51,53 src/app/components/statistics/statistics.component.ts @@ -3539,9 +3610,10 @@ Lightning Explorer + Explorator Lightning src/app/components/master-page/master-page.component.html - 44,45 + 44,47 src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts @@ -3549,20 +3621,12 @@ master-page.lightning - - beta - - src/app/components/master-page/master-page.component.html - 45,48 - - beta - Documentation Documentație src/app/components/master-page/master-page.component.html - 55,57 + 54,56 src/app/docs/docs/docs.component.html @@ -3642,6 +3706,32 @@ dashboard.adjustments + + Broadcast Transaction + Transmite Tranzacție + + src/app/components/mining-dashboard/mining-dashboard.component.html + 92 + + + src/app/components/push-transaction/push-transaction.component.html + 2 + + + src/app/components/push-transaction/push-transaction.component.html + 8 + + + src/app/dashboard/dashboard.component.html + 161,169 + + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 102 + + Broadcast Transaction + shared.broadcast-transaction + Pools luck (1 week) Noroc fonduri (1 săptămână) @@ -3709,7 +3799,7 @@ src/app/components/pool-ranking/pool-ranking.component.html - 136,138 + 152,154 master-page.blocks @@ -3739,12 +3829,25 @@ mining.rank + + Avg Health + Medie Sănătate + + src/app/components/pool-ranking/pool-ranking.component.html + 96,97 + + + src/app/components/pool-ranking/pool-ranking.component.html + 96,98 + + latest-blocks.avg_health + Empty blocks Blocuri goale src/app/components/pool-ranking/pool-ranking.component.html - 95,98 + 97,100 mining.empty-blocks @@ -3753,7 +3856,7 @@ Toți minerii src/app/components/pool-ranking/pool-ranking.component.html - 113,114 + 129,130 mining.all-miners @@ -3762,7 +3865,7 @@ Noroc Fonduri (1săpt) src/app/components/pool-ranking/pool-ranking.component.html - 130,132 + 146,148 mining.miners-luck @@ -3771,7 +3874,7 @@ Număr Fonduri (1săpt) src/app/components/pool-ranking/pool-ranking.component.html - 142,144 + 158,160 mining.miners-count @@ -3780,7 +3883,7 @@ Fondurile de minerit src/app/components/pool-ranking/pool-ranking.component.ts - 57 + 58 @@ -3797,6 +3900,7 @@ mining pool + Fond de minerit src/app/components/pool/pool-preview.component.html 3,5 @@ -4006,24 +4110,6 @@ latest-blocks.coinbasetag - - Broadcast Transaction - Transmite Tranzacție - - src/app/components/push-transaction/push-transaction.component.html - 2 - - - src/app/components/push-transaction/push-transaction.component.html - 8 - - - src/app/dashboard/dashboard.component.html - 154,161 - - Broadcast Transaction - shared.broadcast-transaction - Transaction hex Codul hex al tranzacției @@ -4033,7 +4119,7 @@ src/app/components/transaction/transaction.component.html - 296,297 + 290,291 transaction.hex @@ -4065,6 +4151,7 @@ Avg Block Fees + Comisioane medii de bloc src/app/components/reward-stats/reward-stats.component.html 17 @@ -4077,6 +4164,7 @@ Average fees per block in the past 144 blocks + Comioane medii per bloc în ultimele 144 de blocuri src/app/components/reward-stats/reward-stats.component.html 18,20 @@ -4085,6 +4173,7 @@ BTC/block + BTC/bloc src/app/components/reward-stats/reward-stats.component.html 21,24 @@ -4094,6 +4183,7 @@ Avg Tx Fee + Comision mediu per Tx src/app/components/reward-stats/reward-stats.component.html 30 @@ -4138,6 +4228,7 @@ Explore the full Bitcoin ecosystem + Explorați întregul ecosistem Bitcoin src/app/components/search-form/search-form.component.html 4,5 @@ -4153,6 +4244,78 @@ search-form.search-title + + Bitcoin Block Height + Blocul Bitcoin Curent + + src/app/components/search-form/search-results/search-results.component.html + 3 + + search.bitcoin-block-height + + + Bitcoin Transaction + Tranzacția Bitcoin + + src/app/components/search-form/search-results/search-results.component.html + 9 + + search.bitcoin-transaction + + + Bitcoin Address + Adresa Bitcoin + + src/app/components/search-form/search-results/search-results.component.html + 15 + + search.bitcoin-address + + + Bitcoin Block + Blocul Bitcoin + + src/app/components/search-form/search-results/search-results.component.html + 21 + + search.bitcoin-block + + + Bitcoin Addresses + Adrese Bitcoin + + src/app/components/search-form/search-results/search-results.component.html + 27 + + search.bitcoin-addresses + + + Lightning Nodes + Noduri Lightning + + src/app/components/search-form/search-results/search-results.component.html + 35 + + search.lightning-nodes + + + Lightning Channels + Canale Lightning + + src/app/components/search-form/search-results/search-results.component.html + 43 + + search.lightning-channels + + + Go to "" + Mergi la &quot;&quot; + + src/app/components/search-form/search-results/search-results.component.html + 52 + + search.go-to + Mempool by vBytes (sat/vByte) Mempool prin vBytes (sat/vByte) @@ -4410,6 +4573,7 @@ This transaction replaced: + Această tranzacție a înlocuit: src/app/components/transaction/transaction.component.html 10,12 @@ -4419,6 +4583,7 @@ Replaced + Înlocuit src/app/components/transaction/transaction.component.html 36,39 @@ -4435,7 +4600,7 @@ src/app/components/transactions-list/transactions-list.component.html - 298,301 + 300,303 Transaction unconfirmed state transaction.unconfirmed @@ -4445,7 +4610,7 @@ Prima dată văzut src/app/components/transaction/transaction.component.html - 108,109 + 102,103 src/app/lightning/node/node.component.html @@ -4479,7 +4644,7 @@ ETA src/app/components/transaction/transaction.component.html - 115,116 + 109,110 Transaction ETA transaction.eta @@ -4489,7 +4654,7 @@ În câteva ore (sau mai mult) src/app/components/transaction/transaction.component.html - 121,124 + 115,118 Transaction ETA in several hours or more transaction.eta.in-several-hours @@ -4499,11 +4664,11 @@ Descendent src/app/components/transaction/transaction.component.html - 168,170 + 162,164 src/app/components/transaction/transaction.component.html - 179,181 + 173,175 Descendant transaction.descendant @@ -4513,37 +4678,40 @@ Strămoş src/app/components/transaction/transaction.component.html - 190,192 + 184,186 Transaction Ancestor transaction.ancestor Flow + Flux src/app/components/transaction/transaction.component.html - 208,211 + 202,205 src/app/components/transaction/transaction.component.html - 346,350 + 340,344 Transaction flow transaction.flow Hide diagram + Ascunde diagrama src/app/components/transaction/transaction.component.html - 211,216 + 205,210 hide-diagram Show more + Arată mai multe src/app/components/transaction/transaction.component.html - 231,233 + 225,227 src/app/components/transactions-list/transactions-list.component.html @@ -4557,9 +4725,10 @@ Show less + Arată mai puțin src/app/components/transaction/transaction.component.html - 233,239 + 227,233 src/app/components/transactions-list/transactions-list.component.html @@ -4569,9 +4738,10 @@ Show diagram + Arată diagrama src/app/components/transaction/transaction.component.html - 253,254 + 247,248 show-diagram @@ -4580,7 +4750,7 @@ Locktime src/app/components/transaction/transaction.component.html - 292,294 + 286,288 transaction.locktime @@ -4589,7 +4759,7 @@ Tranzacția nu a fost găsită. src/app/components/transaction/transaction.component.html - 455,456 + 449,450 transaction.error.transaction-not-found @@ -4598,7 +4768,7 @@ Se așteaptă să apară în mempool... src/app/components/transaction/transaction.component.html - 456,461 + 450,455 transaction.error.waiting-for-it-to-appear @@ -4607,7 +4777,7 @@ Rata efectivă a comisionului src/app/components/transaction/transaction.component.html - 489,492 + 485,488 Effective transaction fee rate transaction.effective-fee-rate @@ -4753,22 +4923,25 @@ Show more inputs to reveal fee data + Arată mai multe intrări pentru a dezvălui datele despre comision src/app/components/transactions-list/transactions-list.component.html - 288,291 + 290,293 transactions-list.load-to-reveal-fee-info remaining + rămase src/app/components/transactions-list/transactions-list.component.html - 330,331 + 332,333 x-remaining other inputs + alte intrări src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html 12 @@ -4777,6 +4950,7 @@ other outputs + alte ieșiri src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html 13 @@ -4785,6 +4959,7 @@ Input + Intrare src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html 42 @@ -4797,6 +4972,7 @@ Output + Ieșire src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html 43 @@ -4809,6 +4985,7 @@ This transaction saved % on fees by using native SegWit + Această tranzacție a economisit % din comisioane utilizând SegWit nativ src/app/components/tx-features/tx-features.component.html 2 @@ -4835,6 +5012,7 @@ This transaction saved % on fees by using SegWit and could save % more by fully upgrading to native SegWit + Această tranzacție a economisit % din comisioane utilizând SegWit și ar putea economisi încă % prin trecerea la SegWit nativ src/app/components/tx-features/tx-features.component.html 4 @@ -4843,6 +5021,7 @@ This transaction could save % on fees by upgrading to native SegWit or % by upgrading to SegWit-P2SH + Această tranzacție ar putea economisi % din comisioane prin trecerea la SegWit nativ sau % prin trecerea la SegWit-P2SH src/app/components/tx-features/tx-features.component.html 6 @@ -4851,6 +5030,7 @@ This transaction uses Taproot and thereby saved at least % on fees + Această tranzacție folosește Taproot și, prin urmare, a economisit cel puțin % din comisioane src/app/components/tx-features/tx-features.component.html 12 @@ -4859,6 +5039,7 @@ Taproot + Taproot src/app/components/tx-features/tx-features.component.html 12 @@ -4884,6 +5065,7 @@ This transaction uses Taproot and already saved at least % on fees, but could save an additional % by fully using Taproot + Această tranzacție folosește Taproot și a economisit deja cel puțin % din comisioane, dar ar putea economisi încă % utilizând complet Taproot src/app/components/tx-features/tx-features.component.html 14 @@ -4892,6 +5074,7 @@ This transaction could save % on fees by using Taproot + Această tranzacție ar putea economisi % din comisioane utilizând Taproot src/app/components/tx-features/tx-features.component.html 16 @@ -4900,6 +5083,7 @@ This transaction does not use Taproot + Această tranzacție nu folosește Taproot src/app/components/tx-features/tx-features.component.html 18 @@ -4917,6 +5101,7 @@ This transaction supports Replace-By-Fee (RBF) allowing fee bumping + Această tranzacție acceptă Replace-By-Fee (RBF), permițând creșterea ulterioară a comisionului src/app/components/tx-features/tx-features.component.html 28 @@ -5001,21 +5186,12 @@ dashboard.latest-transactions - - USD - USD - - src/app/dashboard/dashboard.component.html - 126,127 - - dashboard.latest-transactions.USD - Minimum fee Comision minim src/app/dashboard/dashboard.component.html - 201,202 + 210,211 Minimum mempool fee dashboard.minimum-fee @@ -5025,7 +5201,7 @@ Înlăturare src/app/dashboard/dashboard.component.html - 202,203 + 211,212 Purgin below fee dashboard.purging @@ -5035,7 +5211,7 @@ Utilizarea memoriei src/app/dashboard/dashboard.component.html - 214,215 + 223,224 Memory usage dashboard.memory-usage @@ -5045,16 +5221,25 @@ L-BTC în circulație src/app/dashboard/dashboard.component.html - 228,230 + 237,239 dashboard.lbtc-pegs-in-circulation + + mempool.space merely provides data about the Bitcoin network. It cannot help you with retrieving funds, confirming your transaction quicker, etc. + mempool.space oferă doar date despre rețeaua Bitcoin. Nu vă poate ajuta să recuperați fonduri, să confirmați tranzacția mai rapid etc. + + src/app/docs/api-docs/api-docs.component.html + 13 + + faq.big-disclaimer + REST API service Serviciu REST API src/app/docs/api-docs/api-docs.component.html - 39,40 + 41,42 api-docs.title @@ -5063,11 +5248,11 @@ Terminație src/app/docs/api-docs/api-docs.component.html - 48,49 + 50,51 src/app/docs/api-docs/api-docs.component.html - 102,105 + 104,107 Api docs endpoint @@ -5076,11 +5261,11 @@ Descriere src/app/docs/api-docs/api-docs.component.html - 67,68 + 69,70 src/app/docs/api-docs/api-docs.component.html - 106,107 + 108,109 @@ -5088,7 +5273,7 @@ Trimitere implicită: acțiune: 'want', data: ['blocks', ...] pentru a exprima ce dorești să trimiți. Disponibil: blocks, mempool-blocks, live-2h-chart, și stats.Tranzacții de trimitere pentru adresa: 'track-address': '3PbJ...bF9B' pentru a primi toate tranzacțiile noi care conțin acea adresă ca intrare sau iesire. Returnează un șir de tranzacții. address-transactions pentru tranzacții noi din mempool, și block-transactions pentru tranzacții confirmate din blocuri noi. src/app/docs/api-docs/api-docs.component.html - 107,108 + 109,110 api-docs.websocket.websocket @@ -5157,6 +5342,7 @@ Base fee + Comision de bază src/app/lightning/channel/channel-box/channel-box.component.html 29 @@ -5169,6 +5355,7 @@ mSats + mSats src/app/lightning/channel/channel-box/channel-box.component.html 35 @@ -5189,6 +5376,7 @@ This channel supports zero base fee routing + Acest canal acceptă rutarea cu comision de bază zero src/app/lightning/channel/channel-box/channel-box.component.html 44 @@ -5197,6 +5385,7 @@ Zero base fee + Comision de bază zero src/app/lightning/channel/channel-box/channel-box.component.html 45 @@ -5205,6 +5394,7 @@ This channel does not support zero base fee routing + Acest canal nu acceptă rutarea cu comision de bază zero src/app/lightning/channel/channel-box/channel-box.component.html 50 @@ -5213,6 +5403,7 @@ Non-zero base fee + Comision de bază diferit de zero src/app/lightning/channel/channel-box/channel-box.component.html 51 @@ -5221,6 +5412,7 @@ Min HTLC + Min HTLC src/app/lightning/channel/channel-box/channel-box.component.html 57 @@ -5229,6 +5421,7 @@ Max HTLC + Max HTLC src/app/lightning/channel/channel-box/channel-box.component.html 63 @@ -5237,6 +5430,7 @@ Timelock delta + Diferență Timelock src/app/lightning/channel/channel-box/channel-box.component.html 69 @@ -5245,18 +5439,20 @@ channels + canale src/app/lightning/channel/channel-box/channel-box.component.html 79 src/app/lightning/channels-list/channels-list.component.html - 120,121 + 123,124 lightning.x-channels Starting balance + Balanța inițială src/app/lightning/channel/channel-close-box/channel-close-box.component.html 6 @@ -5266,6 +5462,7 @@ Closing balance + Balanța finală src/app/lightning/channel/channel-close-box/channel-close-box.component.html 12 @@ -5275,6 +5472,7 @@ lightning channel + canal lightning src/app/lightning/channel/channel-preview.component.html 3,5 @@ -5283,6 +5481,7 @@ Inactive + Inactiv src/app/lightning/channel/channel-preview.component.html 10,11 @@ -5293,12 +5492,13 @@ src/app/lightning/channels-list/channels-list.component.html - 65,66 + 68,69 status.inactive Active + Activ src/app/lightning/channel/channel-preview.component.html 11,12 @@ -5309,12 +5509,13 @@ src/app/lightning/channels-list/channels-list.component.html - 66,68 + 69,71 status.active Closed + Închis src/app/lightning/channel/channel-preview.component.html 12,14 @@ -5329,12 +5530,13 @@ src/app/lightning/channels-list/channels-list.component.html - 68,70 + 71,73 status.closed Created + Creat src/app/lightning/channel/channel-preview.component.html 23,26 @@ -5347,6 +5549,7 @@ Capacity + Capacitate src/app/lightning/channel/channel-preview.component.html 27,28 @@ -5357,7 +5560,7 @@ src/app/lightning/channels-list/channels-list.component.html - 40,43 + 43,46 src/app/lightning/node-statistics/node-statistics.component.html @@ -5365,7 +5568,7 @@ src/app/lightning/node-statistics/node-statistics.component.html - 47,50 + 46,49 src/app/lightning/nodes-list/nodes-list.component.html @@ -5399,6 +5602,7 @@ ppm + ppm src/app/lightning/channel/channel-preview.component.html 34,35 @@ -5419,6 +5623,7 @@ Lightning channel + Canal lightning src/app/lightning/channel/channel.component.html 2,5 @@ -5431,6 +5636,7 @@ Last update + Ultima actualizare src/app/lightning/channel/channel.component.html 33,34 @@ -5463,18 +5669,20 @@ Closing date + Data limită src/app/lightning/channel/channel.component.html 37,38 src/app/lightning/channels-list/channels-list.component.html - 39,40 + 42,43 lightning.closing_date Closed by + Închis de src/app/lightning/channel/channel.component.html 52,54 @@ -5483,6 +5691,7 @@ Opening transaction + Tranzacția inițială src/app/lightning/channel/channel.component.html 84,85 @@ -5491,6 +5700,7 @@ Closing transaction + Tranzacția finală src/app/lightning/channel/channel.component.html 93,95 @@ -5499,13 +5709,39 @@ Channel: + Canal: src/app/lightning/channel/channel.component.ts 37 + + Mutually closed + Închis reciproc + + src/app/lightning/channel/closing-type/closing-type.component.ts + 20 + + + + Force closed + Închis forțat + + src/app/lightning/channel/closing-type/closing-type.component.ts + 24 + + + + Force closed with penalty + Închis forțat cu penalizare + + src/app/lightning/channel/closing-type/closing-type.component.ts + 28 + + Open + Deschis src/app/lightning/channels-list/channels-list.component.html 5,7 @@ -5514,17 +5750,19 @@ No channels to display + Nu există canale de afișat src/app/lightning/channels-list/channels-list.component.html - 29,35 + 29,37 lightning.empty-channels-list Alias + Alias src/app/lightning/channels-list/channels-list.component.html - 35,37 + 38,40 src/app/lightning/group/group.component.html @@ -5558,29 +5796,32 @@ Status + Stare src/app/lightning/channels-list/channels-list.component.html - 37,38 + 40,41 status Channel ID + ID Canal src/app/lightning/channels-list/channels-list.component.html - 41,45 + 44,48 channels.id sats + sats src/app/lightning/channels-list/channels-list.component.html - 60,64 + 63,67 src/app/lightning/channels-list/channels-list.component.html - 84,88 + 87,91 src/app/lightning/channels-statistics/channels-statistics.component.html @@ -5624,8 +5865,27 @@ shared.sats + + avg + avg + + src/app/lightning/channels-statistics/channels-statistics.component.html + 3,5 + + statistics.average-small + + + med + med + + src/app/lightning/channels-statistics/channels-statistics.component.html + 6,9 + + statistics.median-small + Avg Capacity + Capacitate medie src/app/lightning/channels-statistics/channels-statistics.component.html 13,15 @@ -5638,6 +5898,7 @@ Avg Fee Rate + Rata medie comision src/app/lightning/channels-statistics/channels-statistics.component.html 26,28 @@ -5650,6 +5911,7 @@ The average fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm + Comisionul mediu perceput de nodurile de rutare, ignorând valori > 0,5% sau 5000 ppm src/app/lightning/channels-statistics/channels-statistics.component.html 28,30 @@ -5658,6 +5920,7 @@ Avg Base Fee + Comision de bază mediu src/app/lightning/channels-statistics/channels-statistics.component.html 41,43 @@ -5670,6 +5933,7 @@ The average base fee charged by routing nodes, ignoring base fees > 5000ppm + Comision de bază mediu perceput de nodurile de rutare, ignorând valori > 5000 ppm src/app/lightning/channels-statistics/channels-statistics.component.html 43,45 @@ -5678,6 +5942,7 @@ Med Capacity + Capacitate medie src/app/lightning/channels-statistics/channels-statistics.component.html 59,61 @@ -5686,6 +5951,7 @@ Med Fee Rate + Rata mediană comision src/app/lightning/channels-statistics/channels-statistics.component.html 72,74 @@ -5694,6 +5960,7 @@ The median fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm + Rata mediană a comisionului perceput de nodurile de rutare, ignorând valori > 0,5% sau 5000 ppm src/app/lightning/channels-statistics/channels-statistics.component.html 74,76 @@ -5702,6 +5969,7 @@ Med Base Fee + Comision de bază median src/app/lightning/channels-statistics/channels-statistics.component.html 87,89 @@ -5710,6 +5978,7 @@ The median base fee charged by routing nodes, ignoring base fees > 5000ppm + Comision de bază median perceput de nodurile de rutare, ignorând valori > 5000 ppm src/app/lightning/channels-statistics/channels-statistics.component.html 89,91 @@ -5718,6 +5987,7 @@ Lightning node group + Grup de noduri Lightning src/app/lightning/group/group-preview.component.html 3,5 @@ -5730,6 +6000,7 @@ Nodes + Noduri src/app/lightning/group/group-preview.component.html 25,29 @@ -5740,11 +6011,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 17,18 + 16,17 src/app/lightning/node-statistics/node-statistics.component.html - 54,57 + 53,56 src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html @@ -5766,6 +6037,7 @@ Liquidity + Lichiditate src/app/lightning/group/group-preview.component.html 29,31 @@ -5802,6 +6074,7 @@ Channels + Canale src/app/lightning/group/group-preview.component.html 40,43 @@ -5812,11 +6085,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 29,30 + 28,29 src/app/lightning/node-statistics/node-statistics.component.html - 61,64 + 60,63 src/app/lightning/nodes-list/nodes-list.component.html @@ -5862,6 +6135,7 @@ Average size + Mărime medie src/app/lightning/group/group-preview.component.html 44,46 @@ -5874,6 +6148,7 @@ Location + Locație src/app/lightning/group/group.component.html 74,77 @@ -5914,6 +6189,7 @@ Network Statistics + Statistici Rețea src/app/lightning/lightning-dashboard/lightning-dashboard.component.html 10 @@ -5922,6 +6198,7 @@ Channels Statistics + Statistici Canale src/app/lightning/lightning-dashboard/lightning-dashboard.component.html 24 @@ -5930,6 +6207,7 @@ Lightning Network History + Istoric Rețea Lightning src/app/lightning/lightning-dashboard/lightning-dashboard.component.html 49 @@ -5938,6 +6216,7 @@ Liquidity Ranking + Clasament Lichiditate src/app/lightning/lightning-dashboard/lightning-dashboard.component.html 62 @@ -5954,6 +6233,7 @@ Connectivity Ranking + Clasament Conectivitate src/app/lightning/lightning-dashboard/lightning-dashboard.component.html 76 @@ -5966,30 +6246,57 @@ Fee distribution + Distribuție Comisioane src/app/lightning/node-fee-chart/node-fee-chart.component.html 2 lightning.node-fee-distribution + + Outgoing Fees + Comisioane Ieșiri + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 170 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 208 + + + + Incoming Fees + Comisioane Intrări + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 178 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 222 + + Percentage change past week + Modificare procentuală săptămâna trecută src/app/lightning/node-statistics/node-statistics.component.html 5,7 src/app/lightning/node-statistics/node-statistics.component.html - 18,20 + 17,19 src/app/lightning/node-statistics/node-statistics.component.html - 30,32 + 29,31 mining.percentage-change-last-week Lightning node + Nod Lightning src/app/lightning/node/node-preview.component.html 3,5 @@ -6006,6 +6313,7 @@ Active capacity + Capacitate activă src/app/lightning/node/node-preview.component.html 20,22 @@ -6018,6 +6326,7 @@ Active channels + Canale active src/app/lightning/node/node-preview.component.html 26,30 @@ -6030,6 +6339,7 @@ Country + Țară src/app/lightning/node/node-preview.component.html 44,47 @@ -6038,6 +6348,7 @@ No node found for public key "" + Nu a fost găsit niciun nod pentru cheia publică &quot; &quot; src/app/lightning/node/node.component.html 17,19 @@ -6046,6 +6357,7 @@ Average channel size + Dimensiunea medie a canalului src/app/lightning/node/node.component.html 40,43 @@ -6054,6 +6366,7 @@ Avg channel distance + Distanța medie a canalului src/app/lightning/node/node.component.html 56,57 @@ -6062,6 +6375,7 @@ Color + Culoare src/app/lightning/node/node.component.html 79,81 @@ -6070,6 +6384,7 @@ ISP + ISP src/app/lightning/node/node.component.html 86,87 @@ -6082,6 +6397,7 @@ Exclusively on Tor + Exclusiv pe Tor src/app/lightning/node/node.component.html 93,95 @@ -6090,6 +6406,7 @@ Liquidity ad + Anunț de lichiditate src/app/lightning/node/node.component.html 138,141 @@ -6098,6 +6415,7 @@ Lease fee rate + Rata comisionului de închiriere src/app/lightning/node/node.component.html 144,147 @@ -6107,6 +6425,7 @@ Lease base fee + Comisionul de inchiriere de bază src/app/lightning/node/node.component.html 152,154 @@ -6115,6 +6434,7 @@ Funding weight + Greutatea finanțării src/app/lightning/node/node.component.html 158,159 @@ -6123,6 +6443,7 @@ Channel fee rate + Comisionul canalului src/app/lightning/node/node.component.html 168,171 @@ -6132,6 +6453,7 @@ Channel base fee + Comisionul de bază al canalului src/app/lightning/node/node.component.html 176,178 @@ -6140,6 +6462,7 @@ Compact lease + Închiriere compactă src/app/lightning/node/node.component.html 188,190 @@ -6148,6 +6471,7 @@ TLV extension records + Înregistrări extensiil TLV src/app/lightning/node/node.component.html 199,202 @@ -6156,6 +6480,7 @@ Open channels + Canale deschise src/app/lightning/node/node.component.html 240,243 @@ -6164,6 +6489,7 @@ Closed channels + Canale închise src/app/lightning/node/node.component.html 244,247 @@ -6172,6 +6498,7 @@ Node: + Nod: src/app/lightning/node/node.component.ts 60 @@ -6179,6 +6506,7 @@ (Tor nodes excluded) + (Nodurile Tor excluse) src/app/lightning/nodes-channels-map/nodes-channels-map.component.html 8,11 @@ -6199,6 +6527,7 @@ Lightning Nodes Channels World Map + Harta lumii cu canalele nodurilor Lightning src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts 69 @@ -6206,13 +6535,15 @@ No geolocation data available + Nu sunt disponibile date de geolocalizare src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts - 218,213 + 219,214 Active channels map + Harta canalelor active src/app/lightning/nodes-channels/node-channels.component.html 2,3 @@ -6221,6 +6552,7 @@ Indexing in progress + Indexare în curs src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts 121,116 @@ -6232,6 +6564,7 @@ Reachable on Clearnet Only + Accesibil numai pe Clearnet src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts 164,161 @@ -6243,6 +6576,7 @@ Reachable on Clearnet and Darknet + Accesibil pe Clearnet și Darknet src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts 185,182 @@ -6254,6 +6588,7 @@ Reachable on Darknet Only + Accesibil numai pe Darknet src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts 206,203 @@ -6265,6 +6600,7 @@ Share + Partajează src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html 29,31 @@ -6277,6 +6613,7 @@ nodes + noduri src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts 103,102 @@ -6292,6 +6629,7 @@ BTC capacity + capacitate BTC src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts 104,102 @@ -6299,6 +6637,7 @@ Lightning nodes in + Noduri Lightning în src/app/lightning/nodes-per-country/nodes-per-country.component.html 3,4 @@ -6307,6 +6646,7 @@ ISP Count + Număr ISP src/app/lightning/nodes-per-country/nodes-per-country.component.html 34,38 @@ -6315,6 +6655,7 @@ Top ISP + Top ISP src/app/lightning/nodes-per-country/nodes-per-country.component.html 38,40 @@ -6323,6 +6664,7 @@ Lightning nodes in + Noduri Lightning în src/app/lightning/nodes-per-country/nodes-per-country.component.ts 35 @@ -6330,6 +6672,7 @@ Clearnet Capacity + Capacitate Clearnet src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 6,8 @@ -6342,6 +6685,7 @@ How much liquidity is running on nodes advertising at least one clearnet IP address + Câtă lichiditate există pe nodurile care anunță cel puțin o adresă IP din Clearnet src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 8,9 @@ -6350,6 +6694,7 @@ Unknown Capacity + Capacitate necunoscută src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 13,15 @@ -6362,6 +6707,7 @@ How much liquidity is running on nodes which ISP was not identifiable + Câtă lichiditate există pe noduri pe care ISP-ul nu a fost identificabil src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 15,16 @@ -6370,6 +6716,7 @@ Tor Capacity + Capacitate Tor src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 20,22 @@ -6382,6 +6729,7 @@ How much liquidity is running on nodes advertising only Tor addresses + Câtă lichiditate există pe nodurile care anunță numai adrese Tor src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 22,23 @@ -6390,6 +6738,7 @@ Top 100 ISPs hosting LN nodes + Top 100 ISP-uri care găzduiesc noduri LN src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html 31,33 @@ -6398,6 +6747,7 @@ BTC + BTC src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts 158,156 @@ -6409,6 +6759,7 @@ Lightning ISP + Lightning ISP src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.html 3,5 @@ -6417,6 +6768,7 @@ Top country + Țara de top src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.html 39,41 @@ -6429,6 +6781,7 @@ Top node + Nodul de top src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.html 45,48 @@ -6437,6 +6790,7 @@ Lightning nodes on ISP: [AS] + Noduri Lightning pe ISP: [CA] src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.ts 44 @@ -6448,6 +6802,7 @@ Lightning nodes on ISP: + Noduri Lightning pe ISP: src/app/lightning/nodes-per-isp/nodes-per-isp.component.html 2,4 @@ -6456,6 +6811,7 @@ ASN + ASN src/app/lightning/nodes-per-isp/nodes-per-isp.component.html 11,14 @@ -6464,6 +6820,7 @@ Active nodes + Noduri active src/app/lightning/nodes-per-isp/nodes-per-isp.component.html 14,18 @@ -6472,6 +6829,7 @@ Top 100 oldest lightning nodes + Top 100 cele mai vechi noduri lightning src/app/lightning/nodes-ranking/oldest-nodes/oldest-nodes.component.html 3,7 @@ -6480,6 +6838,7 @@ Oldest lightning nodes + Cele mai vechi noduri lightning src/app/lightning/nodes-ranking/oldest-nodes/oldest-nodes.component.ts 27 @@ -6487,6 +6846,7 @@ Top 100 nodes liquidity ranking + Top 100 de noduri de lichiditate src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.html 3,7 @@ -6495,6 +6855,7 @@ Top 100 nodes connectivity ranking + Top 100 de noduri de conectivitate src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.html 3,7 @@ -6503,6 +6864,7 @@ Oldest nodes + Cele mai vechi noduri src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.html 36 @@ -6511,6 +6873,7 @@ Top lightning nodes + Top noduri lightning src/app/lightning/nodes-rankings-dashboard/nodes-rankings-dashboard.component.ts 22 @@ -6518,6 +6881,7 @@ Indexing in progress + Indexare în curs src/app/lightning/statistics-chart/lightning-statistics-chart.component.html 52,55 diff --git a/frontend/src/locale/messages.xlf b/frontend/src/locale/messages.xlf index a4154cbcd..3e4c29cfe 100644 --- a/frontend/src/locale/messages.xlf +++ b/frontend/src/locale/messages.xlf @@ -323,11 +323,11 @@ src/app/components/block/block.component.html - 303,304 + 310,311 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 26,27 + 46,47 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -347,11 +347,11 @@ src/app/components/block/block.component.html - 304,305 + 311,312 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 27,28 + 47,48 src/app/components/mempool-blocks/mempool-blocks.component.html @@ -550,7 +550,7 @@ src/app/components/pool-ranking/pool-ranking.component.html - 94,96 + 94,95 @@ -717,14 +717,22 @@ src/app/components/about/about.component.html 385,389 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 88 + src/app/dashboard/dashboard.component.html - 150,152 + 157,159 src/app/docs/docs/docs.component.html 51 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 97 + Terms of Service shared.terms-of-service @@ -734,14 +742,22 @@ src/app/bisq/bisq-main-dashboard/bisq-main-dashboard.component.html 113,120 + + src/app/components/mining-dashboard/mining-dashboard.component.html + 90 + src/app/dashboard/dashboard.component.html - 152,154 + 159,161 src/app/docs/docs/docs.component.html 53 + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 99 + Privacy Policy shared.privacy-policy @@ -916,7 +932,7 @@ src/app/dashboard/dashboard.component.html - 124,125 + 124,126 @@ -960,7 +976,7 @@ src/app/components/transaction/transaction.component.html - 158,160 + 152,154 src/app/components/transactions-list/transactions-list.component.html @@ -975,11 +991,11 @@ src/app/components/block/block.component.html - 245,246 + 252,253 src/app/components/transaction/transaction.component.html - 288,290 + 282,284 transaction.version @@ -1028,7 +1044,7 @@ src/app/components/transactions-list/transactions-list.component.html - 294,295 + 296,297 Transaction singular confirmation count shared.confirmation-count.singular @@ -1056,7 +1072,7 @@ src/app/components/transactions-list/transactions-list.component.html - 295,296 + 297,298 Transaction plural confirmation count shared.confirmation-count.plural @@ -1067,10 +1083,6 @@ src/app/bisq/bisq-transaction/bisq-transaction.component.html 43,45 - - src/app/components/transaction/transaction.component.html - 65,67 - Transaction included in block transaction.included-in-block @@ -1082,11 +1094,11 @@ src/app/components/transaction/transaction.component.html - 77,80 + 71,74 src/app/components/transaction/transaction.component.html - 135,138 + 129,132 Transaction features transaction.features @@ -1112,11 +1124,11 @@ src/app/components/transaction/transaction.component.html - 262,267 + 256,261 src/app/components/transaction/transaction.component.html - 406,412 + 400,406 transaction.details @@ -1132,11 +1144,11 @@ src/app/components/transaction/transaction.component.html - 249,253 + 243,247 src/app/components/transaction/transaction.component.html - 377,383 + 371,377 Transaction inputs and outputs transaction.inputs-and-outputs @@ -1153,7 +1165,7 @@ src/app/components/transaction/transaction.component.ts - 241,240 + 244,243 @@ -1171,7 +1183,7 @@ src/app/components/transaction/transaction.component.html - 159,160 + 153,154 src/app/dashboard/dashboard.component.html @@ -1186,7 +1198,7 @@ src/app/components/transaction/transaction.component.html - 72,73 + 66,67 Transaction Confirmed state transaction.confirmed @@ -1454,7 +1466,7 @@ src/app/components/amount/amount.component.html - 6,9 + 18,21 src/app/components/asset-circulation/asset-circulation.component.html @@ -1470,7 +1482,7 @@ src/app/components/transactions-list/transactions-list.component.html - 302,304 + 304,306 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -1897,7 +1909,7 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 161 + 165 @@ -1912,7 +1924,7 @@ src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 163 + 167 @@ -1923,7 +1935,7 @@ src/app/components/block-fees-graph/block-fees-graph.component.ts - 62 + 67 src/app/components/graphs/graphs.component.html @@ -1935,15 +1947,15 @@ Indexing blocks src/app/components/block-fees-graph/block-fees-graph.component.ts - 110,105 + 116,111 src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 108,103 + 113,108 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 115,110 + 116,111 src/app/components/hashrate-chart/hashrate-chart.component.ts @@ -1986,7 +1998,7 @@ src/app/components/transaction/transaction.component.html - 478 + 472 src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html @@ -2011,11 +2023,11 @@ src/app/components/transaction/transaction.component.html - 478,479 + 472 src/app/components/transactions-list/transactions-list.component.html - 286,287 + 288 sat shared.sat @@ -2028,11 +2040,11 @@ src/app/components/transaction/transaction.component.html - 161,165 + 155,159 src/app/components/transaction/transaction.component.html - 481,483 + 475,477 src/app/lightning/channel/channel-box/channel-box.component.html @@ -2061,19 +2073,19 @@ src/app/components/block/block.component.html - 123,126 + 124,127 src/app/components/block/block.component.html - 127 + 128,130 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 12,14 + 19,22 src/app/components/blockchain-blocks/blockchain-blocks.component.html - 15,17 + 30,33 src/app/components/fees-box/fees-box.component.html @@ -2113,27 +2125,27 @@ src/app/components/transaction/transaction.component.html - 173,174 + 167,168 src/app/components/transaction/transaction.component.html - 184,185 + 178,179 src/app/components/transaction/transaction.component.html - 195,196 + 189,190 src/app/components/transaction/transaction.component.html - 483,486 + 477,480 src/app/components/transaction/transaction.component.html - 494,496 + 488,490 src/app/components/transactions-list/transactions-list.component.html - 286 + 286,287 src/app/dashboard/dashboard.component.html @@ -2141,7 +2153,7 @@ src/app/dashboard/dashboard.component.html - 206,210 + 213,217 sat/vB shared.sat-vbyte @@ -2154,11 +2166,11 @@ src/app/components/transaction/transaction.component.html - 160,162 + 154,156 src/app/components/transaction/transaction.component.html - 274,277 + 268,271 Transaction Virtual Size transaction.vsize @@ -2261,7 +2273,7 @@ src/app/components/block-rewards-graph/block-rewards-graph.component.ts - 60 + 65 src/app/components/graphs/graphs.component.html @@ -2289,11 +2301,11 @@ Size src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 180,179 + 184,183 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 226,224 + 239,237 src/app/components/block/block.component.html @@ -2321,7 +2333,7 @@ src/app/components/transaction/transaction.component.html - 270,272 + 264,266 src/app/dashboard/dashboard.component.html @@ -2332,11 +2344,11 @@ Weight src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 188,187 + 192,191 src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts - 257,254 + 270,267 src/app/components/block/block-preview.component.html @@ -2348,7 +2360,18 @@ src/app/components/transaction/transaction.component.html - 278,280 + 272,274 + + + + Size per weight + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 200,199 + + + src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts + 282,279 @@ -2363,16 +2386,6 @@ shared.block-title - - - - src/app/components/block/block-preview.component.html - 11,12 - - shared.block-title - Median fee @@ -2381,7 +2394,7 @@ src/app/components/block/block.component.html - 126,127 + 127,128 src/app/components/mempool-block/mempool-block.component.html @@ -2397,11 +2410,11 @@ src/app/components/block/block.component.html - 131,133 + 138,140 src/app/components/block/block.component.html - 157,160 + 164,167 src/app/components/mempool-block/mempool-block.component.html @@ -2418,7 +2431,7 @@ src/app/components/block/block.component.html - 166,168 + 173,175 block.miner @@ -2430,7 +2443,7 @@ src/app/components/block/block.component.ts - 234 + 242 @@ -2479,6 +2492,14 @@ src/app/components/blocks-list/blocks-list.component.html 60,63 + + src/app/components/pool-ranking/pool-ranking.component.html + 121,124 + + + src/app/lightning/channel/closing-type/closing-type.component.ts + 32 + src/app/lightning/node/node.component.html 52,55 @@ -2501,7 +2522,7 @@ Fee span src/app/components/block/block.component.html - 122,123 + 123,124 src/app/components/mempool-block/mempool-block.component.html @@ -2513,7 +2534,7 @@ Based on average native segwit transaction of 140 vBytes src/app/components/block/block.component.html - 127,129 + 131,136 src/app/components/fees-box/fees-box.component.html @@ -2537,15 +2558,15 @@ Transaction fee tooltip - - Subsidy + fees: + + Subsidy + fees src/app/components/block/block.component.html - 146,149 + 153,156 src/app/components/block/block.component.html - 161,165 + 168,172 Total subsidy and fees in a block block.subsidy-and-fees @@ -2554,7 +2575,7 @@ Expected src/app/components/block/block.component.html - 209 + 216 block.expected @@ -2562,11 +2583,11 @@ beta src/app/components/block/block.component.html - 209,210 + 216,217 src/app/components/block/block.component.html - 215,217 + 222,224 beta @@ -2574,7 +2595,7 @@ Actual src/app/components/block/block.component.html - 211,215 + 218,222 block.actual @@ -2582,7 +2603,7 @@ Expected Block src/app/components/block/block.component.html - 215 + 222 block.expected-block @@ -2590,7 +2611,7 @@ Actual Block src/app/components/block/block.component.html - 224 + 231 block.actual-block @@ -2598,7 +2619,7 @@ Bits src/app/components/block/block.component.html - 249,251 + 256,258 block.bits @@ -2606,7 +2627,7 @@ Merkle root src/app/components/block/block.component.html - 253,255 + 260,262 block.merkle-root @@ -2614,7 +2635,7 @@ Difficulty src/app/components/block/block.component.html - 264,267 + 271,274 src/app/components/difficulty-adjustments-table/difficulty-adjustments-table.component.html @@ -2642,7 +2663,7 @@ Nonce src/app/components/block/block.component.html - 268,270 + 275,277 block.nonce @@ -2650,7 +2671,7 @@ Block Header Hex src/app/components/block/block.component.html - 272,273 + 279,280 block.header @@ -2658,7 +2679,7 @@ Audit src/app/components/block/block.component.html - 290,294 + 297,301 Toggle Audit block.toggle-audit @@ -2667,11 +2688,11 @@ Details src/app/components/block/block.component.html - 297,301 + 304,308 src/app/components/transaction/transaction.component.html - 254,259 + 248,253 src/app/lightning/channel/channel.component.html @@ -2692,11 +2713,11 @@ Error loading data. src/app/components/block/block.component.html - 316,318 + 323,325 src/app/components/block/block.component.html - 355,359 + 362,366 src/app/lightning/channel/channel-preview.component.html @@ -2720,7 +2741,7 @@ Why is this block empty? src/app/components/block/block.component.html - 377,383 + 384,390 block.empty-block-explanation @@ -2824,7 +2845,7 @@ src/app/dashboard/dashboard.component.html - 212,216 + 219,223 dashboard.txs @@ -3045,7 +3066,7 @@ src/app/dashboard/dashboard.component.html - 239,240 + 246,247 dashboard.incoming-transactions @@ -3057,7 +3078,7 @@ src/app/dashboard/dashboard.component.html - 242,245 + 249,252 dashboard.backend-is-synchronizing @@ -3069,7 +3090,7 @@ src/app/dashboard/dashboard.component.html - 247,252 + 254,259 vB/s shared.vbytes-per-second @@ -3082,7 +3103,7 @@ src/app/dashboard/dashboard.component.html - 210,211 + 217,218 Unconfirmed count dashboard.unconfirmed @@ -3428,6 +3449,31 @@ dashboard.adjustments + + Broadcast Transaction + + src/app/components/mining-dashboard/mining-dashboard.component.html + 92 + + + src/app/components/push-transaction/push-transaction.component.html + 2 + + + src/app/components/push-transaction/push-transaction.component.html + 8 + + + src/app/dashboard/dashboard.component.html + 161,169 + + + src/app/lightning/lightning-dashboard/lightning-dashboard.component.html + 102 + + Broadcast Transaction + shared.broadcast-transaction + Pools luck (1 week) @@ -3488,7 +3534,7 @@ src/app/components/pool-ranking/pool-ranking.component.html - 136,138 + 152,154 master-page.blocks @@ -3516,11 +3562,23 @@ mining.rank + + Avg Health + + src/app/components/pool-ranking/pool-ranking.component.html + 96,97 + + + src/app/components/pool-ranking/pool-ranking.component.html + 96,98 + + latest-blocks.avg_health + Empty blocks src/app/components/pool-ranking/pool-ranking.component.html - 95,98 + 97,100 mining.empty-blocks @@ -3528,7 +3586,7 @@ All miners src/app/components/pool-ranking/pool-ranking.component.html - 113,114 + 129,130 mining.all-miners @@ -3536,7 +3594,7 @@ Pools Luck (1w) src/app/components/pool-ranking/pool-ranking.component.html - 130,132 + 146,148 mining.miners-luck @@ -3544,7 +3602,7 @@ Pools Count (1w) src/app/components/pool-ranking/pool-ranking.component.html - 142,144 + 158,160 mining.miners-count @@ -3552,7 +3610,7 @@ Mining Pools src/app/components/pool-ranking/pool-ranking.component.ts - 57 + 58 @@ -3766,23 +3824,6 @@ latest-blocks.coinbasetag - - Broadcast Transaction - - src/app/components/push-transaction/push-transaction.component.html - 2 - - - src/app/components/push-transaction/push-transaction.component.html - 8 - - - src/app/dashboard/dashboard.component.html - 154,162 - - Broadcast Transaction - shared.broadcast-transaction - Transaction hex @@ -3791,7 +3832,7 @@ src/app/components/transaction/transaction.component.html - 296,297 + 290,291 transaction.hex @@ -3905,6 +3946,70 @@ search-form.search-title + + Bitcoin Block Height + + src/app/components/search-form/search-results/search-results.component.html + 3 + + search.bitcoin-block-height + + + Bitcoin Transaction + + src/app/components/search-form/search-results/search-results.component.html + 9 + + search.bitcoin-transaction + + + Bitcoin Address + + src/app/components/search-form/search-results/search-results.component.html + 15 + + search.bitcoin-address + + + Bitcoin Block + + src/app/components/search-form/search-results/search-results.component.html + 21 + + search.bitcoin-block + + + Bitcoin Addresses + + src/app/components/search-form/search-results/search-results.component.html + 27 + + search.bitcoin-addresses + + + Lightning Nodes + + src/app/components/search-form/search-results/search-results.component.html + 35 + + search.lightning-nodes + + + Lightning Channels + + src/app/components/search-form/search-results/search-results.component.html + 43 + + search.lightning-channels + + + Go to "" + + src/app/components/search-form/search-results/search-results.component.html + 52 + + search.go-to + Mempool by vBytes (sat/vByte) @@ -4176,7 +4281,7 @@ src/app/components/transactions-list/transactions-list.component.html - 298,301 + 300,303 Transaction unconfirmed state transaction.unconfirmed @@ -4185,7 +4290,7 @@ First seen src/app/components/transaction/transaction.component.html - 108,109 + 102,103 src/app/lightning/node/node.component.html @@ -4218,7 +4323,7 @@ ETA src/app/components/transaction/transaction.component.html - 115,116 + 109,110 Transaction ETA transaction.eta @@ -4227,7 +4332,7 @@ In several hours (or more) src/app/components/transaction/transaction.component.html - 121,124 + 115,118 Transaction ETA in several hours or more transaction.eta.in-several-hours @@ -4236,11 +4341,11 @@ Descendant src/app/components/transaction/transaction.component.html - 168,170 + 162,164 src/app/components/transaction/transaction.component.html - 179,181 + 173,175 Descendant transaction.descendant @@ -4249,7 +4354,7 @@ Ancestor src/app/components/transaction/transaction.component.html - 190,192 + 184,186 Transaction Ancestor transaction.ancestor @@ -4258,11 +4363,11 @@ Flow src/app/components/transaction/transaction.component.html - 208,211 + 202,205 src/app/components/transaction/transaction.component.html - 346,350 + 340,344 Transaction flow transaction.flow @@ -4271,7 +4376,7 @@ Hide diagram src/app/components/transaction/transaction.component.html - 211,216 + 205,210 hide-diagram @@ -4279,7 +4384,7 @@ Show more src/app/components/transaction/transaction.component.html - 231,233 + 225,227 src/app/components/transactions-list/transactions-list.component.html @@ -4295,7 +4400,7 @@ Show less src/app/components/transaction/transaction.component.html - 233,239 + 227,233 src/app/components/transactions-list/transactions-list.component.html @@ -4307,7 +4412,7 @@ Show diagram src/app/components/transaction/transaction.component.html - 253,254 + 247,248 show-diagram @@ -4315,7 +4420,7 @@ Locktime src/app/components/transaction/transaction.component.html - 292,294 + 286,288 transaction.locktime @@ -4323,7 +4428,7 @@ Transaction not found. src/app/components/transaction/transaction.component.html - 455,456 + 449,450 transaction.error.transaction-not-found @@ -4331,7 +4436,7 @@ Waiting for it to appear in the mempool... src/app/components/transaction/transaction.component.html - 456,461 + 450,455 transaction.error.waiting-for-it-to-appear @@ -4339,7 +4444,7 @@ Effective fee rate src/app/components/transaction/transaction.component.html - 491,494 + 485,488 Effective transaction fee rate transaction.effective-fee-rate @@ -4472,7 +4577,7 @@ Show more inputs to reveal fee data src/app/components/transactions-list/transactions-list.component.html - 288,291 + 290,293 transactions-list.load-to-reveal-fee-info @@ -4480,7 +4585,7 @@ remaining src/app/components/transactions-list/transactions-list.component.html - 330,331 + 332,333 x-remaining @@ -4709,19 +4814,11 @@ dashboard.latest-transactions - - USD - - src/app/dashboard/dashboard.component.html - 126,127 - - dashboard.latest-transactions.USD - Minimum fee src/app/dashboard/dashboard.component.html - 203,204 + 210,211 Minimum mempool fee dashboard.minimum-fee @@ -4730,7 +4827,7 @@ Purging src/app/dashboard/dashboard.component.html - 204,205 + 211,212 Purgin below fee dashboard.purging @@ -4739,7 +4836,7 @@ Memory usage src/app/dashboard/dashboard.component.html - 216,217 + 223,224 Memory usage dashboard.memory-usage @@ -4748,10 +4845,18 @@ L-BTC in circulation src/app/dashboard/dashboard.component.html - 230,232 + 237,239 dashboard.lbtc-pegs-in-circulation + + mempool.space merely provides data about the Bitcoin network. It cannot help you with retrieving funds, confirming your transaction quicker, etc. + + src/app/docs/api-docs/api-docs.component.html + 13 + + faq.big-disclaimer + REST API service @@ -5059,7 +5164,7 @@ src/app/lightning/node-statistics/node-statistics.component.html - 47,50 + 46,49 src/app/lightning/nodes-list/nodes-list.component.html @@ -5198,6 +5303,27 @@ 37 + + Mutually closed + + src/app/lightning/channel/closing-type/closing-type.component.ts + 20 + + + + Force closed + + src/app/lightning/channel/closing-type/closing-type.component.ts + 24 + + + + Force closed with penalty + + src/app/lightning/channel/closing-type/closing-type.component.ts + 28 + + Open @@ -5318,6 +5444,22 @@ shared.sats + + avg + + src/app/lightning/channels-statistics/channels-statistics.component.html + 3,5 + + statistics.average-small + + + med + + src/app/lightning/channels-statistics/channels-statistics.component.html + 6,9 + + statistics.median-small + Avg Capacity @@ -5434,11 +5576,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 17,18 + 16,17 src/app/lightning/node-statistics/node-statistics.component.html - 54,57 + 53,56 src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.html @@ -5506,11 +5648,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 29,30 + 28,29 src/app/lightning/node-statistics/node-statistics.component.html - 61,64 + 60,63 src/app/lightning/nodes-list/nodes-list.component.html @@ -5666,6 +5808,28 @@ lightning.node-fee-distribution + + Outgoing Fees + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 170 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 208 + + + + Incoming Fees + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 178 + + + src/app/lightning/node-fee-chart/node-fee-chart.component.ts + 222 + + Percentage change past week @@ -5674,11 +5838,11 @@ src/app/lightning/node-statistics/node-statistics.component.html - 18,20 + 17,19 src/app/lightning/node-statistics/node-statistics.component.html - 30,32 + 29,31 mining.percentage-change-last-week @@ -5902,7 +6066,7 @@ No geolocation data available src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts - 218,213 + 219,214 diff --git a/production/bitcoin.conf b/production/bitcoin.conf index 46ab41b20..501f49f50 100644 --- a/production/bitcoin.conf +++ b/production/bitcoin.conf @@ -1,6 +1,7 @@ datadir=/bitcoin server=1 txindex=1 +coinstatsindex=1 listen=1 discover=1 par=16 diff --git a/production/mempool-config.mainnet.json b/production/mempool-config.mainnet.json index 1258e62fb..cca43d7e3 100644 --- a/production/mempool-config.mainnet.json +++ b/production/mempool-config.mainnet.json @@ -11,8 +11,9 @@ "INDEXING_BLOCKS_AMOUNT": -1, "BLOCKS_SUMMARIES_INDEXING": true, "AUDIT": true, + "CPFP_INDEXING": true, "ADVANCED_GBT_AUDIT": true, - "ADVANCED_GBT_MEMPOOL": false, + "ADVANCED_GBT_MEMPOOL": true, "USE_SECOND_NODE_FOR_MINFEE": true }, "SYSLOG" : { diff --git a/production/mempool-config.signet.json b/production/mempool-config.signet.json index 3c661c39f..87f8e2650 100644 --- a/production/mempool-config.signet.json +++ b/production/mempool-config.signet.json @@ -9,7 +9,7 @@ "INDEXING_BLOCKS_AMOUNT": -1, "AUDIT": true, "ADVANCED_GBT_AUDIT": true, - "ADVANCED_GBT_MEMPOOL": false, + "ADVANCED_GBT_MEMPOOL": true, "POLL_RATE_MS": 1000 }, "SYSLOG" : { diff --git a/production/mempool-config.testnet.json b/production/mempool-config.testnet.json index 352529c6e..5c1695e62 100644 --- a/production/mempool-config.testnet.json +++ b/production/mempool-config.testnet.json @@ -9,7 +9,7 @@ "INDEXING_BLOCKS_AMOUNT": -1, "AUDIT": true, "ADVANCED_GBT_AUDIT": true, - "ADVANCED_GBT_MEMPOOL": false, + "ADVANCED_GBT_MEMPOOL": true, "POLL_RATE_MS": 1000 }, "SYSLOG" : { diff --git a/production/nginx-cache-warmer b/production/nginx-cache-warmer index db025a137..cb742caee 100755 --- a/production/nginx-cache-warmer +++ b/production/nginx-cache-warmer @@ -1,6 +1,6 @@ #!/usr/bin/env zsh hostname=$(hostname) -slugs=(`curl -sSL https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json | jq -r '.slugs[]'`) +slugs=(`curl -sSL https://${hostname}/api/v1/mining/pools/3y|jq -r -S '(.pools[].slug)'`) warm() {