Compare commits
97 Commits
v2.5.0-dev
...
hunicus/su
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9522d6ab0a | ||
|
|
a9dc5e9be4 | ||
|
|
90fa4a8f77 | ||
|
|
bdbb1dcf8e | ||
|
|
2ada9dcd40 | ||
|
|
95cc74c076 | ||
|
|
d59a31a65a | ||
|
|
38e4832b6a | ||
|
|
6b6dc9fb24 | ||
|
|
a1b6fc5a7b | ||
|
|
6ac0e887f7 | ||
|
|
bdb7e62921 | ||
|
|
445e376675 | ||
|
|
bedbd9c5d5 | ||
|
|
34236fca7c | ||
|
|
f74d651b85 | ||
|
|
41a93af89e | ||
|
|
e5b1615c61 | ||
|
|
2ef340712f | ||
|
|
3841d1e7b8 | ||
|
|
675ecc608c | ||
|
|
3625e41e97 | ||
|
|
ff8fecbd05 | ||
|
|
a91a8d2a4b | ||
|
|
83c03474a9 | ||
|
|
f55aac46f1 | ||
|
|
f1b5ee2a5f | ||
|
|
97008b9caa | ||
|
|
b3038e557c | ||
|
|
61e29bcff9 | ||
|
|
a512884b65 | ||
|
|
46fbd6aa49 | ||
|
|
fc29943d0f | ||
|
|
482a609d84 | ||
|
|
b7d869ad23 | ||
|
|
321161ede9 | ||
|
|
b5ad0895ac | ||
|
|
427cef9f9d | ||
|
|
816fb3bf01 | ||
|
|
44bbb472d3 | ||
|
|
aba49897f9 | ||
|
|
96121a86f8 | ||
|
|
ea2193a42d | ||
|
|
9e4fe40ca3 | ||
|
|
d9b4ad64bb | ||
|
|
7562407a0c | ||
|
|
0bc244b9f1 | ||
|
|
14e0d80042 | ||
|
|
5555916de3 | ||
|
|
ef09912d1b | ||
|
|
5977251a20 | ||
|
|
a4c027dc48 | ||
|
|
9f40cba914 | ||
|
|
5ba2c181b0 | ||
|
|
2fc404a55c | ||
|
|
2baa10dcef | ||
|
|
d08a318a2c | ||
|
|
96f3218ec6 | ||
|
|
57eddac7f0 | ||
|
|
af115b49aa | ||
|
|
332f9a2f5e | ||
|
|
2b3d132db6 | ||
|
|
f1361a698d | ||
|
|
34eef3553b | ||
|
|
9e4ce42b6a | ||
|
|
4c4a91ae95 | ||
|
|
93d46d5c5b | ||
|
|
8788d4f898 | ||
|
|
e28650c46c | ||
|
|
855c11f02c | ||
|
|
3f8e91bd46 | ||
|
|
6722e45109 | ||
|
|
414383638d | ||
|
|
2575b79c05 | ||
|
|
c7cab4c877 | ||
|
|
85c2f0ba30 | ||
|
|
edfbede704 | ||
|
|
5f60cb821a | ||
|
|
8486c1117d | ||
|
|
ad3785ff41 | ||
|
|
61f24562fd | ||
|
|
28de93d0ff | ||
|
|
1fd85b729d | ||
|
|
5681ae3f5c | ||
|
|
9d9e0976ae | ||
|
|
6180837636 | ||
|
|
17beaf7d4f | ||
|
|
ce8f471b27 | ||
|
|
b3e36fdd99 | ||
|
|
f971ddf1fa | ||
|
|
c0c37922c3 | ||
|
|
1eb9e58331 | ||
|
|
f8a35a110c | ||
|
|
c4d13fb5b7 | ||
|
|
ccab8b16bf | ||
|
|
7970f4ae88 | ||
|
|
96a41400f4 |
@@ -30,6 +30,8 @@ Mempool can be conveniently installed on the following full-node distros:
|
|||||||
|
|
||||||
Mempool can be installed in other ways too, but we only recommend doing so if you're a developer, have experience managing servers, or otherwise know what you're doing.
|
Mempool can be installed in other ways too, but we only recommend doing so if you're a developer, have experience managing servers, or otherwise know what you're doing.
|
||||||
|
|
||||||
|
**We only provide support for advanced installation methods to <a href="https://mempool.space/enterprise">Enterprise sponsors</a>.**
|
||||||
|
|
||||||
- See the [`docker/`](./docker/) directory for instructions on deploying Mempool with Docker.
|
- See the [`docker/`](./docker/) directory for instructions on deploying Mempool with Docker.
|
||||||
- See the [`backend/`](./backend/) and [`frontend/`](./frontend/) directories for manual install instructions oriented for developers.
|
- See the [`backend/`](./backend/) and [`frontend/`](./frontend/) directories for manual install instructions oriented for developers.
|
||||||
- See the [`production/`](./production/) directory for guidance on setting up a more serious Mempool instance designed for high performance at scale.
|
- See the [`production/`](./production/) directory for guidance on setting up a more serious Mempool instance designed for high performance at scale.
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
These instructions are mostly intended for developers.
|
These instructions are mostly intended for developers.
|
||||||
|
|
||||||
If you choose to use these instructions for a production setup, be aware that you will still probably need to do additional configuration for your specific OS, environment, use-case, etc. We do our best here to provide a good starting point, but only proceed if you know what you're doing. Mempool does not provide support for custom setups.
|
If you choose to use these instructions for a production setup, be aware that you will still probably need to do additional configuration for your specific OS, environment, use-case, etc. We do our best here to provide a good starting point, but only proceed if you know what you're doing.
|
||||||
|
|
||||||
|
**We only provide support for this installation method to <a href="https://mempool.space/enterprise">Enterprise sponsors</a>.**
|
||||||
|
|
||||||
See other ways to set up Mempool on [the main README](/../../#installation-methods).
|
See other ways to set up Mempool on [the main README](/../../#installation-methods).
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,8 @@
|
|||||||
"TLS_ENABLED": true
|
"TLS_ENABLED": true
|
||||||
},
|
},
|
||||||
"ESPLORA": {
|
"ESPLORA": {
|
||||||
"REST_API_URL": "http://127.0.0.1:3000"
|
"REST_API_URL": "http://127.0.0.1:3000",
|
||||||
|
"UNIX_SOCKET_PATH": "/tmp/esplora-bitcoin-mainnet"
|
||||||
},
|
},
|
||||||
"SECOND_CORE_RPC": {
|
"SECOND_CORE_RPC": {
|
||||||
"HOST": "127.0.0.1",
|
"HOST": "127.0.0.1",
|
||||||
|
|||||||
6631
backend/package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mempool-backend",
|
"name": "mempool-backend",
|
||||||
"version": "2.5.0-dev",
|
"version": "2.6.0-dev",
|
||||||
"description": "Bitcoin mempool visualizer and blockchain explorer backend",
|
"description": "Bitcoin mempool visualizer and blockchain explorer backend",
|
||||||
"license": "GNU Affero General Public License v3.0",
|
"license": "GNU Affero General Public License v3.0",
|
||||||
"homepage": "https://mempool.space",
|
"homepage": "https://mempool.space",
|
||||||
@@ -34,35 +34,35 @@
|
|||||||
"prettier": "./node_modules/.bin/prettier --write \"src/**/*.{js,ts}\""
|
"prettier": "./node_modules/.bin/prettier --write \"src/**/*.{js,ts}\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.20.12",
|
"@babel/core": "^7.21.3",
|
||||||
"@mempool/electrum-client": "^1.1.7",
|
"@mempool/electrum-client": "1.1.9",
|
||||||
"@types/node": "^16.18.11",
|
"@types/node": "^18.15.3",
|
||||||
"axios": "~0.27.2",
|
"axios": "~0.27.2",
|
||||||
"bitcoinjs-lib": "~6.1.0",
|
"bitcoinjs-lib": "~6.1.0",
|
||||||
"crypto-js": "~4.1.1",
|
"crypto-js": "~4.1.1",
|
||||||
"express": "~4.18.2",
|
"express": "~4.18.2",
|
||||||
"maxmind": "~4.3.8",
|
"maxmind": "~4.3.8",
|
||||||
"mysql2": "~2.3.3",
|
"mysql2": "~3.2.0",
|
||||||
"node-worker-threads-pool": "~1.5.1",
|
"node-worker-threads-pool": "~1.5.1",
|
||||||
"socks-proxy-agent": "~7.0.0",
|
"socks-proxy-agent": "~7.0.0",
|
||||||
"typescript": "~4.7.4",
|
"typescript": "~4.7.4",
|
||||||
"ws": "~8.11.0"
|
"ws": "~8.13.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.7",
|
"@babel/core": "^7.21.3",
|
||||||
"@babel/code-frame": "^7.18.6",
|
"@babel/code-frame": "^7.18.6",
|
||||||
"@types/compression": "^1.7.2",
|
"@types/compression": "^1.7.2",
|
||||||
"@types/crypto-js": "^4.1.1",
|
"@types/crypto-js": "^4.1.1",
|
||||||
"@types/express": "^4.17.15",
|
"@types/express": "^4.17.15",
|
||||||
"@types/jest": "^29.2.5",
|
"@types/jest": "^29.5.0",
|
||||||
"@types/ws": "~8.5.4",
|
"@types/ws": "~8.5.4",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.48.1",
|
"@typescript-eslint/eslint-plugin": "^5.55.0",
|
||||||
"@typescript-eslint/parser": "^5.48.1",
|
"@typescript-eslint/parser": "^5.55.0",
|
||||||
"eslint": "^8.31.0",
|
"eslint": "^8.36.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.7.0",
|
||||||
"jest": "^29.3.1",
|
"jest": "^29.5.0",
|
||||||
"prettier": "^2.8.2",
|
"prettier": "^2.8.4",
|
||||||
"ts-jest": "^29.0.3",
|
"ts-jest": "^29.0.5",
|
||||||
"ts-node": "^10.9.1"
|
"ts-node": "^10.9.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,8 @@
|
|||||||
"TLS_ENABLED": true
|
"TLS_ENABLED": true
|
||||||
},
|
},
|
||||||
"ESPLORA": {
|
"ESPLORA": {
|
||||||
"REST_API_URL": "__ESPLORA_REST_API_URL__"
|
"REST_API_URL": "__ESPLORA_REST_API_URL__",
|
||||||
|
"UNIX_SOCKET_PATH": "__ESPLORA_UNIX_SOCKET_PATH__"
|
||||||
},
|
},
|
||||||
"SECOND_CORE_RPC": {
|
"SECOND_CORE_RPC": {
|
||||||
"HOST": "__SECOND_CORE_RPC_HOST__",
|
"HOST": "__SECOND_CORE_RPC_HOST__",
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ describe('Mempool Backend Config', () => {
|
|||||||
|
|
||||||
expect(config.ELECTRUM).toStrictEqual({ HOST: '127.0.0.1', PORT: 3306, TLS_ENABLED: true });
|
expect(config.ELECTRUM).toStrictEqual({ HOST: '127.0.0.1', PORT: 3306, TLS_ENABLED: true });
|
||||||
|
|
||||||
expect(config.ESPLORA).toStrictEqual({ REST_API_URL: 'http://127.0.0.1:3000' });
|
expect(config.ESPLORA).toStrictEqual({ REST_API_URL: 'http://127.0.0.1:3000', UNIX_SOCKET_PATH: null });
|
||||||
|
|
||||||
expect(config.CORE_RPC).toStrictEqual({
|
expect(config.CORE_RPC).toStrictEqual({
|
||||||
HOST: '127.0.0.1',
|
HOST: '127.0.0.1',
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import config from '../config';
|
import config from '../config';
|
||||||
|
import logger from '../logger';
|
||||||
import { TransactionExtended, MempoolBlockWithTransactions } from '../mempool.interfaces';
|
import { TransactionExtended, MempoolBlockWithTransactions } from '../mempool.interfaces';
|
||||||
|
|
||||||
const PROPAGATION_MARGIN = 180; // in seconds, time since a transaction is first seen after which it is assumed to have propagated to all miners
|
const PROPAGATION_MARGIN = 180; // in seconds, time since a transaction is first seen after which it is assumed to have propagated to all miners
|
||||||
@@ -39,17 +40,19 @@ class Audit {
|
|||||||
} else {
|
} else {
|
||||||
isCensored[txid] = true;
|
isCensored[txid] = true;
|
||||||
}
|
}
|
||||||
displacedWeight += mempool[txid].weight;
|
displacedWeight += mempool[txid]?.weight || 0;
|
||||||
} else {
|
} else {
|
||||||
matchedWeight += mempool[txid].weight;
|
matchedWeight += mempool[txid]?.weight || 0;
|
||||||
}
|
}
|
||||||
projectedWeight += mempool[txid].weight;
|
projectedWeight += mempool[txid]?.weight || 0;
|
||||||
inTemplate[txid] = true;
|
inTemplate[txid] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
displacedWeight += (4000 - transactions[0].weight);
|
if (transactions[0]) {
|
||||||
projectedWeight += transactions[0].weight;
|
displacedWeight += (4000 - transactions[0].weight);
|
||||||
matchedWeight += transactions[0].weight;
|
projectedWeight += transactions[0].weight;
|
||||||
|
matchedWeight += transactions[0].weight;
|
||||||
|
}
|
||||||
|
|
||||||
// we can expect an honest miner to include 'displaced' transactions in place of recent arrivals and censored txs
|
// we can expect an honest miner to include 'displaced' transactions in place of recent arrivals and censored txs
|
||||||
// these displaced transactions should occupy the first N weight units of the next projected block
|
// these displaced transactions should occupy the first N weight units of the next projected block
|
||||||
@@ -59,19 +62,24 @@ class Audit {
|
|||||||
let failures = 0;
|
let failures = 0;
|
||||||
while (projectedBlocks[1] && index < projectedBlocks[1].transactionIds.length && failures < 500) {
|
while (projectedBlocks[1] && index < projectedBlocks[1].transactionIds.length && failures < 500) {
|
||||||
const txid = projectedBlocks[1].transactionIds[index];
|
const txid = projectedBlocks[1].transactionIds[index];
|
||||||
const fits = (mempool[txid].weight - displacedWeightRemaining) < 4000;
|
const tx = mempool[txid];
|
||||||
const feeMatches = mempool[txid].effectiveFeePerVsize >= lastFeeRate;
|
if (tx) {
|
||||||
if (fits || feeMatches) {
|
const fits = (tx.weight - displacedWeightRemaining) < 4000;
|
||||||
isDisplaced[txid] = true;
|
const feeMatches = tx.effectiveFeePerVsize >= lastFeeRate;
|
||||||
if (fits) {
|
if (fits || feeMatches) {
|
||||||
lastFeeRate = Math.min(lastFeeRate, mempool[txid].effectiveFeePerVsize);
|
isDisplaced[txid] = true;
|
||||||
|
if (fits) {
|
||||||
|
lastFeeRate = Math.min(lastFeeRate, tx.effectiveFeePerVsize);
|
||||||
|
}
|
||||||
|
if (tx.firstSeen == null || (now - (tx?.firstSeen || 0)) > PROPAGATION_MARGIN) {
|
||||||
|
displacedWeightRemaining -= tx.weight;
|
||||||
|
}
|
||||||
|
failures = 0;
|
||||||
|
} else {
|
||||||
|
failures++;
|
||||||
}
|
}
|
||||||
if (mempool[txid].firstSeen == null || (now - (mempool[txid]?.firstSeen || 0)) > PROPAGATION_MARGIN) {
|
|
||||||
displacedWeightRemaining -= mempool[txid].weight;
|
|
||||||
}
|
|
||||||
failures = 0;
|
|
||||||
} else {
|
} else {
|
||||||
failures++;
|
logger.warn('projected transaction missing from mempool cache');
|
||||||
}
|
}
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
@@ -108,20 +116,25 @@ class Audit {
|
|||||||
index = projectedBlocks[0].transactionIds.length - 1;
|
index = projectedBlocks[0].transactionIds.length - 1;
|
||||||
while (index >= 0) {
|
while (index >= 0) {
|
||||||
const txid = projectedBlocks[0].transactionIds[index];
|
const txid = projectedBlocks[0].transactionIds[index];
|
||||||
if (overflowWeightRemaining > 0) {
|
const tx = mempool[txid];
|
||||||
if (isCensored[txid]) {
|
if (tx) {
|
||||||
delete isCensored[txid];
|
if (overflowWeightRemaining > 0) {
|
||||||
}
|
if (isCensored[txid]) {
|
||||||
if (mempool[txid].effectiveFeePerVsize > maxOverflowRate) {
|
delete isCensored[txid];
|
||||||
maxOverflowRate = mempool[txid].effectiveFeePerVsize;
|
}
|
||||||
rateThreshold = (Math.ceil(maxOverflowRate * 100) / 100) + 0.005;
|
if (tx.effectiveFeePerVsize > maxOverflowRate) {
|
||||||
}
|
maxOverflowRate = tx.effectiveFeePerVsize;
|
||||||
} else if (mempool[txid].effectiveFeePerVsize <= rateThreshold) { // tolerance of 0.01 sat/vb + rounding
|
rateThreshold = (Math.ceil(maxOverflowRate * 100) / 100) + 0.005;
|
||||||
if (isCensored[txid]) {
|
}
|
||||||
delete isCensored[txid];
|
} else if (tx.effectiveFeePerVsize <= rateThreshold) { // tolerance of 0.01 sat/vb + rounding
|
||||||
|
if (isCensored[txid]) {
|
||||||
|
delete isCensored[txid];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
overflowWeightRemaining -= (mempool[txid]?.weight || 0);
|
||||||
|
} else {
|
||||||
|
logger.warn('projected transaction missing from mempool cache');
|
||||||
}
|
}
|
||||||
overflowWeightRemaining -= (mempool[txid]?.weight || 0);
|
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,14 @@ import { AbstractBitcoinApi } from './bitcoin-api-abstract-factory';
|
|||||||
import { IEsploraApi } from './esplora-api.interface';
|
import { IEsploraApi } from './esplora-api.interface';
|
||||||
|
|
||||||
const axiosConnection = axios.create({
|
const axiosConnection = axios.create({
|
||||||
httpAgent: new http.Agent({ keepAlive: true })
|
httpAgent: new http.Agent({ keepAlive: true, })
|
||||||
});
|
});
|
||||||
|
|
||||||
class ElectrsApi implements AbstractBitcoinApi {
|
class ElectrsApi implements AbstractBitcoinApi {
|
||||||
axiosConfig: AxiosRequestConfig = {
|
axiosConfig: AxiosRequestConfig = config.ESPLORA.UNIX_SOCKET_PATH ? {
|
||||||
|
socketPath: config.ESPLORA.UNIX_SOCKET_PATH,
|
||||||
|
timeout: 10000,
|
||||||
|
} : {
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import config from '../config';
|
|||||||
import bitcoinApi, { bitcoinCoreApi } from './bitcoin/bitcoin-api-factory';
|
import bitcoinApi, { bitcoinCoreApi } from './bitcoin/bitcoin-api-factory';
|
||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
import memPool from './mempool';
|
import memPool from './mempool';
|
||||||
import { BlockExtended, BlockExtension, BlockSummary, PoolTag, TransactionExtended, TransactionStripped, TransactionMinerInfo } from '../mempool.interfaces';
|
import { BlockExtended, BlockExtension, BlockSummary, PoolTag, TransactionExtended, TransactionStripped, TransactionMinerInfo, CpfpSummary } from '../mempool.interfaces';
|
||||||
import { Common } from './common';
|
import { Common } from './common';
|
||||||
import diskCache from './disk-cache';
|
import diskCache from './disk-cache';
|
||||||
import transactionUtils from './transaction-utils';
|
import transactionUtils from './transaction-utils';
|
||||||
@@ -200,8 +200,15 @@ class Blocks {
|
|||||||
extras.segwitTotalWeight = 0;
|
extras.segwitTotalWeight = 0;
|
||||||
} else {
|
} else {
|
||||||
const stats: IBitcoinApi.BlockStats = await bitcoinClient.getBlockStats(block.id);
|
const stats: IBitcoinApi.BlockStats = await bitcoinClient.getBlockStats(block.id);
|
||||||
extras.medianFee = stats.feerate_percentiles[2]; // 50th percentiles
|
let feeStats = {
|
||||||
extras.feeRange = [stats.minfeerate, stats.feerate_percentiles, stats.maxfeerate].flat();
|
medianFee: stats.feerate_percentiles[2], // 50th percentiles
|
||||||
|
feeRange: [stats.minfeerate, stats.feerate_percentiles, stats.maxfeerate].flat(),
|
||||||
|
};
|
||||||
|
if (transactions?.length > 1) {
|
||||||
|
feeStats = Common.calcEffectiveFeeStatistics(transactions);
|
||||||
|
}
|
||||||
|
extras.medianFee = feeStats.medianFee;
|
||||||
|
extras.feeRange = feeStats.feeRange;
|
||||||
extras.totalFees = stats.totalfee;
|
extras.totalFees = stats.totalfee;
|
||||||
extras.avgFee = stats.avgfee;
|
extras.avgFee = stats.avgfee;
|
||||||
extras.avgFeeRate = stats.avgfeerate;
|
extras.avgFeeRate = stats.avgfeerate;
|
||||||
@@ -403,12 +410,13 @@ class Blocks {
|
|||||||
try {
|
try {
|
||||||
// Get all indexed block hash
|
// Get all indexed block hash
|
||||||
const unindexedBlockHeights = await blocksRepository.$getCPFPUnindexedBlocks();
|
const unindexedBlockHeights = await blocksRepository.$getCPFPUnindexedBlocks();
|
||||||
logger.info(`Indexing cpfp data for ${unindexedBlockHeights.length} blocks`);
|
|
||||||
|
|
||||||
if (!unindexedBlockHeights?.length) {
|
if (!unindexedBlockHeights?.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.info(`Indexing cpfp data for ${unindexedBlockHeights.length} blocks`);
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let countThisRun = 0;
|
let countThisRun = 0;
|
||||||
@@ -558,7 +566,7 @@ class Blocks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (this.currentBlockHeight < blockHeightTip) {
|
while (this.currentBlockHeight < blockHeightTip) {
|
||||||
if (this.currentBlockHeight < blockHeightTip - config.MEMPOOL.INITIAL_BLOCKS_AMOUNT) {
|
if (this.currentBlockHeight === 0) {
|
||||||
this.currentBlockHeight = blockHeightTip;
|
this.currentBlockHeight = blockHeightTip;
|
||||||
} else {
|
} else {
|
||||||
this.currentBlockHeight++;
|
this.currentBlockHeight++;
|
||||||
@@ -571,7 +579,8 @@ class Blocks {
|
|||||||
const block = BitcoinApi.convertBlock(verboseBlock);
|
const block = BitcoinApi.convertBlock(verboseBlock);
|
||||||
const txIds: string[] = await bitcoinApi.$getTxIdsForBlock(blockHash);
|
const txIds: string[] = await bitcoinApi.$getTxIdsForBlock(blockHash);
|
||||||
const transactions = await this.$getTransactionsExtended(blockHash, block.height, false);
|
const transactions = await this.$getTransactionsExtended(blockHash, block.height, false);
|
||||||
const blockExtended: BlockExtended = await this.$getBlockExtended(block, transactions);
|
const cpfpSummary: CpfpSummary = Common.calculateCpfp(block.height, transactions);
|
||||||
|
const blockExtended: BlockExtended = await this.$getBlockExtended(block, cpfpSummary.transactions);
|
||||||
const blockSummary: BlockSummary = this.summarizeBlock(verboseBlock);
|
const blockSummary: BlockSummary = this.summarizeBlock(verboseBlock);
|
||||||
|
|
||||||
// start async callbacks
|
// start async callbacks
|
||||||
@@ -581,11 +590,10 @@ class Blocks {
|
|||||||
if (!fastForwarded) {
|
if (!fastForwarded) {
|
||||||
const lastBlock = await blocksRepository.$getBlockByHeight(blockExtended.height - 1);
|
const lastBlock = await blocksRepository.$getBlockByHeight(blockExtended.height - 1);
|
||||||
if (lastBlock !== null && blockExtended.previousblockhash !== lastBlock.id) {
|
if (lastBlock !== null && blockExtended.previousblockhash !== lastBlock.id) {
|
||||||
logger.warn(`Chain divergence detected at block ${lastBlock.height}, re-indexing most recent data`);
|
logger.warn(`Chain divergence detected at block ${lastBlock.height}, re-indexing most recent data`, logger.tags.mining);
|
||||||
// We assume there won't be a reorg with more than 10 block depth
|
// We assume there won't be a reorg with more than 10 block depth
|
||||||
await BlocksRepository.$deleteBlocksFrom(lastBlock.height - 10);
|
await BlocksRepository.$deleteBlocksFrom(lastBlock.height - 10);
|
||||||
await HashratesRepository.$deleteLastEntries();
|
await HashratesRepository.$deleteLastEntries();
|
||||||
await BlocksSummariesRepository.$deleteBlocksFrom(lastBlock.height - 10);
|
|
||||||
await cpfpRepository.$deleteClustersFrom(lastBlock.height - 10);
|
await cpfpRepository.$deleteClustersFrom(lastBlock.height - 10);
|
||||||
for (let i = 10; i >= 0; --i) {
|
for (let i = 10; i >= 0; --i) {
|
||||||
const newBlock = await this.$indexBlock(lastBlock.height - i);
|
const newBlock = await this.$indexBlock(lastBlock.height - i);
|
||||||
@@ -596,7 +604,7 @@ class Blocks {
|
|||||||
}
|
}
|
||||||
await mining.$indexDifficultyAdjustments();
|
await mining.$indexDifficultyAdjustments();
|
||||||
await DifficultyAdjustmentsRepository.$deleteLastAdjustment();
|
await DifficultyAdjustmentsRepository.$deleteLastAdjustment();
|
||||||
logger.info(`Re-indexed 10 blocks and summaries. Also re-indexed the last difficulty adjustments. Will re-index latest hashrates in a few seconds.`);
|
logger.info(`Re-indexed 10 blocks and summaries. Also re-indexed the last difficulty adjustments. Will re-index latest hashrates in a few seconds.`, logger.tags.mining);
|
||||||
indexer.reindex();
|
indexer.reindex();
|
||||||
}
|
}
|
||||||
await blocksRepository.$saveBlockInDatabase(blockExtended);
|
await blocksRepository.$saveBlockInDatabase(blockExtended);
|
||||||
@@ -608,7 +616,7 @@ class Blocks {
|
|||||||
priceId: lastestPriceId,
|
priceId: lastestPriceId,
|
||||||
}]);
|
}]);
|
||||||
} else {
|
} else {
|
||||||
logger.info(`Cannot save block price for ${blockExtended.height} because the price updater hasnt completed yet. Trying again in 10 seconds.`, logger.tags.mining);
|
logger.debug(`Cannot save block price for ${blockExtended.height} because the price updater hasnt completed yet. Trying again in 10 seconds.`, logger.tags.mining);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
indexer.runSingleTask('blocksPrices');
|
indexer.runSingleTask('blocksPrices');
|
||||||
}, 10000);
|
}, 10000);
|
||||||
@@ -619,7 +627,7 @@ class Blocks {
|
|||||||
await this.$getStrippedBlockTransactions(blockExtended.id, true);
|
await this.$getStrippedBlockTransactions(blockExtended.id, true);
|
||||||
}
|
}
|
||||||
if (config.MEMPOOL.CPFP_INDEXING) {
|
if (config.MEMPOOL.CPFP_INDEXING) {
|
||||||
this.$indexCPFP(blockExtended.id, this.currentBlockHeight);
|
this.$saveCpfp(blockExtended.id, this.currentBlockHeight, cpfpSummary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -728,7 +736,7 @@ class Blocks {
|
|||||||
|
|
||||||
// Index the response if needed
|
// Index the response if needed
|
||||||
if (Common.blocksSummariesIndexingEnabled() === true) {
|
if (Common.blocksSummariesIndexingEnabled() === true) {
|
||||||
await BlocksSummariesRepository.$saveSummary({height: block.height, mined: summary});
|
await BlocksSummariesRepository.$saveTransactions(block.height, block.hash, summary.transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return summary.transactions;
|
return summary.transactions;
|
||||||
@@ -844,7 +852,7 @@ class Blocks {
|
|||||||
if (cleanBlock.fee_amt_percentiles === null) {
|
if (cleanBlock.fee_amt_percentiles === null) {
|
||||||
const block = await bitcoinClient.getBlock(cleanBlock.hash, 2);
|
const block = await bitcoinClient.getBlock(cleanBlock.hash, 2);
|
||||||
const summary = this.summarizeBlock(block);
|
const summary = this.summarizeBlock(block);
|
||||||
await BlocksSummariesRepository.$saveSummary({ height: block.height, mined: summary });
|
await BlocksSummariesRepository.$saveTransactions(cleanBlock.height, cleanBlock.hash, summary.transactions);
|
||||||
cleanBlock.fee_amt_percentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(cleanBlock.hash);
|
cleanBlock.fee_amt_percentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(cleanBlock.hash);
|
||||||
}
|
}
|
||||||
if (cleanBlock.fee_amt_percentiles !== null) {
|
if (cleanBlock.fee_amt_percentiles !== null) {
|
||||||
@@ -913,42 +921,20 @@ class Blocks {
|
|||||||
public async $indexCPFP(hash: string, height: number): Promise<void> {
|
public async $indexCPFP(hash: string, height: number): Promise<void> {
|
||||||
const block = await bitcoinClient.getBlock(hash, 2);
|
const block = await bitcoinClient.getBlock(hash, 2);
|
||||||
const transactions = block.tx.map(tx => {
|
const transactions = block.tx.map(tx => {
|
||||||
tx.vsize = tx.weight / 4;
|
|
||||||
tx.fee *= 100_000_000;
|
tx.fee *= 100_000_000;
|
||||||
return tx;
|
return tx;
|
||||||
});
|
});
|
||||||
|
|
||||||
const clusters: any[] = [];
|
const summary = Common.calculateCpfp(height, transactions);
|
||||||
|
|
||||||
let cluster: TransactionStripped[] = [];
|
await this.$saveCpfp(hash, height, summary);
|
||||||
let ancestors: { [txid: string]: boolean } = {};
|
|
||||||
for (let i = transactions.length - 1; i >= 0; i--) {
|
const effectiveFeeStats = Common.calcEffectiveFeeStatistics(summary.transactions);
|
||||||
const tx = transactions[i];
|
await blocksRepository.$saveEffectiveFeeStats(hash, effectiveFeeStats);
|
||||||
if (!ancestors[tx.txid]) {
|
}
|
||||||
let totalFee = 0;
|
|
||||||
let totalVSize = 0;
|
public async $saveCpfp(hash: string, height: number, cpfpSummary: CpfpSummary): Promise<void> {
|
||||||
cluster.forEach(tx => {
|
const result = await cpfpRepository.$batchSaveClusters(cpfpSummary.clusters);
|
||||||
totalFee += tx?.fee || 0;
|
|
||||||
totalVSize += tx.vsize;
|
|
||||||
});
|
|
||||||
const effectiveFeePerVsize = totalFee / totalVSize;
|
|
||||||
if (cluster.length > 1) {
|
|
||||||
clusters.push({
|
|
||||||
root: cluster[0].txid,
|
|
||||||
height,
|
|
||||||
txs: cluster.map(tx => { return { txid: tx.txid, weight: tx.vsize * 4, fee: tx.fee || 0 }; }),
|
|
||||||
effectiveFeePerVsize,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
cluster = [];
|
|
||||||
ancestors = {};
|
|
||||||
}
|
|
||||||
cluster.push(tx);
|
|
||||||
tx.vin.forEach(vin => {
|
|
||||||
ancestors[vin.txid] = true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const result = await cpfpRepository.$batchSaveClusters(clusters);
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
await cpfpRepository.$insertProgressMarker(height);
|
await cpfpRepository.$insertProgressMarker(height);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { CpfpInfo, MempoolBlockWithTransactions, TransactionExtended, TransactionStripped } from '../mempool.interfaces';
|
import { Ancestor, CpfpInfo, CpfpSummary, EffectiveFeeStats, MempoolBlockWithTransactions, TransactionExtended, TransactionStripped } from '../mempool.interfaces';
|
||||||
import config from '../config';
|
import config from '../config';
|
||||||
import { NodeSocket } from '../repositories/NodesSocketsRepository';
|
import { NodeSocket } from '../repositories/NodesSocketsRepository';
|
||||||
import { isIP } from 'net';
|
import { isIP } from 'net';
|
||||||
@@ -345,4 +345,99 @@ export class Common {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static calculateCpfp(height: number, transactions: TransactionExtended[]): CpfpSummary {
|
||||||
|
const clusters: { root: string, height: number, txs: Ancestor[], effectiveFeePerVsize: number }[] = [];
|
||||||
|
let cluster: TransactionExtended[] = [];
|
||||||
|
let ancestors: { [txid: string]: boolean } = {};
|
||||||
|
const txMap = {};
|
||||||
|
for (let i = transactions.length - 1; i >= 0; i--) {
|
||||||
|
const tx = transactions[i];
|
||||||
|
txMap[tx.txid] = tx;
|
||||||
|
if (!ancestors[tx.txid]) {
|
||||||
|
let totalFee = 0;
|
||||||
|
let totalVSize = 0;
|
||||||
|
cluster.forEach(tx => {
|
||||||
|
totalFee += tx?.fee || 0;
|
||||||
|
totalVSize += (tx.weight / 4);
|
||||||
|
});
|
||||||
|
const effectiveFeePerVsize = totalFee / totalVSize;
|
||||||
|
if (cluster.length > 1) {
|
||||||
|
clusters.push({
|
||||||
|
root: cluster[0].txid,
|
||||||
|
height,
|
||||||
|
txs: cluster.map(tx => { return { txid: tx.txid, weight: tx.weight, fee: tx.fee || 0 }; }),
|
||||||
|
effectiveFeePerVsize,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
cluster.forEach(tx => {
|
||||||
|
txMap[tx.txid].effectiveFeePerVsize = effectiveFeePerVsize;
|
||||||
|
});
|
||||||
|
cluster = [];
|
||||||
|
ancestors = {};
|
||||||
|
}
|
||||||
|
cluster.push(tx);
|
||||||
|
tx.vin.forEach(vin => {
|
||||||
|
ancestors[vin.txid] = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
transactions,
|
||||||
|
clusters,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static calcEffectiveFeeStatistics(transactions: { weight: number, fee: number, effectiveFeePerVsize?: number, txid: string }[]): EffectiveFeeStats {
|
||||||
|
const sortedTxs = transactions.map(tx => { return { txid: tx.txid, weight: tx.weight, rate: tx.effectiveFeePerVsize || ((tx.fee || 0) / (tx.weight / 4)) }; }).sort((a, b) => a.rate - b.rate);
|
||||||
|
|
||||||
|
let weightCount = 0;
|
||||||
|
let medianFee = 0;
|
||||||
|
let medianWeight = 0;
|
||||||
|
|
||||||
|
// calculate the "medianFee" as the average fee rate of the middle 10000 weight units of transactions
|
||||||
|
const leftBound = 1995000;
|
||||||
|
const rightBound = 2005000;
|
||||||
|
for (let i = 0; i < sortedTxs.length && weightCount < rightBound; i++) {
|
||||||
|
const left = weightCount;
|
||||||
|
const right = weightCount + sortedTxs[i].weight;
|
||||||
|
if (right > leftBound) {
|
||||||
|
const weight = Math.min(right, rightBound) - Math.max(left, leftBound);
|
||||||
|
medianFee += (sortedTxs[i].rate * (weight / 4) );
|
||||||
|
medianWeight += weight;
|
||||||
|
}
|
||||||
|
weightCount += sortedTxs[i].weight;
|
||||||
|
}
|
||||||
|
const medianFeeRate = medianWeight ? (medianFee / (medianWeight / 4)) : 0;
|
||||||
|
|
||||||
|
// minimum effective fee heuristic:
|
||||||
|
// lowest of
|
||||||
|
// a) the 1st percentile of effective fee rates
|
||||||
|
// b) the minimum effective fee rate in the last 2% of transactions (in block order)
|
||||||
|
const minFee = Math.min(
|
||||||
|
Common.getNthPercentile(1, sortedTxs).rate,
|
||||||
|
transactions.slice(-transactions.length / 50).reduce((min, tx) => { return Math.min(min, tx.effectiveFeePerVsize || ((tx.fee || 0) / (tx.weight / 4))); }, Infinity)
|
||||||
|
);
|
||||||
|
|
||||||
|
// maximum effective fee heuristic:
|
||||||
|
// highest of
|
||||||
|
// a) the 99th percentile of effective fee rates
|
||||||
|
// b) the maximum effective fee rate in the first 2% of transactions (in block order)
|
||||||
|
const maxFee = Math.max(
|
||||||
|
Common.getNthPercentile(99, sortedTxs).rate,
|
||||||
|
transactions.slice(0, transactions.length / 50).reduce((max, tx) => { return Math.max(max, tx.effectiveFeePerVsize || ((tx.fee || 0) / (tx.weight / 4))); }, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
medianFee: medianFeeRate,
|
||||||
|
feeRange: [
|
||||||
|
minFee,
|
||||||
|
[10,25,50,75,90].map(n => Common.getNthPercentile(n, sortedTxs).rate),
|
||||||
|
maxFee,
|
||||||
|
].flat(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static getNthPercentile(n: number, sortedDistribution: any[]): any {
|
||||||
|
return sortedDistribution[Math.floor((sortedDistribution.length - 1) * (n / 100))];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -497,6 +497,7 @@ class DatabaseMigration {
|
|||||||
this.uniqueLog(logger.notice, this.blocksTruncatedMessage);
|
this.uniqueLog(logger.notice, this.blocksTruncatedMessage);
|
||||||
await this.$executeQuery('DELETE FROM `pools`');
|
await this.$executeQuery('DELETE FROM `pools`');
|
||||||
await this.$executeQuery('ALTER TABLE pools AUTO_INCREMENT = 1');
|
await this.$executeQuery('ALTER TABLE pools AUTO_INCREMENT = 1');
|
||||||
|
await this.$executeQuery(`UPDATE state SET string = NULL WHERE name = 'pools_json_sha'`);
|
||||||
this.uniqueLog(logger.notice, '`pools` table has been truncated`');
|
this.uniqueLog(logger.notice, '`pools` table has been truncated`');
|
||||||
await this.updateToSchemaVersion(56);
|
await this.updateToSchemaVersion(56);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,12 +24,11 @@ export function calcDifficultyAdjustment(
|
|||||||
network: string,
|
network: string,
|
||||||
latestBlockTimestamp: number,
|
latestBlockTimestamp: number,
|
||||||
): DifficultyAdjustment {
|
): DifficultyAdjustment {
|
||||||
const ESTIMATE_LAG_BLOCKS = 146; // For first 7.2% of epoch, don't estimate.
|
|
||||||
const EPOCH_BLOCK_LENGTH = 2016; // Bitcoin mainnet
|
const EPOCH_BLOCK_LENGTH = 2016; // Bitcoin mainnet
|
||||||
const BLOCK_SECONDS_TARGET = 600; // Bitcoin mainnet
|
const BLOCK_SECONDS_TARGET = 600; // Bitcoin mainnet
|
||||||
const TESTNET_MAX_BLOCK_SECONDS = 1200; // Bitcoin testnet
|
const TESTNET_MAX_BLOCK_SECONDS = 1200; // Bitcoin testnet
|
||||||
|
|
||||||
const diffSeconds = nowSeconds - DATime;
|
const diffSeconds = Math.max(0, nowSeconds - DATime);
|
||||||
const blocksInEpoch = (blockHeight >= 0) ? blockHeight % EPOCH_BLOCK_LENGTH : 0;
|
const blocksInEpoch = (blockHeight >= 0) ? blockHeight % EPOCH_BLOCK_LENGTH : 0;
|
||||||
const progressPercent = (blockHeight >= 0) ? blocksInEpoch / EPOCH_BLOCK_LENGTH * 100 : 100;
|
const progressPercent = (blockHeight >= 0) ? blocksInEpoch / EPOCH_BLOCK_LENGTH * 100 : 100;
|
||||||
const remainingBlocks = EPOCH_BLOCK_LENGTH - blocksInEpoch;
|
const remainingBlocks = EPOCH_BLOCK_LENGTH - blocksInEpoch;
|
||||||
@@ -37,18 +36,16 @@ export function calcDifficultyAdjustment(
|
|||||||
const expectedBlocks = diffSeconds / BLOCK_SECONDS_TARGET;
|
const expectedBlocks = diffSeconds / BLOCK_SECONDS_TARGET;
|
||||||
|
|
||||||
let difficultyChange = 0;
|
let difficultyChange = 0;
|
||||||
let timeAvgSecs = diffSeconds / blocksInEpoch;
|
let timeAvgSecs = blocksInEpoch ? diffSeconds / blocksInEpoch : BLOCK_SECONDS_TARGET;
|
||||||
// Only calculate the estimate once we have 7.2% of blocks in current epoch
|
|
||||||
if (blocksInEpoch >= ESTIMATE_LAG_BLOCKS) {
|
difficultyChange = (BLOCK_SECONDS_TARGET / timeAvgSecs - 1) * 100;
|
||||||
difficultyChange = (BLOCK_SECONDS_TARGET / timeAvgSecs - 1) * 100;
|
// Max increase is x4 (+300%)
|
||||||
// Max increase is x4 (+300%)
|
if (difficultyChange > 300) {
|
||||||
if (difficultyChange > 300) {
|
difficultyChange = 300;
|
||||||
difficultyChange = 300;
|
}
|
||||||
}
|
// Max decrease is /4 (-75%)
|
||||||
// Max decrease is /4 (-75%)
|
if (difficultyChange < -75) {
|
||||||
if (difficultyChange < -75) {
|
difficultyChange = -75;
|
||||||
difficultyChange = -75;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testnet difficulty is set to 1 after 20 minutes of no blocks,
|
// Testnet difficulty is set to 1 after 20 minutes of no blocks,
|
||||||
|
|||||||
@@ -43,7 +43,9 @@ class DiskCache {
|
|||||||
const mempool = memPool.getMempool();
|
const mempool = memPool.getMempool();
|
||||||
const mempoolArray: TransactionExtended[] = [];
|
const mempoolArray: TransactionExtended[] = [];
|
||||||
for (const tx in mempool) {
|
for (const tx in mempool) {
|
||||||
mempoolArray.push(mempool[tx]);
|
if (mempool[tx] && !mempool[tx].deleteAfter) {
|
||||||
|
mempoolArray.push(mempool[tx]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Common.shuffleArray(mempoolArray);
|
Common.shuffleArray(mempoolArray);
|
||||||
@@ -162,7 +164,7 @@ class DiskCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.info('Error parsing ' + fileName + '. Skipping. Reason: ' + (e instanceof Error ? e.message : e));
|
logger.err('Error parsing ' + fileName + '. Skipping. Reason: ' + (e instanceof Error ? e.message : e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class MempoolBlocks {
|
|||||||
// Loop through and traverse all ancestors and sum up all the sizes + fees
|
// Loop through and traverse all ancestors and sum up all the sizes + fees
|
||||||
// Pass down size + fee to all unconfirmed children
|
// Pass down size + fee to all unconfirmed children
|
||||||
let sizes = 0;
|
let sizes = 0;
|
||||||
memPoolArray.forEach((tx, i) => {
|
memPoolArray.forEach((tx) => {
|
||||||
sizes += tx.weight;
|
sizes += tx.weight;
|
||||||
if (sizes > 4000000 * 8) {
|
if (sizes > 4000000 * 8) {
|
||||||
return;
|
return;
|
||||||
@@ -74,7 +74,7 @@ class MempoolBlocks {
|
|||||||
const time = end - start;
|
const time = end - start;
|
||||||
logger.debug('Mempool blocks calculated in ' + time / 1000 + ' seconds');
|
logger.debug('Mempool blocks calculated in ' + time / 1000 + ' seconds');
|
||||||
|
|
||||||
const blocks = this.calculateMempoolBlocks(memPoolArray, this.mempoolBlocks);
|
const blocks = this.calculateMempoolBlocks(memPoolArray);
|
||||||
|
|
||||||
if (saveResults) {
|
if (saveResults) {
|
||||||
const deltas = this.calculateMempoolDeltas(this.mempoolBlocks, blocks);
|
const deltas = this.calculateMempoolDeltas(this.mempoolBlocks, blocks);
|
||||||
@@ -85,26 +85,23 @@ class MempoolBlocks {
|
|||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private calculateMempoolBlocks(transactionsSorted: TransactionExtended[], prevBlocks: MempoolBlockWithTransactions[]): MempoolBlockWithTransactions[] {
|
private calculateMempoolBlocks(transactionsSorted: TransactionExtended[]): MempoolBlockWithTransactions[] {
|
||||||
const mempoolBlocks: MempoolBlockWithTransactions[] = [];
|
const mempoolBlocks: MempoolBlockWithTransactions[] = [];
|
||||||
let blockWeight = 0;
|
let blockWeight = 0;
|
||||||
let blockSize = 0;
|
|
||||||
let transactions: TransactionExtended[] = [];
|
let transactions: TransactionExtended[] = [];
|
||||||
transactionsSorted.forEach((tx) => {
|
transactionsSorted.forEach((tx) => {
|
||||||
if (blockWeight + tx.weight <= config.MEMPOOL.BLOCK_WEIGHT_UNITS
|
if (blockWeight + tx.weight <= config.MEMPOOL.BLOCK_WEIGHT_UNITS
|
||||||
|| mempoolBlocks.length === config.MEMPOOL.MEMPOOL_BLOCKS_AMOUNT - 1) {
|
|| mempoolBlocks.length === config.MEMPOOL.MEMPOOL_BLOCKS_AMOUNT - 1) {
|
||||||
blockWeight += tx.weight;
|
blockWeight += tx.weight;
|
||||||
blockSize += tx.size;
|
|
||||||
transactions.push(tx);
|
transactions.push(tx);
|
||||||
} else {
|
} else {
|
||||||
mempoolBlocks.push(this.dataToMempoolBlocks(transactions, mempoolBlocks.length));
|
mempoolBlocks.push(this.dataToMempoolBlocks(transactions));
|
||||||
blockWeight = tx.weight;
|
blockWeight = tx.weight;
|
||||||
blockSize = tx.size;
|
|
||||||
transactions = [tx];
|
transactions = [tx];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (transactions.length) {
|
if (transactions.length) {
|
||||||
mempoolBlocks.push(this.dataToMempoolBlocks(transactions, mempoolBlocks.length));
|
mempoolBlocks.push(this.dataToMempoolBlocks(transactions));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mempoolBlocks;
|
return mempoolBlocks;
|
||||||
@@ -151,7 +148,7 @@ class MempoolBlocks {
|
|||||||
// prepare a stripped down version of the mempool with only the minimum necessary data
|
// prepare a stripped down version of the mempool with only the minimum necessary data
|
||||||
// to reduce the overhead of passing this data to the worker thread
|
// to reduce the overhead of passing this data to the worker thread
|
||||||
const strippedMempool: { [txid: string]: ThreadTransaction } = {};
|
const strippedMempool: { [txid: string]: ThreadTransaction } = {};
|
||||||
Object.values(newMempool).forEach(entry => {
|
Object.values(newMempool).filter(tx => !tx.deleteAfter).forEach(entry => {
|
||||||
strippedMempool[entry.txid] = {
|
strippedMempool[entry.txid] = {
|
||||||
txid: entry.txid,
|
txid: entry.txid,
|
||||||
fee: entry.fee,
|
fee: entry.fee,
|
||||||
@@ -186,7 +183,14 @@ class MempoolBlocks {
|
|||||||
this.txSelectionWorker?.once('error', reject);
|
this.txSelectionWorker?.once('error', reject);
|
||||||
});
|
});
|
||||||
this.txSelectionWorker.postMessage({ type: 'set', mempool: strippedMempool });
|
this.txSelectionWorker.postMessage({ type: 'set', mempool: strippedMempool });
|
||||||
const { blocks, clusters } = await workerResultPromise;
|
let { blocks, clusters } = await workerResultPromise;
|
||||||
|
// filter out stale transactions
|
||||||
|
const unfilteredCount = blocks.reduce((total, block) => { return total + block.length; }, 0);
|
||||||
|
blocks = blocks.map(block => block.filter(tx => (tx.txid && tx.txid in newMempool)));
|
||||||
|
const filteredCount = blocks.reduce((total, block) => { return total + block.length; }, 0);
|
||||||
|
if (filteredCount < unfilteredCount) {
|
||||||
|
logger.warn(`tx selection worker thread returned ${unfilteredCount - filteredCount} stale transactions from makeBlockTemplates`);
|
||||||
|
}
|
||||||
|
|
||||||
// clean up thread error listener
|
// clean up thread error listener
|
||||||
this.txSelectionWorker?.removeListener('error', threadErrorListener);
|
this.txSelectionWorker?.removeListener('error', threadErrorListener);
|
||||||
@@ -228,7 +232,14 @@ class MempoolBlocks {
|
|||||||
this.txSelectionWorker?.once('error', reject);
|
this.txSelectionWorker?.once('error', reject);
|
||||||
});
|
});
|
||||||
this.txSelectionWorker.postMessage({ type: 'update', added: addedStripped, removed });
|
this.txSelectionWorker.postMessage({ type: 'update', added: addedStripped, removed });
|
||||||
const { blocks, clusters } = await workerResultPromise;
|
let { blocks, clusters } = await workerResultPromise;
|
||||||
|
// filter out stale transactions
|
||||||
|
const unfilteredCount = blocks.reduce((total, block) => { return total + block.length; }, 0);
|
||||||
|
blocks = blocks.map(block => block.filter(tx => (tx.txid && tx.txid in newMempool)));
|
||||||
|
const filteredCount = blocks.reduce((total, block) => { return total + block.length; }, 0);
|
||||||
|
if (filteredCount < unfilteredCount) {
|
||||||
|
logger.warn(`tx selection worker thread returned ${unfilteredCount - filteredCount} stale transactions from updateBlockTemplates`);
|
||||||
|
}
|
||||||
|
|
||||||
// clean up thread error listener
|
// clean up thread error listener
|
||||||
this.txSelectionWorker?.removeListener('error', threadErrorListener);
|
this.txSelectionWorker?.removeListener('error', threadErrorListener);
|
||||||
@@ -243,7 +254,7 @@ class MempoolBlocks {
|
|||||||
// update this thread's mempool with the results
|
// update this thread's mempool with the results
|
||||||
blocks.forEach(block => {
|
blocks.forEach(block => {
|
||||||
block.forEach(tx => {
|
block.forEach(tx => {
|
||||||
if (tx.txid in mempool) {
|
if (tx.txid && tx.txid in mempool) {
|
||||||
if (tx.effectiveFeePerVsize != null) {
|
if (tx.effectiveFeePerVsize != null) {
|
||||||
mempool[tx.txid].effectiveFeePerVsize = tx.effectiveFeePerVsize;
|
mempool[tx.txid].effectiveFeePerVsize = tx.effectiveFeePerVsize;
|
||||||
}
|
}
|
||||||
@@ -253,6 +264,10 @@ class MempoolBlocks {
|
|||||||
const cluster = clusters[tx.cpfpRoot];
|
const cluster = clusters[tx.cpfpRoot];
|
||||||
let matched = false;
|
let matched = false;
|
||||||
cluster.forEach(txid => {
|
cluster.forEach(txid => {
|
||||||
|
if (!txid || !mempool[txid]) {
|
||||||
|
logger.warn('projected transaction ancestor missing from mempool cache');
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (txid === tx.txid) {
|
if (txid === tx.txid) {
|
||||||
matched = true;
|
matched = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -273,15 +288,17 @@ class MempoolBlocks {
|
|||||||
mempool[tx.txid].bestDescendant = null;
|
mempool[tx.txid].bestDescendant = null;
|
||||||
}
|
}
|
||||||
mempool[tx.txid].cpfpChecked = tx.cpfpChecked;
|
mempool[tx.txid].cpfpChecked = tx.cpfpChecked;
|
||||||
|
} else {
|
||||||
|
logger.warn('projected transaction missing from mempool cache');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// unpack the condensed blocks into proper mempool blocks
|
// unpack the condensed blocks into proper mempool blocks
|
||||||
const mempoolBlocks = blocks.map((transactions, blockIndex) => {
|
const mempoolBlocks = blocks.map((transactions) => {
|
||||||
return this.dataToMempoolBlocks(transactions.map(tx => {
|
return this.dataToMempoolBlocks(transactions.map(tx => {
|
||||||
return mempool[tx.txid] || null;
|
return mempool[tx.txid] || null;
|
||||||
}).filter(tx => !!tx), blockIndex);
|
}).filter(tx => !!tx));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (saveResults) {
|
if (saveResults) {
|
||||||
@@ -293,7 +310,7 @@ class MempoolBlocks {
|
|||||||
return mempoolBlocks;
|
return mempoolBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private dataToMempoolBlocks(transactions: TransactionExtended[], blocksIndex: number): MempoolBlockWithTransactions {
|
private dataToMempoolBlocks(transactions: TransactionExtended[]): MempoolBlockWithTransactions {
|
||||||
let totalSize = 0;
|
let totalSize = 0;
|
||||||
let totalWeight = 0;
|
let totalWeight = 0;
|
||||||
const fitTransactions: TransactionExtended[] = [];
|
const fitTransactions: TransactionExtended[] = [];
|
||||||
@@ -304,22 +321,14 @@ class MempoolBlocks {
|
|||||||
fitTransactions.push(tx);
|
fitTransactions.push(tx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let rangeLength = 4;
|
const feeStats = Common.calcEffectiveFeeStatistics(transactions);
|
||||||
if (blocksIndex === 0) {
|
|
||||||
rangeLength = 8;
|
|
||||||
}
|
|
||||||
if (transactions.length > 4000) {
|
|
||||||
rangeLength = 6;
|
|
||||||
} else if (transactions.length > 10000) {
|
|
||||||
rangeLength = 8;
|
|
||||||
}
|
|
||||||
return {
|
return {
|
||||||
blockSize: totalSize,
|
blockSize: totalSize,
|
||||||
blockVSize: totalWeight / 4,
|
blockVSize: totalWeight / 4,
|
||||||
nTx: transactions.length,
|
nTx: transactions.length,
|
||||||
totalFees: transactions.reduce((acc, cur) => acc + cur.fee, 0),
|
totalFees: transactions.reduce((acc, cur) => acc + cur.fee, 0),
|
||||||
medianFee: Common.percentile(transactions.map((tx) => tx.effectiveFeePerVsize), config.MEMPOOL.RECOMMENDED_FEE_PERCENTILE),
|
medianFee: feeStats.medianFee, // Common.percentile(transactions.map((tx) => tx.effectiveFeePerVsize), config.MEMPOOL.RECOMMENDED_FEE_PERCENTILE),
|
||||||
feeRange: Common.getFeesInRange(transactions, rangeLength),
|
feeRange: feeStats.feeRange, //Common.getFeesInRange(transactions, rangeLength),
|
||||||
transactionIds: transactions.map((tx) => tx.txid),
|
transactionIds: transactions.map((tx) => tx.txid),
|
||||||
transactions: fitTransactions.map((tx) => Common.stripTransaction(tx)),
|
transactions: fitTransactions.map((tx) => Common.stripTransaction(tx)),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ class Mempool {
|
|||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
setInterval(this.updateTxPerSecond.bind(this), 1000);
|
setInterval(this.updateTxPerSecond.bind(this), 1000);
|
||||||
setInterval(this.deleteExpiredTransactions.bind(this), 20000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -256,7 +255,7 @@ class Mempool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private deleteExpiredTransactions() {
|
public deleteExpiredTransactions() {
|
||||||
const now = new Date().getTime();
|
const now = new Date().getTime();
|
||||||
for (const tx in this.mempoolCache) {
|
for (const tx in this.mempoolCache) {
|
||||||
const lazyDeleteAt = this.mempoolCache[tx].deleteAfter;
|
const lazyDeleteAt = this.mempoolCache[tx].deleteAfter;
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ class Mining {
|
|||||||
const elapsedSeconds = Math.max(1, Math.round((new Date().getTime() / 1000) - timer));
|
const elapsedSeconds = Math.max(1, Math.round((new Date().getTime() / 1000) - timer));
|
||||||
if (elapsedSeconds > 5) {
|
if (elapsedSeconds > 5) {
|
||||||
const progress = Math.round(totalBlockChecked / blocks.length * 100);
|
const progress = Math.round(totalBlockChecked / blocks.length * 100);
|
||||||
logger.info(`Indexing difficulty adjustment at block #${block.height} | Progress: ${progress}%`, logger.tags.mining);
|
logger.debug(`Indexing difficulty adjustment at block #${block.height} | Progress: ${progress}%`, logger.tags.mining);
|
||||||
timer = new Date().getTime() / 1000;
|
timer = new Date().getTime() / 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,8 +558,10 @@ class Mining {
|
|||||||
currentBlockHeight -= 10000;
|
currentBlockHeight -= 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalIndexed) {
|
if (totalIndexed > 0) {
|
||||||
logger.info(`Indexing missing coinstatsindex data completed`, logger.tags.mining);
|
logger.info(`Indexing missing coinstatsindex data completed. Indexed ${totalIndexed}`, logger.tags.mining);
|
||||||
|
} else {
|
||||||
|
logger.debug(`Indexing missing coinstatsindex data completed. Indexed 0.`, logger.tags.mining);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -211,6 +211,7 @@ class WebsocketHandler {
|
|||||||
if (!_blocks) {
|
if (!_blocks) {
|
||||||
_blocks = blocks.getBlocks().slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT);
|
_blocks = blocks.getBlocks().slice(-config.MEMPOOL.INITIAL_BLOCKS_AMOUNT);
|
||||||
}
|
}
|
||||||
|
const da = difficultyAdjustment.getDifficultyAdjustment();
|
||||||
return {
|
return {
|
||||||
'mempoolInfo': memPool.getMempoolInfo(),
|
'mempoolInfo': memPool.getMempoolInfo(),
|
||||||
'vBytesPerSecond': memPool.getVBytesPerSecond(),
|
'vBytesPerSecond': memPool.getVBytesPerSecond(),
|
||||||
@@ -220,7 +221,7 @@ class WebsocketHandler {
|
|||||||
'transactions': memPool.getLatestTransactions(),
|
'transactions': memPool.getLatestTransactions(),
|
||||||
'backendInfo': backendInfo.getBackendInfo(),
|
'backendInfo': backendInfo.getBackendInfo(),
|
||||||
'loadingIndicators': loadingIndicators.getLoadingIndicators(),
|
'loadingIndicators': loadingIndicators.getLoadingIndicators(),
|
||||||
'da': difficultyAdjustment.getDifficultyAdjustment(),
|
'da': da?.previousTime ? da : undefined,
|
||||||
'fees': feeApi.getRecommendedFee(),
|
'fees': feeApi.getRecommendedFee(),
|
||||||
...this.extraInitProperties
|
...this.extraInitProperties
|
||||||
};
|
};
|
||||||
@@ -278,7 +279,9 @@ class WebsocketHandler {
|
|||||||
response['mempoolInfo'] = mempoolInfo;
|
response['mempoolInfo'] = mempoolInfo;
|
||||||
response['vBytesPerSecond'] = vBytesPerSecond;
|
response['vBytesPerSecond'] = vBytesPerSecond;
|
||||||
response['transactions'] = newTransactions.slice(0, 6).map((tx) => Common.stripTransaction(tx));
|
response['transactions'] = newTransactions.slice(0, 6).map((tx) => Common.stripTransaction(tx));
|
||||||
response['da'] = da;
|
if (da?.previousTime) {
|
||||||
|
response['da'] = da;
|
||||||
|
}
|
||||||
response['fees'] = recommendedFees;
|
response['fees'] = recommendedFees;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,7 +508,7 @@ class WebsocketHandler {
|
|||||||
const response = {
|
const response = {
|
||||||
'block': block,
|
'block': block,
|
||||||
'mempoolInfo': memPool.getMempoolInfo(),
|
'mempoolInfo': memPool.getMempoolInfo(),
|
||||||
'da': da,
|
'da': da?.previousTime ? da : undefined,
|
||||||
'fees': fees,
|
'fees': fees,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ interface IConfig {
|
|||||||
};
|
};
|
||||||
ESPLORA: {
|
ESPLORA: {
|
||||||
REST_API_URL: string;
|
REST_API_URL: string;
|
||||||
|
UNIX_SOCKET_PATH: string | void | null;
|
||||||
};
|
};
|
||||||
LIGHTNING: {
|
LIGHTNING: {
|
||||||
ENABLED: boolean;
|
ENABLED: boolean;
|
||||||
@@ -163,6 +164,7 @@ const defaults: IConfig = {
|
|||||||
},
|
},
|
||||||
'ESPLORA': {
|
'ESPLORA': {
|
||||||
'REST_API_URL': 'http://127.0.0.1:3000',
|
'REST_API_URL': 'http://127.0.0.1:3000',
|
||||||
|
'UNIX_SOCKET_PATH': null,
|
||||||
},
|
},
|
||||||
'ELECTRUM': {
|
'ELECTRUM': {
|
||||||
'HOST': '127.0.0.1',
|
'HOST': '127.0.0.1',
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ class Server {
|
|||||||
logger.debug(msg);
|
logger.debug(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
memPool.deleteExpiredTransactions();
|
||||||
await blocks.$updateBlocks();
|
await blocks.$updateBlocks();
|
||||||
await memPool.$updateMempool();
|
await memPool.$updateMempool();
|
||||||
indexer.$run();
|
indexer.$run();
|
||||||
@@ -275,7 +276,7 @@ class Server {
|
|||||||
|
|
||||||
if (!this.warnedHeapCritical && this.maxHeapSize > warnThreshold) {
|
if (!this.warnedHeapCritical && this.maxHeapSize > warnThreshold) {
|
||||||
this.warnedHeapCritical = true;
|
this.warnedHeapCritical = true;
|
||||||
logger.warn(`Used ${(this.maxHeapSize / stats.heap_size_limit).toFixed(2)}% of heap limit (${formatBytes(this.maxHeapSize, byteUnits, true)} / ${formatBytes(stats.heap_size_limit, byteUnits)})!`);
|
logger.warn(`Used ${(this.maxHeapSize / stats.heap_size_limit * 100).toFixed(2)}% of heap limit (${formatBytes(this.maxHeapSize, byteUnits, true)} / ${formatBytes(stats.heap_size_limit, byteUnits)})!`);
|
||||||
}
|
}
|
||||||
if (this.lastHeapLogTime === null || (now - this.lastHeapLogTime) > (this.heapLogInterval * 1000)) {
|
if (this.lastHeapLogTime === null || (now - this.lastHeapLogTime) > (this.heapLogInterval * 1000)) {
|
||||||
logger.debug(`Memory usage: ${formatBytes(this.maxHeapSize, byteUnits)} / ${formatBytes(stats.heap_size_limit, byteUnits)}`);
|
logger.debug(`Memory usage: ${formatBytes(this.maxHeapSize, byteUnits)} / ${formatBytes(stats.heap_size_limit, byteUnits)}`);
|
||||||
|
|||||||
@@ -214,6 +214,16 @@ export interface MempoolStats {
|
|||||||
tx_count: number;
|
tx_count: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface EffectiveFeeStats {
|
||||||
|
medianFee: number; // median effective fee rate
|
||||||
|
feeRange: number[]; // 2nd, 10th, 25th, 50th, 75th, 90th, 98th percentiles
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CpfpSummary {
|
||||||
|
transactions: TransactionExtended[];
|
||||||
|
clusters: { root: string, height: number, txs: Ancestor[], effectiveFeePerVsize: number }[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface Statistic {
|
export interface Statistic {
|
||||||
id?: number;
|
id?: number;
|
||||||
added: string;
|
added: string;
|
||||||
@@ -309,9 +319,11 @@ export interface IDifficultyAdjustment {
|
|||||||
remainingBlocks: number;
|
remainingBlocks: number;
|
||||||
remainingTime: number;
|
remainingTime: number;
|
||||||
previousRetarget: number;
|
previousRetarget: number;
|
||||||
|
previousTime: number;
|
||||||
nextRetargetHeight: number;
|
nextRetargetHeight: number;
|
||||||
timeAvg: number;
|
timeAvg: number;
|
||||||
timeOffset: number;
|
timeOffset: number;
|
||||||
|
expectedBlocks: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IndexedDifficultyAdjustment {
|
export interface IndexedDifficultyAdjustment {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { BlockExtended, BlockExtension, BlockPrice } from '../mempool.interfaces';
|
import { BlockExtended, BlockExtension, BlockPrice, EffectiveFeeStats } from '../mempool.interfaces';
|
||||||
import DB from '../database';
|
import DB from '../database';
|
||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
import { Common } from '../api/common';
|
import { Common } from '../api/common';
|
||||||
@@ -466,30 +466,6 @@ class BlocksRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get one block by hash
|
|
||||||
*/
|
|
||||||
public async $getBlockByHash(hash: string): Promise<object | null> {
|
|
||||||
try {
|
|
||||||
const query = `
|
|
||||||
SELECT ${BLOCK_DB_FIELDS}
|
|
||||||
FROM blocks
|
|
||||||
JOIN pools ON blocks.pool_id = pools.id
|
|
||||||
WHERE hash = ?;
|
|
||||||
`;
|
|
||||||
const [rows]: any[] = await DB.query(query, [hash]);
|
|
||||||
|
|
||||||
if (rows.length <= 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return await this.formatDbBlockIntoExtendedBlock(rows[0]);
|
|
||||||
} catch (e) {
|
|
||||||
logger.err(`Cannot get indexed block ${hash}. Reason: ` + (e instanceof Error ? e.message : e));
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return blocks difficulty
|
* Return blocks difficulty
|
||||||
*/
|
*/
|
||||||
@@ -599,7 +575,6 @@ class BlocksRepository {
|
|||||||
if (blocks[idx].previous_block_hash !== blocks[idx - 1].hash) {
|
if (blocks[idx].previous_block_hash !== blocks[idx - 1].hash) {
|
||||||
logger.warn(`Chain divergence detected at block ${blocks[idx - 1].height}`);
|
logger.warn(`Chain divergence detected at block ${blocks[idx - 1].height}`);
|
||||||
await this.$deleteBlocksFrom(blocks[idx - 1].height);
|
await this.$deleteBlocksFrom(blocks[idx - 1].height);
|
||||||
await BlocksSummariesRepository.$deleteBlocksFrom(blocks[idx - 1].height);
|
|
||||||
await HashratesRepository.$deleteHashratesFromTimestamp(blocks[idx - 1].timestamp - 604800);
|
await HashratesRepository.$deleteHashratesFromTimestamp(blocks[idx - 1].timestamp - 604800);
|
||||||
await DifficultyAdjustmentsRepository.$deleteAdjustementsFromHeight(blocks[idx - 1].height);
|
await DifficultyAdjustmentsRepository.$deleteAdjustementsFromHeight(blocks[idx - 1].height);
|
||||||
return false;
|
return false;
|
||||||
@@ -619,7 +594,7 @@ class BlocksRepository {
|
|||||||
* Delete blocks from the database from blockHeight
|
* Delete blocks from the database from blockHeight
|
||||||
*/
|
*/
|
||||||
public async $deleteBlocksFrom(blockHeight: number) {
|
public async $deleteBlocksFrom(blockHeight: number) {
|
||||||
logger.info(`Delete newer blocks from height ${blockHeight} from the database`);
|
logger.info(`Delete newer blocks from height ${blockHeight} from the database`, logger.tags.mining);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await DB.query(`DELETE FROM blocks where height >= ${blockHeight}`);
|
await DB.query(`DELETE FROM blocks where height >= ${blockHeight}`);
|
||||||
@@ -908,6 +883,25 @@ class BlocksRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save indexed effective fee statistics
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @param feeStats
|
||||||
|
*/
|
||||||
|
public async $saveEffectiveFeeStats(id: string, feeStats: EffectiveFeeStats): Promise<void> {
|
||||||
|
try {
|
||||||
|
await DB.query(`
|
||||||
|
UPDATE blocks SET median_fee = ?, fee_span = ?
|
||||||
|
WHERE hash = ?`,
|
||||||
|
[feeStats.medianFee, JSON.stringify(feeStats.feeRange), id]
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Cannot update block fee stats. Reason: ` + (e instanceof Error ? e.message : e));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a mysql row block into a BlockExtended. Note that you
|
* Convert a mysql row block into a BlockExtended. Note that you
|
||||||
* must provide the correct field into dbBlk object param
|
* must provide the correct field into dbBlk object param
|
||||||
@@ -978,6 +972,7 @@ class BlocksRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we're missing block summary related field, check if we can populate them on the fly now
|
// If we're missing block summary related field, check if we can populate them on the fly now
|
||||||
|
// This is for example triggered upon re-org
|
||||||
if (Common.blocksSummariesIndexingEnabled() &&
|
if (Common.blocksSummariesIndexingEnabled() &&
|
||||||
(extras.medianFeeAmt === null || extras.feePercentiles === null))
|
(extras.medianFeeAmt === null || extras.feePercentiles === null))
|
||||||
{
|
{
|
||||||
@@ -985,7 +980,7 @@ class BlocksRepository {
|
|||||||
if (extras.feePercentiles === null) {
|
if (extras.feePercentiles === null) {
|
||||||
const block = await bitcoinClient.getBlock(dbBlk.id, 2);
|
const block = await bitcoinClient.getBlock(dbBlk.id, 2);
|
||||||
const summary = blocks.summarizeBlock(block);
|
const summary = blocks.summarizeBlock(block);
|
||||||
await BlocksSummariesRepository.$saveSummary({ height: block.height, mined: summary });
|
await BlocksSummariesRepository.$saveTransactions(dbBlk.height, dbBlk.hash, summary.transactions);
|
||||||
extras.feePercentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(dbBlk.id);
|
extras.feePercentiles = await BlocksSummariesRepository.$getFeePercentilesByBlockId(dbBlk.id);
|
||||||
}
|
}
|
||||||
if (extras.feePercentiles !== null) {
|
if (extras.feePercentiles !== null) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import DB from '../database';
|
import DB from '../database';
|
||||||
import logger from '../logger';
|
import logger from '../logger';
|
||||||
import { BlockSummary } from '../mempool.interfaces';
|
import { BlockSummary, TransactionStripped } from '../mempool.interfaces';
|
||||||
|
|
||||||
class BlocksSummariesRepository {
|
class BlocksSummariesRepository {
|
||||||
public async $getByBlockId(id: string): Promise<BlockSummary | undefined> {
|
public async $getByBlockId(id: string): Promise<BlockSummary | undefined> {
|
||||||
@@ -17,7 +17,7 @@ class BlocksSummariesRepository {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $saveSummary(params: { height: number, mined?: BlockSummary}) {
|
public async $saveSummary(params: { height: number, mined?: BlockSummary}): Promise<void> {
|
||||||
const blockId = params.mined?.id;
|
const blockId = params.mined?.id;
|
||||||
try {
|
try {
|
||||||
const transactions = JSON.stringify(params.mined?.transactions || []);
|
const transactions = JSON.stringify(params.mined?.transactions || []);
|
||||||
@@ -37,6 +37,20 @@ class BlocksSummariesRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async $saveTransactions(blockHeight: number, blockId: string, transactions: TransactionStripped[]): Promise<void> {
|
||||||
|
try {
|
||||||
|
const transactionsStr = JSON.stringify(transactions);
|
||||||
|
await DB.query(`
|
||||||
|
INSERT INTO blocks_summaries
|
||||||
|
SET height = ?, transactions = ?, id = ?
|
||||||
|
ON DUPLICATE KEY UPDATE transactions = ?`,
|
||||||
|
[blockHeight, transactionsStr, blockId, transactionsStr]);
|
||||||
|
} catch (e: any) {
|
||||||
|
logger.debug(`Cannot save block summary transactions for ${blockId}. Reason: ${e instanceof Error ? e.message : e}`);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async $saveTemplate(params: { height: number, template: BlockSummary}) {
|
public async $saveTemplate(params: { height: number, template: BlockSummary}) {
|
||||||
const blockId = params.template?.id;
|
const blockId = params.template?.id;
|
||||||
try {
|
try {
|
||||||
@@ -68,19 +82,6 @@ class BlocksSummariesRepository {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete blocks from the database from blockHeight
|
|
||||||
*/
|
|
||||||
public async $deleteBlocksFrom(blockHeight: number) {
|
|
||||||
logger.info(`Delete newer blocks summary from height ${blockHeight} from the database`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await DB.query(`DELETE FROM blocks_summaries where height >= ${blockHeight}`);
|
|
||||||
} catch (e) {
|
|
||||||
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
|
* Get the fee percentiles if the block has already been indexed, [] otherwise
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class CpfpRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async $batchSaveClusters(clusters: { root: string, height: number, txs: any, effectiveFeePerVsize: number}[]): Promise<boolean> {
|
public async $batchSaveClusters(clusters: { root: string, height: number, txs: Ancestor[], effectiveFeePerVsize: number }[]): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const clusterValues: any[] = [];
|
const clusterValues: any[] = [];
|
||||||
const txs: any[] = [];
|
const txs: any[] = [];
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ class HashratesRepository {
|
|||||||
* Delete hashrates from the database from timestamp
|
* Delete hashrates from the database from timestamp
|
||||||
*/
|
*/
|
||||||
public async $deleteHashratesFromTimestamp(timestamp: number) {
|
public async $deleteHashratesFromTimestamp(timestamp: number) {
|
||||||
logger.info(`Delete newer hashrates from timestamp ${new Date(timestamp * 1000).toUTCString()} from the database`);
|
logger.info(`Delete newer hashrates from timestamp ${new Date(timestamp * 1000).toUTCString()} from the database`, logger.tags.mining);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await DB.query(`DELETE FROM hashrates WHERE hashrate_timestamp >= FROM_UNIXTIME(?)`, [timestamp]);
|
await DB.query(`DELETE FROM hashrates WHERE hashrate_timestamp >= FROM_UNIXTIME(?)`, [timestamp]);
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ class PricesRepository {
|
|||||||
|
|
||||||
// Compute fiat exchange rates
|
// Compute fiat exchange rates
|
||||||
let latestPrice = rates[0] as ApiPrice;
|
let latestPrice = rates[0] as ApiPrice;
|
||||||
if (latestPrice.USD === -1) {
|
if (!latestPrice || latestPrice.USD === -1) {
|
||||||
latestPrice = priceUpdater.getEmptyPricesObj();
|
latestPrice = priceUpdater.getEmptyPricesObj();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class ForensicsService {
|
|||||||
|
|
||||||
private async $runTasks(): Promise<void> {
|
private async $runTasks(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
logger.info(`Running forensics scans`);
|
logger.debug(`Running forensics scans`);
|
||||||
|
|
||||||
if (config.MEMPOOL.BACKEND === 'esplora') {
|
if (config.MEMPOOL.BACKEND === 'esplora') {
|
||||||
await this.$runClosedChannelsForensics(false);
|
await this.$runClosedChannelsForensics(false);
|
||||||
@@ -73,7 +73,7 @@ class ForensicsService {
|
|||||||
let progress = 0;
|
let progress = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.info(`Started running closed channel forensics...`);
|
logger.debug(`Started running closed channel forensics...`);
|
||||||
let channels;
|
let channels;
|
||||||
if (onlyNewChannels) {
|
if (onlyNewChannels) {
|
||||||
channels = await channelsApi.$getClosedChannelsWithoutReason();
|
channels = await channelsApi.$getClosedChannelsWithoutReason();
|
||||||
@@ -156,7 +156,7 @@ class ForensicsService {
|
|||||||
this.loggerTimer = new Date().getTime() / 1000;
|
this.loggerTimer = new Date().getTime() / 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.info(`Closed channels forensics scan complete.`);
|
logger.debug(`Closed channels forensics scan complete.`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.err('$runClosedChannelsForensics() error: ' + (e instanceof Error ? e.message : e));
|
logger.err('$runClosedChannelsForensics() error: ' + (e instanceof Error ? e.message : e));
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ class ForensicsService {
|
|||||||
let progress = 0;
|
let progress = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.info(`Started running open channel forensics...`);
|
logger.debug(`Started running open channel forensics...`);
|
||||||
const channels = await channelsApi.$getChannelsWithoutSourceChecked();
|
const channels = await channelsApi.$getChannelsWithoutSourceChecked();
|
||||||
|
|
||||||
for (const openChannel of channels) {
|
for (const openChannel of channels) {
|
||||||
@@ -266,7 +266,7 @@ class ForensicsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`Open channels forensics scan complete.`);
|
logger.debug(`Open channels forensics scan complete.`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.err('$runOpenedChannelsForensics() error: ' + (e instanceof Error ? e.message : e));
|
logger.err('$runOpenedChannelsForensics() error: ' + (e instanceof Error ? e.message : e));
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ class NetworkSyncService {
|
|||||||
} else {
|
} else {
|
||||||
log += ` for the first time`;
|
log += ` for the first time`;
|
||||||
}
|
}
|
||||||
logger.info(`${log}`, logger.tags.ln);
|
logger.debug(`${log}`, logger.tags.ln);
|
||||||
|
|
||||||
const channels = await channelsApi.$getChannelsByStatus([0, 1]);
|
const channels = await channelsApi.$getChannelsByStatus([0, 1]);
|
||||||
for (const channel of channels) {
|
for (const channel of channels) {
|
||||||
|
|||||||
@@ -15,16 +15,20 @@ class LightningStatsImporter {
|
|||||||
topologiesFolder = config.LIGHTNING.TOPOLOGY_FOLDER;
|
topologiesFolder = config.LIGHTNING.TOPOLOGY_FOLDER;
|
||||||
|
|
||||||
async $run(): Promise<void> {
|
async $run(): Promise<void> {
|
||||||
const [channels]: any[] = await DB.query('SELECT short_id from channels;');
|
try {
|
||||||
logger.info(`Caching funding txs for currently existing channels`, logger.tags.ln);
|
const [channels]: any[] = await DB.query('SELECT short_id from channels;');
|
||||||
await fundingTxFetcher.$fetchChannelsFundingTxs(channels.map(channel => channel.short_id));
|
logger.info(`Caching funding txs for currently existing channels`, logger.tags.ln);
|
||||||
|
await fundingTxFetcher.$fetchChannelsFundingTxs(channels.map(channel => channel.short_id));
|
||||||
|
|
||||||
if (config.MEMPOOL.NETWORK !== 'mainnet' || config.DATABASE.ENABLED === false) {
|
if (config.MEMPOOL.NETWORK !== 'mainnet' || config.DATABASE.ENABLED === false) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.$importHistoricalLightningStats();
|
||||||
|
await this.$cleanupIncorrectSnapshot();
|
||||||
|
} catch (e) {
|
||||||
|
logger.err(`Exception in LightningStatsImporter::$run(). ${e}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.$importHistoricalLightningStats();
|
|
||||||
await this.$cleanupIncorrectSnapshot();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class PoolsUpdater {
|
|||||||
if (this.currentSha === null) {
|
if (this.currentSha === null) {
|
||||||
logger.info(`Downloading pools-v2.json for the first time from ${this.poolsUrl} over ${network}`, logger.tags.mining);
|
logger.info(`Downloading pools-v2.json for the first time from ${this.poolsUrl} over ${network}`, logger.tags.mining);
|
||||||
} else {
|
} else {
|
||||||
logger.warn(`pools-v2.json is outdated, fetch latest from ${this.poolsUrl} over ${network}`, logger.tags.mining);
|
logger.warn(`pools-v2.json is outdated, fetching latest from ${this.poolsUrl} over ${network}`, logger.tags.mining);
|
||||||
}
|
}
|
||||||
const poolsJson = await this.query(this.poolsUrl);
|
const poolsJson = await this.query(this.poolsUrl);
|
||||||
if (poolsJson === undefined) {
|
if (poolsJson === undefined) {
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ class PriceUpdater {
|
|||||||
private async $insertMissingRecentPrices(type: 'hour' | 'day'): Promise<void> {
|
private async $insertMissingRecentPrices(type: 'hour' | 'day'): Promise<void> {
|
||||||
const existingPriceTimes = await PricesRepository.$getPricesTimes();
|
const existingPriceTimes = await PricesRepository.$getPricesTimes();
|
||||||
|
|
||||||
logger.info(`Fetching ${type === 'day' ? 'dai' : 'hour'}ly price history from exchanges and saving missing ones into the database`, logger.tags.mining);
|
logger.debug(`Fetching ${type === 'day' ? 'dai' : 'hour'}ly price history from exchanges and saving missing ones into the database`, logger.tags.mining);
|
||||||
|
|
||||||
const historicalPrices: PriceHistory[] = [];
|
const historicalPrices: PriceHistory[] = [];
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"types": ["node", "jest"],
|
"types": ["node", "jest"],
|
||||||
"lib": ["es2019", "dom"],
|
"lib": ["es2019", "dom"],
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"outDir": "dist",
|
"outDir": "dist",
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ If you are looking to use these Docker images to deploy your own instance of Mem
|
|||||||
|
|
||||||
See a video guide of this installation method by k3tan [on BitcoinTV.com](https://bitcointv.com/w/8fpAx6rf5CQ16mMhospwjg).
|
See a video guide of this installation method by k3tan [on BitcoinTV.com](https://bitcointv.com/w/8fpAx6rf5CQ16mMhospwjg).
|
||||||
|
|
||||||
|
**We only provide support for this installation method to <a href="https://mempool.space/enterprise">Enterprise sponsors</a>.**
|
||||||
|
|
||||||
Jump to a section in this doc:
|
Jump to a section in this doc:
|
||||||
- [Configure with Bitcoin Core Only](#configure-with-bitcoin-core-only)
|
- [Configure with Bitcoin Core Only](#configure-with-bitcoin-core-only)
|
||||||
- [Configure with Bitcoin Core + Electrum Server](#configure-with-bitcoin-core--electrum-server)
|
- [Configure with Bitcoin Core + Electrum Server](#configure-with-bitcoin-core--electrum-server)
|
||||||
@@ -204,7 +206,8 @@ Corresponding `docker-compose.yml` overrides:
|
|||||||
`mempool-config.json`:
|
`mempool-config.json`:
|
||||||
```json
|
```json
|
||||||
"ESPLORA": {
|
"ESPLORA": {
|
||||||
"REST_API_URL": "http://127.0.0.1:3000"
|
"REST_API_URL": "http://127.0.0.1:3000",
|
||||||
|
"UNIX_SOCKET_PATH": "/tmp/esplora-socket"
|
||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -213,6 +216,7 @@ Corresponding `docker-compose.yml` overrides:
|
|||||||
api:
|
api:
|
||||||
environment:
|
environment:
|
||||||
ESPLORA_REST_API_URL: ""
|
ESPLORA_REST_API_URL: ""
|
||||||
|
ESPLORA_UNIX_SOCKET_PATH: ""
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,8 @@
|
|||||||
"TLS_ENABLED": __ELECTRUM_TLS_ENABLED__
|
"TLS_ENABLED": __ELECTRUM_TLS_ENABLED__
|
||||||
},
|
},
|
||||||
"ESPLORA": {
|
"ESPLORA": {
|
||||||
"REST_API_URL": "__ESPLORA_REST_API_URL__"
|
"REST_API_URL": "__ESPLORA_REST_API_URL__",
|
||||||
|
"UNIX_SOCKET_PATH": "__ESPLORA_UNIX_SOCKET_PATH__"
|
||||||
},
|
},
|
||||||
"SECOND_CORE_RPC": {
|
"SECOND_CORE_RPC": {
|
||||||
"HOST": "__SECOND_CORE_RPC_HOST__",
|
"HOST": "__SECOND_CORE_RPC_HOST__",
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ __ELECTRUM_TLS_ENABLED__=${ELECTRUM_TLS_ENABLED:=false}
|
|||||||
|
|
||||||
# ESPLORA
|
# ESPLORA
|
||||||
__ESPLORA_REST_API_URL__=${ESPLORA_REST_API_URL:=http://127.0.0.1:3000}
|
__ESPLORA_REST_API_URL__=${ESPLORA_REST_API_URL:=http://127.0.0.1:3000}
|
||||||
|
__ESPLORA_UNIX_SOCKET_PATH__=${ESPLORA_UNIX_SOCKET_PATH:=null}
|
||||||
|
|
||||||
# SECOND_CORE_RPC
|
# SECOND_CORE_RPC
|
||||||
__SECOND_CORE_RPC_HOST__=${SECOND_CORE_RPC_HOST:=127.0.0.1}
|
__SECOND_CORE_RPC_HOST__=${SECOND_CORE_RPC_HOST:=127.0.0.1}
|
||||||
@@ -166,6 +167,7 @@ sed -i "s/__ELECTRUM_PORT__/${__ELECTRUM_PORT__}/g" mempool-config.json
|
|||||||
sed -i "s/__ELECTRUM_TLS_ENABLED__/${__ELECTRUM_TLS_ENABLED__}/g" mempool-config.json
|
sed -i "s/__ELECTRUM_TLS_ENABLED__/${__ELECTRUM_TLS_ENABLED__}/g" mempool-config.json
|
||||||
|
|
||||||
sed -i "s!__ESPLORA_REST_API_URL__!${__ESPLORA_REST_API_URL__}!g" mempool-config.json
|
sed -i "s!__ESPLORA_REST_API_URL__!${__ESPLORA_REST_API_URL__}!g" mempool-config.json
|
||||||
|
sed -i "s!__ESPLORA_UNIX_SOCKET_PATH__!${__ESPLORA_UNIX_SOCKET_PATH__}!g" mempool-config.json
|
||||||
|
|
||||||
sed -i "s/__SECOND_CORE_RPC_HOST__/${__SECOND_CORE_RPC_HOST__}/g" mempool-config.json
|
sed -i "s/__SECOND_CORE_RPC_HOST__/${__SECOND_CORE_RPC_HOST__}/g" mempool-config.json
|
||||||
sed -i "s/__SECOND_CORE_RPC_PORT__/${__SECOND_CORE_RPC_PORT__}/g" mempool-config.json
|
sed -i "s/__SECOND_CORE_RPC_PORT__/${__SECOND_CORE_RPC_PORT__}/g" mempool-config.json
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ describe('Mainnet', () => {
|
|||||||
|
|
||||||
cy.get('.search-box-container > .form-control').type('S').then(() => {
|
cy.get('.search-box-container > .form-control').type('S').then(() => {
|
||||||
cy.wait('@search-1wizS');
|
cy.wait('@search-1wizS');
|
||||||
cy.get('app-search-results button.dropdown-item').should('have.length', 5);
|
cy.get('app-search-results button.dropdown-item').should('have.length', 6);
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.get('.search-box-container > .form-control').type('A').then(() => {
|
cy.get('.search-box-container > .form-control').type('A').then(() => {
|
||||||
|
|||||||
4
frontend/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "mempool-frontend",
|
"name": "mempool-frontend",
|
||||||
"version": "2.5.0-dev",
|
"version": "2.6.0-dev",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mempool-frontend",
|
"name": "mempool-frontend",
|
||||||
"version": "2.5.0-dev",
|
"version": "2.6.0-dev",
|
||||||
"license": "GNU Affero General Public License v3.0",
|
"license": "GNU Affero General Public License v3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular-devkit/build-angular": "^14.2.10",
|
"@angular-devkit/build-angular": "^14.2.10",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mempool-frontend",
|
"name": "mempool-frontend",
|
||||||
"version": "2.5.0-dev",
|
"version": "2.6.0-dev",
|
||||||
"description": "Bitcoin mempool visualizer and blockchain explorer backend",
|
"description": "Bitcoin mempool visualizer and blockchain explorer backend",
|
||||||
"license": "GNU Affero General Public License v3.0",
|
"license": "GNU Affero General Public License v3.0",
|
||||||
"homepage": "https://mempool.space",
|
"homepage": "https://mempool.space",
|
||||||
|
|||||||
@@ -201,12 +201,12 @@
|
|||||||
<span>Umbrel</span>
|
<span>Umbrel</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/rootzoll/raspiblitz" target="_blank" title="RaspiBlitz">
|
<a href="https://github.com/rootzoll/raspiblitz" target="_blank" title="RaspiBlitz">
|
||||||
<img class="image" src="/resources/profile/raspiblitz.jpg" />
|
<img class="image" src="/resources/profile/raspiblitz.svg" />
|
||||||
<span>RaspiBlitz</span>
|
<span>RaspiBlitz</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/mynodebtc/mynode" target="_blank" title="MyNode">
|
<a href="https://github.com/mynodebtc/mynode" target="_blank" title="myNode">
|
||||||
<img class="image" src="/resources/profile/mynodebtc.jpg" />
|
<img class="image" src="/resources/profile/mynodebtc.png" />
|
||||||
<span>MyNode</span>
|
<span>myNode</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/RoninDojo/RoninDojo" target="_blank" title="RoninDojo">
|
<a href="https://github.com/RoninDojo/RoninDojo" target="_blank" title="RoninDojo">
|
||||||
<img class="image" src="/resources/profile/ronindojo.png" />
|
<img class="image" src="/resources/profile/ronindojo.png" />
|
||||||
@@ -253,7 +253,7 @@
|
|||||||
<span>Sparrow</span>
|
<span>Sparrow</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/ACINQ/phoenix" target="_blank" title="Phoenix Wallet by ACINQ">
|
<a href="https://github.com/ACINQ/phoenix" target="_blank" title="Phoenix Wallet by ACINQ">
|
||||||
<img class="image" src="/resources/profile/phoenix.jpg" />
|
<img class="image not-rounded" src="/resources/profile/phoenix.svg" />
|
||||||
<span>Phoenix</span>
|
<span>Phoenix</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/lnbits/lnbits-legend" target="_blank" title="LNbits">
|
<a href="https://github.com/lnbits/lnbits-legend" target="_blank" title="LNbits">
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
|
|||||||
@Input() unavailable: boolean = false;
|
@Input() unavailable: boolean = false;
|
||||||
@Input() auditHighlighting: boolean = false;
|
@Input() auditHighlighting: boolean = false;
|
||||||
@Input() blockConversion: Price;
|
@Input() blockConversion: Price;
|
||||||
@Output() txClickEvent = new EventEmitter<TransactionStripped>();
|
@Output() txClickEvent = new EventEmitter<{ tx: TransactionStripped, keyModifier: boolean}>();
|
||||||
@Output() txHoverEvent = new EventEmitter<string>();
|
@Output() txHoverEvent = new EventEmitter<string>();
|
||||||
@Output() readyEvent = new EventEmitter();
|
@Output() readyEvent = new EventEmitter();
|
||||||
|
|
||||||
@@ -326,7 +326,9 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
|
|||||||
if (event.target === this.canvas.nativeElement && event.pointerType === 'touch') {
|
if (event.target === this.canvas.nativeElement && event.pointerType === 'touch') {
|
||||||
this.setPreviewTx(event.offsetX, event.offsetY, true);
|
this.setPreviewTx(event.offsetX, event.offsetY, true);
|
||||||
} else if (event.target === this.canvas.nativeElement) {
|
} else if (event.target === this.canvas.nativeElement) {
|
||||||
this.onTxClick(event.offsetX, event.offsetY);
|
const keyMod = event.shiftKey || event.ctrlKey || event.metaKey;
|
||||||
|
const middleClick = event.which === 2 || event.button === 1;
|
||||||
|
this.onTxClick(event.offsetX, event.offsetY, keyMod || middleClick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,12 +411,12 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTxClick(cssX: number, cssY: number) {
|
onTxClick(cssX: number, cssY: number, keyModifier: boolean = false) {
|
||||||
const x = cssX * window.devicePixelRatio;
|
const x = cssX * window.devicePixelRatio;
|
||||||
const y = cssY * window.devicePixelRatio;
|
const y = cssY * window.devicePixelRatio;
|
||||||
const selected = this.scene.getTxAt({ x, y });
|
const selected = this.scene.getTxAt({ x, y });
|
||||||
if (selected && selected.txid) {
|
if (selected && selected.txid) {
|
||||||
this.txClickEvent.emit(selected);
|
this.txClickEvent.emit({ tx: selected, keyModifier });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -612,9 +612,13 @@ export class BlockComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onTxClick(event: TransactionStripped): void {
|
onTxClick(event: { tx: TransactionStripped, keyModifier: boolean }): void {
|
||||||
const url = new RelativeUrlPipe(this.stateService).transform(`/tx/${event.txid}`);
|
const url = new RelativeUrlPipe(this.stateService).transform(`/tx/${event.tx.txid}`);
|
||||||
this.router.navigate([url]);
|
if (!event.keyModifier) {
|
||||||
|
this.router.navigate([url]);
|
||||||
|
} else {
|
||||||
|
window.open(url, '_blank');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTxHover(txid: string): void {
|
onTxHover(txid: string): void {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
<div [attr.data-cy]="'bitcoin-block-' + offset + '-index-' + i + '-fee-span'" class="fee-span"
|
<div [attr.data-cy]="'bitcoin-block-' + offset + '-index-' + i + '-fee-span'" class="fee-span"
|
||||||
*ngIf="block?.extras?.feeRange; else emptyfeespan">
|
*ngIf="block?.extras?.feeRange; else emptyfeespan">
|
||||||
{{ block?.extras?.feeRange?.[1] | number:feeRounding }} - {{
|
{{ block?.extras?.feeRange?.[0] | number:feeRounding }} - {{
|
||||||
block?.extras?.feeRange[block?.extras?.feeRange?.length - 1] | number:feeRounding }} <ng-container
|
block?.extras?.feeRange[block?.extras?.feeRange?.length - 1] | number:feeRounding }} <ng-container
|
||||||
i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
i18n="shared.sat-vbyte|sat/vB">sat/vB</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -90,6 +90,8 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<app-testnet-alert *ngIf="network.val === 'liquidtestnet'"></app-testnet-alert>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
|||||||
@@ -62,6 +62,8 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
<app-testnet-alert *ngIf="network.val === 'testnet' || network.val === 'signet'"></app-testnet-alert>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
|
|||||||
@@ -192,4 +192,4 @@ nav {
|
|||||||
margin: 33px 0px 0px -19px;
|
margin: 33px 0px 0px -19px;
|
||||||
font-size: 7px;
|
font-size: 7px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Component, Inject, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Env, StateService } from '../../services/state.service';
|
import { Env, StateService } from '../../services/state.service';
|
||||||
import { Observable, merge, of } from 'rxjs';
|
import { Observable, merge, of } from 'rxjs';
|
||||||
import { LanguageService } from '../../services/language.service';
|
import { LanguageService } from '../../services/language.service';
|
||||||
|
|||||||
@@ -107,8 +107,12 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
|
|||||||
this.isLoading$.next(false);
|
this.isLoading$.next(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
onTxClick(event: TransactionStripped): void {
|
onTxClick(event: { tx: TransactionStripped, keyModifier: boolean }): void {
|
||||||
const url = new RelativeUrlPipe(this.stateService).transform(`/tx/${event.txid}`);
|
const url = new RelativeUrlPipe(this.stateService).transform(`/tx/${event.tx.txid}`);
|
||||||
this.router.navigate([url]);
|
if (!event.keyModifier) {
|
||||||
|
this.router.navigate([url]);
|
||||||
|
} else {
|
||||||
|
window.open(url, '_blank');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div *ngIf="network !== 'liquid' && network !== 'liquidtestnet'" class="features">
|
<div *ngIf="network !== 'liquid' && network !== 'liquidtestnet'" class="features">
|
||||||
<app-tx-features [tx]="tx"></app-tx-features>
|
<app-tx-features [tx]="tx"></app-tx-features>
|
||||||
<span *ngIf="cpfpInfo && (cpfpInfo.bestDescendant || cpfpInfo.descendants.length)" class="badge badge-primary mr-1">
|
<span *ngIf="cpfpInfo && (cpfpInfo?.bestDescendant || cpfpInfo?.descendants?.length || cpfpInfo?.ancestors?.length)" class="badge badge-primary ml-1 mr-1">
|
||||||
CPFP
|
|
||||||
</span>
|
|
||||||
<span *ngIf="cpfpInfo && !cpfpInfo.bestDescendant && !cpfpInfo.descendants.length && cpfpInfo.ancestors.length" class="badge badge-info mr-1">
|
|
||||||
CPFP
|
CPFP
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
<div infiniteScroll [alwaysCallback]="true" [infiniteScrollDistance]="2" [infiniteScrollUpDistance]="1.5" [infiniteScrollThrottle]="50" (scrolled)="onScroll()">
|
||||||
|
|
||||||
<ng-container *ngFor="let tx of transactions; let i = index; trackBy: trackByFn">
|
<ng-container *ngFor="let tx of transactions; let i = index; trackBy: trackByFn">
|
||||||
<div *ngIf="!transactionPage" class="header-bg box tx-page-container">
|
<div *ngIf="!transactionPage" class="header-bg box tx-page-container">
|
||||||
<a class="tx-link" [routerLink]="['/tx/' | relativeUrl, tx.txid]">
|
<a class="tx-link" [routerLink]="['/tx/' | relativeUrl, tx.txid]">
|
||||||
@@ -11,7 +13,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="header-bg box" infiniteScroll [alwaysCallback]="true" [infiniteScrollDistance]="2" [infiniteScrollUpDistance]="1.5" [infiniteScrollThrottle]="50" (scrolled)="onScroll()" [attr.data-cy]="'tx-' + i">
|
<div class="header-bg box" [attr.data-cy]="'tx-' + i">
|
||||||
|
|
||||||
<div *ngIf="errorUnblinded" class="error-unblinded">{{ errorUnblinded }}</div>
|
<div *ngIf="errorUnblinded" class="error-unblinded">{{ errorUnblinded }}</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -321,6 +323,8 @@
|
|||||||
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<ng-template #assetBox let-item>
|
<ng-template #assetBox let-item>
|
||||||
{{ item.value / pow(10, assetsMinimal[item.asset][3]) | number: '1.' + assetsMinimal[item.asset][3] + '-' + assetsMinimal[item.asset][3] }} {{ assetsMinimal[item.asset][1] }}
|
{{ item.value / pow(10, assetsMinimal[item.asset][3]) | number: '1.' + assetsMinimal[item.asset][3] + '-' + assetsMinimal[item.asset][3] }} {{ assetsMinimal[item.asset][1] }}
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
@@ -182,14 +182,7 @@ export class TransactionsListComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onScroll(): void {
|
onScroll(): void {
|
||||||
const scrollHeight = document.body.scrollHeight;
|
this.loadMore.emit();
|
||||||
const scrollTop = document.documentElement.scrollTop;
|
|
||||||
if (scrollHeight > 0){
|
|
||||||
const percentageScrolled = scrollTop * 100 / scrollHeight;
|
|
||||||
if (percentageScrolled > 70){
|
|
||||||
this.loadMore.emit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
haveBlindedOutputValues(tx: Transaction): boolean {
|
haveBlindedOutputValues(tx: Transaction): boolean {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<ng-template #pegout>
|
<ng-template #pegout>
|
||||||
<ng-container *ngIf="line.pegout; else normal">
|
<ng-container *ngIf="line.pegout; else normal">
|
||||||
<p *ngIf="!isConnector">Peg Out</p>
|
<p *ngIf="!isConnector">Peg Out</p>
|
||||||
<p *ngIf="line.value != null"><app-amount [satoshis]="line.value"></app-amount></p>
|
<p *ngIf="line.displayValue != null"><app-amount [satoshis]="line.displayValue"></app-amount></p>
|
||||||
<p class="address">
|
<p class="address">
|
||||||
<app-truncate [text]="line.pegout"></app-truncate>
|
<app-truncate [text]="line.pegout"></app-truncate>
|
||||||
</p>
|
</p>
|
||||||
@@ -55,18 +55,18 @@
|
|||||||
<p *ngSwitchCase="'output'"><span i18n="transaction.input">Input</span> #{{ line.vin + 1 }}</p>
|
<p *ngSwitchCase="'output'"><span i18n="transaction.input">Input</span> #{{ line.vin + 1 }}</p>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<p *ngIf="line.value == null && line.confidential" i18n="shared.confidential">Confidential</p>
|
<p *ngIf="line.displayValue == null && line.confidential" i18n="shared.confidential">Confidential</p>
|
||||||
<p *ngIf="line.value != null">
|
<p *ngIf="line.displayValue != null">
|
||||||
<ng-template [ngIf]="line.asset && line.asset !== nativeAssetId" [ngIfElse]="defaultOutput">
|
<ng-template [ngIf]="line.asset && line.asset !== nativeAssetId" [ngIfElse]="defaultOutput">
|
||||||
<div *ngIf="assetsMinimal && assetsMinimal[line.asset] else assetNotFound">
|
<div *ngIf="assetsMinimal && assetsMinimal[line.asset] else assetNotFound">
|
||||||
<ng-container *ngTemplateOutlet="assetBox; context:{ $implicit: line }"></ng-container>
|
<ng-container *ngTemplateOutlet="assetBox; context:{ $implicit: line }"></ng-container>
|
||||||
</div>
|
</div>
|
||||||
<ng-template #assetNotFound>
|
<ng-template #assetNotFound>
|
||||||
{{ line.value }} <span class="symbol">{{ line.asset | slice : 0 : 7 }}</span>
|
{{ line.displayValue }} <span class="symbol">{{ line.asset | slice : 0 : 7 }}</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
<ng-template #defaultOutput>
|
<ng-template #defaultOutput>
|
||||||
<app-amount [blockConversion]="blockConversion" [satoshis]="line.value"></app-amount>
|
<app-amount [blockConversion]="blockConversion" [satoshis]="line.displayValue"></app-amount>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</p>
|
</p>
|
||||||
<p *ngIf="line.type !== 'fee' && line.address" class="address">
|
<p *ngIf="line.type !== 'fee' && line.address" class="address">
|
||||||
@@ -76,5 +76,5 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ng-template #assetBox let-item>
|
<ng-template #assetBox let-item>
|
||||||
{{ item.value / pow(10, assetsMinimal[item.asset][3]) | number: '1.' + assetsMinimal[item.asset][3] + '-' + assetsMinimal[item.asset][3] }} <span class="symbol">{{ assetsMinimal[item.asset][1] }}</span>
|
{{ item.displayValue / pow(10, assetsMinimal[item.asset][3]) | number: '1.' + assetsMinimal[item.asset][3] + '-' + assetsMinimal[item.asset][3] }} <span class="symbol">{{ assetsMinimal[item.asset][1] }}</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
@@ -7,6 +7,7 @@ import { environment } from '../../../environments/environment';
|
|||||||
interface Xput {
|
interface Xput {
|
||||||
type: 'input' | 'output' | 'fee';
|
type: 'input' | 'output' | 'fee';
|
||||||
value?: number;
|
value?: number;
|
||||||
|
displayValue?: number;
|
||||||
index?: number;
|
index?: number;
|
||||||
txid?: string;
|
txid?: string;
|
||||||
vin?: number;
|
vin?: number;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { Component, OnInit, Input, OnChanges, HostListener, Inject, LOCALE_ID } from '@angular/core';
|
import { Component, OnInit, Input, OnChanges, HostListener, Inject, LOCALE_ID } from '@angular/core';
|
||||||
import { StateService } from '../../services/state.service';
|
import { StateService } from '../../services/state.service';
|
||||||
import { Outspend, Transaction } from '../../interfaces/electrs.interface';
|
import { Outspend, Transaction, Vin, Vout } from '../../interfaces/electrs.interface';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { ReplaySubject, merge, Subscription, of } from 'rxjs';
|
import { ReplaySubject, merge, Subscription, of } from 'rxjs';
|
||||||
import { tap, switchMap } from 'rxjs/operators';
|
import { tap, switchMap } from 'rxjs/operators';
|
||||||
import { ApiService } from '../../services/api.service';
|
import { ApiService } from '../../services/api.service';
|
||||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
|
||||||
import { AssetsService } from '../../services/assets.service';
|
import { AssetsService } from '../../services/assets.service';
|
||||||
|
import { environment } from '../../../environments/environment';
|
||||||
|
|
||||||
interface SvgLine {
|
interface SvgLine {
|
||||||
path: string;
|
path: string;
|
||||||
@@ -20,6 +21,7 @@ interface SvgLine {
|
|||||||
interface Xput {
|
interface Xput {
|
||||||
type: 'input' | 'output' | 'fee';
|
type: 'input' | 'output' | 'fee';
|
||||||
value?: number;
|
value?: number;
|
||||||
|
displayValue?: number;
|
||||||
index?: number;
|
index?: number;
|
||||||
txid?: string;
|
txid?: string;
|
||||||
vin?: number;
|
vin?: number;
|
||||||
@@ -74,6 +76,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||||||
zeroValueThickness = 20;
|
zeroValueThickness = 20;
|
||||||
hasLine: boolean;
|
hasLine: boolean;
|
||||||
assetsMinimal: any;
|
assetsMinimal: any;
|
||||||
|
nativeAssetId = this.stateService.network === 'liquidtestnet' ? environment.nativeTestAssetId : environment.nativeAssetId;
|
||||||
|
|
||||||
outspendsSubscription: Subscription;
|
outspendsSubscription: Subscription;
|
||||||
refreshOutspends$: ReplaySubject<string> = new ReplaySubject();
|
refreshOutspends$: ReplaySubject<string> = new ReplaySubject();
|
||||||
@@ -167,7 +170,8 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||||||
let voutWithFee = this.tx.vout.map((v, i) => {
|
let voutWithFee = this.tx.vout.map((v, i) => {
|
||||||
return {
|
return {
|
||||||
type: v.scriptpubkey_type === 'fee' ? 'fee' : 'output',
|
type: v.scriptpubkey_type === 'fee' ? 'fee' : 'output',
|
||||||
value: v?.value,
|
value: this.getOutputValue(v),
|
||||||
|
displayValue: v?.value,
|
||||||
address: v?.scriptpubkey_address || v?.scriptpubkey_type?.toUpperCase(),
|
address: v?.scriptpubkey_address || v?.scriptpubkey_type?.toUpperCase(),
|
||||||
index: i,
|
index: i,
|
||||||
pegout: v?.pegout?.scriptpubkey_address,
|
pegout: v?.pegout?.scriptpubkey_address,
|
||||||
@@ -185,7 +189,8 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||||||
let truncatedInputs = this.tx.vin.map((v, i) => {
|
let truncatedInputs = this.tx.vin.map((v, i) => {
|
||||||
return {
|
return {
|
||||||
type: 'input',
|
type: 'input',
|
||||||
value: v?.prevout?.value || (v?.is_coinbase && !totalValue ? 0 : undefined),
|
value: (v?.is_coinbase && !totalValue ? 0 : this.getInputValue(v)),
|
||||||
|
displayValue: v?.prevout?.value,
|
||||||
txid: v.txid,
|
txid: v.txid,
|
||||||
vout: v.vout,
|
vout: v.vout,
|
||||||
address: v?.prevout?.scriptpubkey_address || v?.prevout?.scriptpubkey_type?.toUpperCase(),
|
address: v?.prevout?.scriptpubkey_address || v?.prevout?.scriptpubkey_type?.toUpperCase(),
|
||||||
@@ -229,14 +234,14 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
calcTotalValue(tx: Transaction): number {
|
calcTotalValue(tx: Transaction): number {
|
||||||
const totalOutput = this.tx.vout.reduce((acc, v) => (v.value == null ? 0 : v.value) + acc, 0);
|
let totalOutput = this.tx.vout.reduce((acc, v) => (this.getOutputValue(v) || 0) + acc, 0);
|
||||||
// simple sum of outputs + fee for bitcoin
|
// simple sum of outputs + fee for bitcoin
|
||||||
if (!this.isLiquid) {
|
if (!this.isLiquid) {
|
||||||
return this.tx.fee ? totalOutput + this.tx.fee : totalOutput;
|
return this.tx.fee ? totalOutput + this.tx.fee : totalOutput;
|
||||||
} else {
|
} else {
|
||||||
const totalInput = this.tx.vin.reduce((acc, v) => (v?.prevout?.value == null ? 0 : v.prevout.value) + acc, 0);
|
const totalInput = this.tx.vin.reduce((acc, v) => (this.getInputValue(v) || 0) + acc, 0);
|
||||||
const confidentialInputCount = this.tx.vin.reduce((acc, v) => acc + (v?.prevout?.value == null ? 1 : 0), 0);
|
const confidentialInputCount = this.tx.vin.reduce((acc, v) => acc + (this.isUnknownInputValue(v) ? 1 : 0), 0);
|
||||||
const confidentialOutputCount = this.tx.vout.reduce((acc, v) => acc + (v.value == null ? 1 : 0), 0);
|
const confidentialOutputCount = this.tx.vout.reduce((acc, v) => acc + (this.isUnknownOutputValue(v) ? 1 : 0), 0);
|
||||||
|
|
||||||
// if there are unknowns on both sides, the total is indeterminate, so we'll just fudge it
|
// if there are unknowns on both sides, the total is indeterminate, so we'll just fudge it
|
||||||
if (confidentialInputCount && confidentialOutputCount) {
|
if (confidentialInputCount && confidentialOutputCount) {
|
||||||
@@ -456,6 +461,34 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getOutputValue(v: Vout): number | void {
|
||||||
|
if (!v) {
|
||||||
|
return null;
|
||||||
|
} else if (this.isLiquid && v.asset !== this.nativeAssetId) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return v.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getInputValue(v: Vin): number | void {
|
||||||
|
if (!v?.prevout) {
|
||||||
|
return null;
|
||||||
|
} else if (this.isLiquid && v.prevout.asset !== this.nativeAssetId) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return v.prevout.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isUnknownInputValue(v: Vin): boolean {
|
||||||
|
return v?.prevout?.value == null || this.isLiquid && v?.prevout?.asset !== this.nativeAssetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
isUnknownOutputValue(v: Vout): boolean {
|
||||||
|
return v?.value == null || this.isLiquid && v?.asset !== this.nativeAssetId;
|
||||||
|
}
|
||||||
|
|
||||||
@HostListener('pointermove', ['$event'])
|
@HostListener('pointermove', ['$event'])
|
||||||
onPointerMove(event) {
|
onPointerMove(event) {
|
||||||
if (this.dir === 'rtl') {
|
if (this.dir === 'rtl') {
|
||||||
|
|||||||
@@ -8863,7 +8863,7 @@ export const faqData = [
|
|||||||
type: "endpoint",
|
type: "endpoint",
|
||||||
category: "advanced",
|
category: "advanced",
|
||||||
showConditions: bitcoinNetworks,
|
showConditions: bitcoinNetworks,
|
||||||
fragment: "how-big-is-mempool-used-by-mempool.space",
|
fragment: "how-big-is-mempool-used-by-mempool-space",
|
||||||
title: "How big is the mempool used by mempool.space?",
|
title: "How big is the mempool used by mempool.space?",
|
||||||
options: { officialOnly: true },
|
options: { officialOnly: true },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -207,7 +207,7 @@
|
|||||||
<p>When a Bitcoin transaction is made, it is stored in a Bitcoin node's mempool before it is confirmed into a block. When the rate of incoming transactions exceeds the rate transactions are confirmed, the mempool grows in size.</p><p>By default, Bitcoin Core allocates 300MB of memory for its mempool, so when a node's mempool grows big enough to use all 300MB of allocated memory, we say it's "full".</p><p>Once a node's mempool is using all of its allocated memory, it will start rejecting new transactions below a certain feerate threshold—so when this is the case, be extra sure to set a feerate that (at a minimum) exceeds that threshold. The current threshold feerate (and memory usage) are displayed right on Mempool's front page.</p>
|
<p>When a Bitcoin transaction is made, it is stored in a Bitcoin node's mempool before it is confirmed into a block. When the rate of incoming transactions exceeds the rate transactions are confirmed, the mempool grows in size.</p><p>By default, Bitcoin Core allocates 300MB of memory for its mempool, so when a node's mempool grows big enough to use all 300MB of allocated memory, we say it's "full".</p><p>Once a node's mempool is using all of its allocated memory, it will start rejecting new transactions below a certain feerate threshold—so when this is the case, be extra sure to set a feerate that (at a minimum) exceeds that threshold. The current threshold feerate (and memory usage) are displayed right on Mempool's front page.</p>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
<ng-template type="how-big-is-mempool-used-by-mempool.space">
|
<ng-template type="how-big-is-mempool-used-by-mempool-space">
|
||||||
<p>mempool.space uses multiple Bitcoin nodes to obtain data: some with the default 300MB mempool memory limit (call these Small Nodes) and others with a much larger mempool memory limit (call these Big Nodes).</p>
|
<p>mempool.space uses multiple Bitcoin nodes to obtain data: some with the default 300MB mempool memory limit (call these Small Nodes) and others with a much larger mempool memory limit (call these Big Nodes).</p>
|
||||||
<p>Many nodes on the Bitcoin network are configured to run with the default 300MB mempool memory setting. When all 300MB of memory are used up, such nodes will reject transactions below a certain threshold feerate. Running Small Nodes allows mempool.space to tell you what this threshold feerate is—this is the "Purging" feerate that shows on the front page when mempools are full, which you can use to be reasonably sure that your transaction will be widely propagated.</p>
|
<p>Many nodes on the Bitcoin network are configured to run with the default 300MB mempool memory setting. When all 300MB of memory are used up, such nodes will reject transactions below a certain threshold feerate. Running Small Nodes allows mempool.space to tell you what this threshold feerate is—this is the "Purging" feerate that shows on the front page when mempools are full, which you can use to be reasonably sure that your transaction will be widely propagated.</p>
|
||||||
<p>Big Node mempools are so big that they don't need to reject (or purge) transactions. Such nodes allow for mempool.space to provide you with information on any pending transaction it has received—no matter how congested the mempool is, and no matter how low-feerate or low-priority the transaction is.</p>
|
<p>Big Node mempools are so big that they don't need to reject (or purge) transactions. Such nodes allow for mempool.space to provide you with information on any pending transaction it has received—no matter how congested the mempool is, and no matter how low-feerate or low-priority the transaction is.</p>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<span class="green-color" *ngIf="blockConversion; else noblockconversion">
|
<span [class]="colorClass" *ngIf="blockConversion; else noblockconversion">
|
||||||
{{
|
{{
|
||||||
(
|
(
|
||||||
(blockConversion.price[currency] > -1 ? blockConversion.price[currency] : null) ??
|
(blockConversion.price[currency] > -1 ? blockConversion.price[currency] : null) ??
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
</span>
|
</span>
|
||||||
|
|
||||||
<ng-template #noblockconversion>
|
<ng-template #noblockconversion>
|
||||||
<span class="green-color" *ngIf="(conversions$ | async) as conversions">
|
<span [class]="colorClass" *ngIf="(conversions$ | async) as conversions">
|
||||||
{{ (conversions[currency] > -1 ? conversions[currency] : 0) * value / 100000000 | fiatCurrency : digitsInfo : currency }}
|
{{ (conversions[currency] > -1 ? conversions[currency] : 0) * value / 100000000 | fiatCurrency : digitsInfo : currency }}
|
||||||
</span>
|
</span>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
.green-color {
|
|
||||||
color: #3bcc49;
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@ import { StateService } from '../services/state.service';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-fiat',
|
selector: 'app-fiat',
|
||||||
templateUrl: './fiat.component.html',
|
templateUrl: './fiat.component.html',
|
||||||
styleUrls: ['./fiat.component.scss'],
|
styleUrls: [],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class FiatComponent implements OnInit, OnDestroy {
|
export class FiatComponent implements OnInit, OnDestroy {
|
||||||
@@ -17,6 +17,7 @@ export class FiatComponent implements OnInit, OnDestroy {
|
|||||||
@Input() value: number;
|
@Input() value: number;
|
||||||
@Input() digitsInfo = '1.2-2';
|
@Input() digitsInfo = '1.2-2';
|
||||||
@Input() blockConversion: Price;
|
@Input() blockConversion: Price;
|
||||||
|
@Input() colorClass = 'green-color';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private stateService: StateService,
|
private stateService: StateService,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md">
|
<div class="col-md table-col">
|
||||||
<a class="subtitle" [routerLink]="['/lightning/node' | relativeUrl, node.public_key]">{{ node.public_key }}</a>
|
<a class="subtitle" [routerLink]="['/lightning/node' | relativeUrl, node.public_key]">{{ node.public_key }}</a>
|
||||||
<table class="table table-borderless table-striped">
|
<table class="table table-borderless table-striped">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|||||||
@@ -18,6 +18,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.table-col {
|
||||||
|
max-width: calc(100% - 470px);
|
||||||
|
}
|
||||||
|
|
||||||
.map-col {
|
.map-col {
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
|||||||
@@ -12,20 +12,22 @@ export class StorageService {
|
|||||||
|
|
||||||
setDefaultValueIfNeeded(key: string, defaultValue: string) {
|
setDefaultValueIfNeeded(key: string, defaultValue: string) {
|
||||||
const graphWindowPreference: string = this.getValue(key);
|
const graphWindowPreference: string = this.getValue(key);
|
||||||
|
const fragment = window.location.hash.replace('#', '');
|
||||||
|
|
||||||
if (graphWindowPreference === null) { // First visit to mempool.space
|
if (graphWindowPreference === null) { // First visit to mempool.space
|
||||||
if (this.router.url.includes('graphs') && key === 'graphWindowPreference' ||
|
if (window.location.pathname.includes('graphs') && key === 'graphWindowPreference' ||
|
||||||
this.router.url.includes('pools') && key === 'miningWindowPreference'
|
window.location.pathname.includes('pools') && key === 'miningWindowPreference'
|
||||||
) {
|
) {
|
||||||
this.setValue(key, this.route.snapshot.fragment ? this.route.snapshot.fragment : defaultValue);
|
this.setValue(key, fragment ? fragment : defaultValue);
|
||||||
} else {
|
} else {
|
||||||
this.setValue(key, defaultValue);
|
this.setValue(key, defaultValue);
|
||||||
}
|
}
|
||||||
} else if (this.router.url.includes('graphs') && key === 'graphWindowPreference' ||
|
} else if (window.location.pathname.includes('graphs') && key === 'graphWindowPreference' ||
|
||||||
this.router.url.includes('pools') && key === 'miningWindowPreference'
|
window.location.pathname.includes('pools') && key === 'miningWindowPreference'
|
||||||
) {
|
) {
|
||||||
// Visit a different graphs#fragment from last visit
|
// Visit a different graphs#fragment from last visit
|
||||||
if (this.route.snapshot.fragment !== null && graphWindowPreference !== this.route.snapshot.fragment) {
|
if (fragment !== null && graphWindowPreference !== fragment) {
|
||||||
this.setValue(key, this.route.snapshot.fragment);
|
this.setValue(key, fragment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
<div class="container p-lg-0 pb-0" style="max-width: 100%; margin-top: 7px" *ngIf="storageService.getValue('hideWarning') !== 'hidden'">
|
||||||
|
<div class="alert alert-danger mb-0 text-center">
|
||||||
|
<div class="message-container" i18n="warning-testnet">This is a test network. Coins have no value.</div>
|
||||||
|
<button type="button" class="close" (click)="dismissWarning()">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
.alert-danger {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #b71c1c;
|
||||||
|
border-color: #b71c1c;
|
||||||
|
padding: 0.5rem 1.25rem;
|
||||||
|
margin: 0px 10px 0px 10px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-container {
|
||||||
|
display: flex;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
display: flex;
|
||||||
|
color: #fff;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
display: flex;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
position: relative;
|
||||||
|
top: -2px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||||
|
import { StorageService } from '../../../services/storage.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-testnet-alert',
|
||||||
|
templateUrl: './testnet-alert.component.html',
|
||||||
|
styleUrls: ['./testnet-alert.component.scss'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
|
})
|
||||||
|
export class TestnetAlertComponent {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public storageService: StorageService,
|
||||||
|
) { }
|
||||||
|
|
||||||
|
dismissWarning(): void {
|
||||||
|
this.storageService.setValue('hideWarning', 'hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -84,6 +84,7 @@ import { SearchResultsComponent } from '../components/search-form/search-results
|
|||||||
import { TimestampComponent } from './components/timestamp/timestamp.component';
|
import { TimestampComponent } from './components/timestamp/timestamp.component';
|
||||||
import { ToggleComponent } from './components/toggle/toggle.component';
|
import { ToggleComponent } from './components/toggle/toggle.component';
|
||||||
import { GeolocationComponent } from '../shared/components/geolocation/geolocation.component';
|
import { GeolocationComponent } from '../shared/components/geolocation/geolocation.component';
|
||||||
|
import { TestnetAlertComponent } from './components/testnet-alert/testnet-alert.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@@ -162,6 +163,7 @@ import { GeolocationComponent } from '../shared/components/geolocation/geolocati
|
|||||||
TimestampComponent,
|
TimestampComponent,
|
||||||
ToggleComponent,
|
ToggleComponent,
|
||||||
GeolocationComponent,
|
GeolocationComponent,
|
||||||
|
TestnetAlertComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
|||||||
@@ -3203,6 +3203,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
|
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> الكتل المتوقعة </target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">13</context>
|
<context context-type="linenumber">13</context>
|
||||||
@@ -3211,6 +3212,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
|
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/>الكتله المتوقعه </target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">14</context>
|
<context context-type="linenumber">14</context>
|
||||||
@@ -3219,6 +3221,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
|
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/>الكتل المعدنه </target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">18</context>
|
<context context-type="linenumber">18</context>
|
||||||
@@ -3227,6 +3230,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
|
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/>الكتله المعدنه</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">19</context>
|
<context context-type="linenumber">19</context>
|
||||||
@@ -3235,6 +3239,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
|
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/>الكتل المتبقية</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">24</context>
|
<context context-type="linenumber">24</context>
|
||||||
@@ -3243,6 +3248,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
|
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/>الكتلة المتبقية</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">25</context>
|
<context context-type="linenumber">25</context>
|
||||||
@@ -3251,6 +3257,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
|
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/>كتل قادمه</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">29</context>
|
<context context-type="linenumber">29</context>
|
||||||
@@ -3259,6 +3266,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
|
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/>كتله قادمه</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">30</context>
|
<context context-type="linenumber">30</context>
|
||||||
@@ -3267,6 +3275,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
|
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/>كتل وراء</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">34</context>
|
<context context-type="linenumber">34</context>
|
||||||
@@ -3275,6 +3284,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
|
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/>كتله وراء</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">35</context>
|
<context context-type="linenumber">35</context>
|
||||||
@@ -3283,6 +3293,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
|
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
|
||||||
<source>Average block time</source>
|
<source>Average block time</source>
|
||||||
|
<target>متوسط وقت الكتل</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
|
||||||
<context context-type="linenumber">42,45</context>
|
<context context-type="linenumber">42,45</context>
|
||||||
@@ -3984,6 +3995,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="312539377512157124" datatype="html">
|
<trans-unit id="312539377512157124" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
|
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="i"/>كتل</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
||||||
<context context-type="linenumber">165,163</context>
|
<context context-type="linenumber">165,163</context>
|
||||||
@@ -4003,6 +4015,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3666195172774554282" datatype="html">
|
<trans-unit id="3666195172774554282" datatype="html">
|
||||||
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
|
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
|
||||||
|
<target>اخرى (<x id="PH" equiv-text="percentage"/>)</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
||||||
<context context-type="linenumber">201</context>
|
<context context-type="linenumber">201</context>
|
||||||
@@ -4565,6 +4578,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="time-until" datatype="html">
|
<trans-unit id="time-until" datatype="html">
|
||||||
<source>In ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></source>
|
<source>In ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></source>
|
||||||
|
<target>في ~ <x id="DATE" equiv-text="dateStrings.i18nYear"/></target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
|
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
|
||||||
<context context-type="linenumber">126</context>
|
<context context-type="linenumber">126</context>
|
||||||
@@ -5348,6 +5362,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8f2791f5d9656271dd6c385f5ad572716e90f4a2" datatype="html">
|
<trans-unit id="8f2791f5d9656271dd6c385f5ad572716e90f4a2" datatype="html">
|
||||||
<source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="mempool.space merely provides data about the Bitcoin network.</b> It cannot help you with"/>mempool.space merely provides data about the Bitcoin network.<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="</b>"/> It cannot help you with retrieving funds, confirming your transaction quicker, etc.</source>
|
<source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="mempool.space merely provides data about the Bitcoin network.</b> It cannot help you with"/>mempool.space merely provides data about the Bitcoin network.<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="</b>"/> It cannot help you with retrieving funds, confirming your transaction quicker, etc.</source>
|
||||||
|
<target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="mempool.space merely provides data about the Bitcoin network.</b> It cannot help you with"/>يوفر mempool.space بيانات حول شبكة البتكوين. <x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="</b>"/> لا يمكننا مساعدتك في استرداد الأموال ، وتأكيد معاملتك بشكل أسرع ، وما إلى ذلك.</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/docs/api-docs/api-docs.component.html</context>
|
<context context-type="sourcefile">src/app/docs/api-docs/api-docs.component.html</context>
|
||||||
<context context-type="linenumber">13</context>
|
<context context-type="linenumber">13</context>
|
||||||
@@ -5873,6 +5888,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="96508700250272816" datatype="html">
|
<trans-unit id="96508700250272816" datatype="html">
|
||||||
<source>Force closed with penalty</source>
|
<source>Force closed with penalty</source>
|
||||||
|
<target>أغلقت بالقوة هناك خطآ</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channel/closing-type/closing-type.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/channel/closing-type/closing-type.component.ts</context>
|
||||||
<context context-type="linenumber">28</context>
|
<context context-type="linenumber">28</context>
|
||||||
@@ -6006,6 +6022,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="cfcc7201138b0ef9901e9604c35f550e91629295" datatype="html">
|
<trans-unit id="cfcc7201138b0ef9901e9604c35f550e91629295" datatype="html">
|
||||||
<source>avg</source>
|
<source>avg</source>
|
||||||
|
<target>متوسط</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">3,5</context>
|
<context context-type="linenumber">3,5</context>
|
||||||
@@ -6014,6 +6031,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ba9117dcc11814c44437cf9d7561874ba8b98a2a" datatype="html">
|
<trans-unit id="ba9117dcc11814c44437cf9d7561874ba8b98a2a" datatype="html">
|
||||||
<source>med</source>
|
<source>med</source>
|
||||||
|
<target>متوسط</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">6,9</context>
|
<context context-type="linenumber">6,9</context>
|
||||||
@@ -6408,6 +6426,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="7254919336112973896" datatype="html">
|
<trans-unit id="7254919336112973896" datatype="html">
|
||||||
<source>Outgoing Fees</source>
|
<source>Outgoing Fees</source>
|
||||||
|
<target>الرسوم الصادرة</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node-fee-chart/node-fee-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/node-fee-chart/node-fee-chart.component.ts</context>
|
||||||
<context context-type="linenumber">170</context>
|
<context context-type="linenumber">170</context>
|
||||||
@@ -6419,6 +6438,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="484887099976974152" datatype="html">
|
<trans-unit id="484887099976974152" datatype="html">
|
||||||
<source>Incoming Fees</source>
|
<source>Incoming Fees</source>
|
||||||
|
<target>رسوم واردة</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node-fee-chart/node-fee-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/node-fee-chart/node-fee-chart.component.ts</context>
|
||||||
<context context-type="linenumber">178</context>
|
<context context-type="linenumber">178</context>
|
||||||
@@ -6706,6 +6726,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="599038141003770125" datatype="html">
|
<trans-unit id="599038141003770125" datatype="html">
|
||||||
<source>Clearnet and Darknet</source>
|
<source>Clearnet and Darknet</source>
|
||||||
|
<target>كليرنت ودارك نت</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
||||||
<context context-type="linenumber">164,161</context>
|
<context context-type="linenumber">164,161</context>
|
||||||
@@ -6717,6 +6738,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1282458597026430784" datatype="html">
|
<trans-unit id="1282458597026430784" datatype="html">
|
||||||
<source>Clearnet Only (IPv4, IPv6)</source>
|
<source>Clearnet Only (IPv4, IPv6)</source>
|
||||||
|
<target>كليرنت فقط (IPv4 ، IPv6)</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
||||||
<context context-type="linenumber">185,182</context>
|
<context context-type="linenumber">185,182</context>
|
||||||
@@ -6728,6 +6750,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2165336009914523952" datatype="html">
|
<trans-unit id="2165336009914523952" datatype="html">
|
||||||
<source>Darknet Only (Tor, I2P, cjdns)</source>
|
<source>Darknet Only (Tor, I2P, cjdns)</source>
|
||||||
|
<target>الداركنت فقط (Tor، I2P، cjdns)</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
||||||
<context context-type="linenumber">206,203</context>
|
<context context-type="linenumber">206,203</context>
|
||||||
@@ -6752,6 +6775,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5222540403093176126" datatype="html">
|
<trans-unit id="5222540403093176126" datatype="html">
|
||||||
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
|
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
|
||||||
|
<target><x id="PH" equiv-text="nodeCount"/>العقد</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
|
||||||
<context context-type="linenumber">104,103</context>
|
<context context-type="linenumber">104,103</context>
|
||||||
|
|||||||
@@ -3235,6 +3235,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
|
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
|
||||||
|
<target>zbývá <x id="INTERPOLATION" equiv-text="{{ i }}"/> bloků</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">24</context>
|
<context context-type="linenumber">24</context>
|
||||||
@@ -3243,6 +3244,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
|
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
|
||||||
|
<target>zbývá <x id="INTERPOLATION" equiv-text="{{ i }}"/> blok</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">25</context>
|
<context context-type="linenumber">25</context>
|
||||||
@@ -3251,6 +3253,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
|
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
|
||||||
|
<target>za <x id="INTERPOLATION" equiv-text="{{ i }}"/> bloků</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">29</context>
|
<context context-type="linenumber">29</context>
|
||||||
@@ -3259,6 +3262,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
|
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
|
||||||
|
<target>za <x id="INTERPOLATION" equiv-text="{{ i }}"/> blok</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">30</context>
|
<context context-type="linenumber">30</context>
|
||||||
@@ -3267,6 +3271,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
|
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
|
||||||
|
<target>Před <x id="INTERPOLATION" equiv-text="{{ i }}"/> bloků</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">34</context>
|
<context context-type="linenumber">34</context>
|
||||||
@@ -3275,6 +3280,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
|
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
|
||||||
|
<target>Před <x id="INTERPOLATION" equiv-text="{{ i }}"/> blok</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">35</context>
|
<context context-type="linenumber">35</context>
|
||||||
@@ -3283,6 +3289,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
|
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
|
||||||
<source>Average block time</source>
|
<source>Average block time</source>
|
||||||
|
<target>Průměrná perioda bloků</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
|
||||||
<context context-type="linenumber">42,45</context>
|
<context context-type="linenumber">42,45</context>
|
||||||
@@ -3984,6 +3991,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="312539377512157124" datatype="html">
|
<trans-unit id="312539377512157124" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
|
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="i"/> bloků</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
||||||
<context context-type="linenumber">165,163</context>
|
<context context-type="linenumber">165,163</context>
|
||||||
@@ -4505,7 +4513,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="time-since" datatype="html">
|
<trans-unit id="time-since" datatype="html">
|
||||||
<source><x id="DATE" equiv-text="dateStrings.i18nYear"/> ago</source>
|
<source><x id="DATE" equiv-text="dateStrings.i18nYear"/> ago</source>
|
||||||
<target>před <x id="DATE" equiv-text="dateStrings.i18nYear"/></target>
|
<target>Před <x id="DATE" equiv-text="dateStrings.i18nYear"/></target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
|
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
|
||||||
<context context-type="linenumber">103</context>
|
<context context-type="linenumber">103</context>
|
||||||
@@ -7104,7 +7112,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="date-base.minute" datatype="html">
|
<trans-unit id="date-base.minute" datatype="html">
|
||||||
<source><x id="DATE" equiv-text="counter"/> minute</source>
|
<source><x id="DATE" equiv-text="counter"/> minute</source>
|
||||||
<target><x id="DATE" equiv-text="counter"/> minuta</target>
|
<target><x id="DATE" equiv-text="counter"/> min</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
|
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
|
||||||
<context context-type="linenumber">13</context>
|
<context context-type="linenumber">13</context>
|
||||||
@@ -7112,7 +7120,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="date-base.minutes" datatype="html">
|
<trans-unit id="date-base.minutes" datatype="html">
|
||||||
<source><x id="DATE" equiv-text="counter"/> minutes</source>
|
<source><x id="DATE" equiv-text="counter"/> minutes</source>
|
||||||
<target><x id="DATE" equiv-text="counter"/> minuty</target>
|
<target><x id="DATE" equiv-text="counter"/> min</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
|
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
|
||||||
<context context-type="linenumber">14</context>
|
<context context-type="linenumber">14</context>
|
||||||
|
|||||||
@@ -3203,6 +3203,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
|
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blokke forventes</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">13</context>
|
<context context-type="linenumber">13</context>
|
||||||
@@ -3211,6 +3212,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
|
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blok forventet</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">14</context>
|
<context context-type="linenumber">14</context>
|
||||||
@@ -3219,6 +3221,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
|
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blokke fundet</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">18</context>
|
<context context-type="linenumber">18</context>
|
||||||
@@ -3227,6 +3230,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
|
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blok fundet</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">19</context>
|
<context context-type="linenumber">19</context>
|
||||||
@@ -3235,6 +3239,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
|
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blokke tilbage</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">24</context>
|
<context context-type="linenumber">24</context>
|
||||||
@@ -3243,6 +3248,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
|
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blok tilbage</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">25</context>
|
<context context-type="linenumber">25</context>
|
||||||
@@ -3251,6 +3257,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
|
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blokke foran</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">29</context>
|
<context context-type="linenumber">29</context>
|
||||||
@@ -3259,6 +3266,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
|
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blok foran</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">30</context>
|
<context context-type="linenumber">30</context>
|
||||||
@@ -3267,6 +3275,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
|
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blokke bagved</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">34</context>
|
<context context-type="linenumber">34</context>
|
||||||
@@ -3275,6 +3284,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
|
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
|
||||||
|
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> blok bagved</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">35</context>
|
<context context-type="linenumber">35</context>
|
||||||
|
|||||||
@@ -432,7 +432,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="07193288a0312875e18f38c3a2486b927a15520a" datatype="html">
|
<trans-unit id="07193288a0312875e18f38c3a2486b927a15520a" datatype="html">
|
||||||
<source>Timestamp</source>
|
<source>Timestamp</source>
|
||||||
<target>Sello de tiempo</target>
|
<target>Timestamp</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/bisq/bisq-block/bisq-block.component.html</context>
|
<context context-type="sourcefile">src/app/bisq/bisq-block/bisq-block.component.html</context>
|
||||||
<context context-type="linenumber">23</context>
|
<context context-type="linenumber">23</context>
|
||||||
@@ -1440,7 +1440,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4b137ec8bf73a47063740b75c0c40d5fd3c48015" datatype="html">
|
<trans-unit id="4b137ec8bf73a47063740b75c0c40d5fd3c48015" datatype="html">
|
||||||
<source>The Mempool Open Source Project</source>
|
<source>The Mempool Open Source Project</source>
|
||||||
<target>Proyecto de Código Abierto The Mempool</target>
|
<target>El proyecto de código abierto Mempool</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
|
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
|
||||||
<context context-type="linenumber">12,13</context>
|
<context context-type="linenumber">12,13</context>
|
||||||
@@ -3355,7 +3355,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ee847b69ef2dc81bb3e9b8cd30f02f8d63adbe07" datatype="html">
|
<trans-unit id="ee847b69ef2dc81bb3e9b8cd30f02f8d63adbe07" datatype="html">
|
||||||
<source>Medium Priority</source>
|
<source>Medium Priority</source>
|
||||||
<target>Prioridad media</target>
|
<target>Media prioridad</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/fees-box/fees-box.component.html</context>
|
<context context-type="sourcefile">src/app/components/fees-box/fees-box.component.html</context>
|
||||||
<context context-type="linenumber">9,10</context>
|
<context context-type="linenumber">9,10</context>
|
||||||
|
|||||||
@@ -3549,7 +3549,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8573a1576789bd2c4faeaed23037c4917812c6cf" datatype="html">
|
<trans-unit id="8573a1576789bd2c4faeaed23037c4917812c6cf" datatype="html">
|
||||||
<source>Lightning Nodes Per ISP</source>
|
<source>Lightning Nodes Per ISP</source>
|
||||||
<target>צמתי ברק לפי ספקי תשתית</target>
|
<target>צמתי ברק לפי ספקיות</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/graphs/graphs.component.html</context>
|
<context context-type="sourcefile">src/app/components/graphs/graphs.component.html</context>
|
||||||
<context context-type="linenumber">37</context>
|
<context context-type="linenumber">37</context>
|
||||||
@@ -3717,6 +3717,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="142e923d3b04186ac6ba23387265d22a2fa404e0" datatype="html">
|
<trans-unit id="142e923d3b04186ac6ba23387265d22a2fa404e0" datatype="html">
|
||||||
<source>Lightning Explorer</source>
|
<source>Lightning Explorer</source>
|
||||||
|
<target>חוקר רשת הברק</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/master-page/master-page.component.html</context>
|
<context context-type="sourcefile">src/app/components/master-page/master-page.component.html</context>
|
||||||
<context context-type="linenumber">44,47</context>
|
<context context-type="linenumber">44,47</context>
|
||||||
@@ -4370,6 +4371,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="7deec1c1520f06170e1f8e8ddfbe4532312f638f" datatype="html">
|
<trans-unit id="7deec1c1520f06170e1f8e8ddfbe4532312f638f" datatype="html">
|
||||||
<source>Explore the full Bitcoin ecosystem</source>
|
<source>Explore the full Bitcoin ecosystem</source>
|
||||||
|
<target>חקור את מרחב רשתות הביטקוין</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/search-form/search-form.component.html</context>
|
<context context-type="sourcefile">src/app/components/search-form/search-form.component.html</context>
|
||||||
<context context-type="linenumber">4,5</context>
|
<context context-type="linenumber">4,5</context>
|
||||||
@@ -5373,6 +5375,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="cd2330c7e9c74256f6a91e83bccf10e2905f8556" datatype="html">
|
<trans-unit id="cd2330c7e9c74256f6a91e83bccf10e2905f8556" datatype="html">
|
||||||
<source>REST API service</source>
|
<source>REST API service</source>
|
||||||
|
<target>שירותי API</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/docs/api-docs/api-docs.component.html</context>
|
<context context-type="sourcefile">src/app/docs/api-docs/api-docs.component.html</context>
|
||||||
<context context-type="linenumber">42,43</context>
|
<context context-type="linenumber">42,43</context>
|
||||||
@@ -5491,6 +5494,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6acd06bd5a3af583cd46c6d9f7954d7a2b44095e" datatype="html">
|
<trans-unit id="6acd06bd5a3af583cd46c6d9f7954d7a2b44095e" datatype="html">
|
||||||
<source>mSats</source>
|
<source>mSats</source>
|
||||||
|
<target>מיליסאטס</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
||||||
<context context-type="linenumber">35</context>
|
<context context-type="linenumber">35</context>
|
||||||
@@ -5547,6 +5551,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="055060668d0b9902c37abfb6168a08a36eba4496" datatype="html">
|
<trans-unit id="055060668d0b9902c37abfb6168a08a36eba4496" datatype="html">
|
||||||
<source>Min HTLC</source>
|
<source>Min HTLC</source>
|
||||||
|
<target>HTLC מינימלי</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
||||||
<context context-type="linenumber">57</context>
|
<context context-type="linenumber">57</context>
|
||||||
@@ -5555,6 +5560,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="c3d94c1a5aef6211f4a902027bd08540d7222b0d" datatype="html">
|
<trans-unit id="c3d94c1a5aef6211f4a902027bd08540d7222b0d" datatype="html">
|
||||||
<source>Max HTLC</source>
|
<source>Max HTLC</source>
|
||||||
|
<target>HTLC מקסימלי</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
||||||
<context context-type="linenumber">63</context>
|
<context context-type="linenumber">63</context>
|
||||||
@@ -5751,6 +5757,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8fd0077b032e360ece45c4fd655f85b2400dcb83" datatype="html">
|
<trans-unit id="8fd0077b032e360ece45c4fd655f85b2400dcb83" datatype="html">
|
||||||
<source>ppm</source>
|
<source>ppm</source>
|
||||||
|
<target>פפ"מ</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channel/channel-preview.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channel/channel-preview.component.html</context>
|
||||||
<context context-type="linenumber">34,35</context>
|
<context context-type="linenumber">34,35</context>
|
||||||
@@ -6059,6 +6066,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="db1f0c0605ab0c4a904523635982253ff72eed40" datatype="html">
|
<trans-unit id="db1f0c0605ab0c4a904523635982253ff72eed40" datatype="html">
|
||||||
<source>The average fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm</source>
|
<source>The average fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm</source>
|
||||||
|
<target>ממוצע העמלות שנגבה בידי צמתי ניתוב, בהתעלמות מתעריף העמלה > 0.5% או 5000 פפ"מ</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">28,30</context>
|
<context context-type="linenumber">28,30</context>
|
||||||
@@ -6080,6 +6088,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="0a46218f4a7b17b6445460898d75ab78e7e7979b" datatype="html">
|
<trans-unit id="0a46218f4a7b17b6445460898d75ab78e7e7979b" datatype="html">
|
||||||
<source>The average base fee charged by routing nodes, ignoring base fees > 5000ppm</source>
|
<source>The average base fee charged by routing nodes, ignoring base fees > 5000ppm</source>
|
||||||
|
<target>ממוצע העמלות שנגבה בידי צמתי ניתוב, בהתעלמות מתעריף העמלה > 5000 פפ"מ</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">43,45</context>
|
<context context-type="linenumber">43,45</context>
|
||||||
@@ -6106,6 +6115,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="cb4dae32e1b4d6a2ba6287d9f7bd859ca7259468" datatype="html">
|
<trans-unit id="cb4dae32e1b4d6a2ba6287d9f7bd859ca7259468" datatype="html">
|
||||||
<source>The median fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm</source>
|
<source>The median fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm</source>
|
||||||
|
<target>חציון העמלות שנגבה בידי צמתי ניתוב, בהתעלמות תעריף העמלה > 0.5% או 5000 פפ"מ</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">74,76</context>
|
<context context-type="linenumber">74,76</context>
|
||||||
@@ -6123,6 +6133,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="b8539025268617abfcab1c3f2a2c60cd8d7485fb" datatype="html">
|
<trans-unit id="b8539025268617abfcab1c3f2a2c60cd8d7485fb" datatype="html">
|
||||||
<source>The median base fee charged by routing nodes, ignoring base fees > 5000ppm</source>
|
<source>The median base fee charged by routing nodes, ignoring base fees > 5000ppm</source>
|
||||||
|
<target>חציון העמלות שנגבה על ידי צמתי ניתוב, בהתעלמות מבסיס העמלה > 5000 פפ"מ</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">89,91</context>
|
<context context-type="linenumber">89,91</context>
|
||||||
@@ -6368,6 +6379,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2d9883d230a47fbbb2ec969e32a186597ea27405" datatype="html">
|
<trans-unit id="2d9883d230a47fbbb2ec969e32a186597ea27405" datatype="html">
|
||||||
<source>Liquidity Ranking</source>
|
<source>Liquidity Ranking</source>
|
||||||
|
<target>דירוג נזילות</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/lightning-dashboard/lightning-dashboard.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/lightning-dashboard/lightning-dashboard.component.html</context>
|
||||||
<context context-type="linenumber">62</context>
|
<context context-type="linenumber">62</context>
|
||||||
@@ -6392,6 +6404,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="c50bf442cf99f6fc5f8b687c460f33234b879869" datatype="html">
|
<trans-unit id="c50bf442cf99f6fc5f8b687c460f33234b879869" datatype="html">
|
||||||
<source>Connectivity Ranking</source>
|
<source>Connectivity Ranking</source>
|
||||||
|
<target>דירוג חיבוריות</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/lightning-dashboard/lightning-dashboard.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/lightning-dashboard/lightning-dashboard.component.html</context>
|
||||||
<context context-type="linenumber">76</context>
|
<context context-type="linenumber">76</context>
|
||||||
@@ -6533,7 +6546,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5b9904cb31f6f28314443f6385dc5facab7ea851" datatype="html">
|
<trans-unit id="5b9904cb31f6f28314443f6385dc5facab7ea851" datatype="html">
|
||||||
<source>ISP</source>
|
<source>ISP</source>
|
||||||
<target>ספק אינטרנט</target>
|
<target>רשת גלויה</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
||||||
<context context-type="linenumber">89,90</context>
|
<context context-type="linenumber">89,90</context>
|
||||||
@@ -6555,6 +6568,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="e128630e07a4c467f51b246a31c5734d5fb1a2c2" datatype="html">
|
<trans-unit id="e128630e07a4c467f51b246a31c5734d5fb1a2c2" datatype="html">
|
||||||
<source>Liquidity ad</source>
|
<source>Liquidity ad</source>
|
||||||
|
<target>פרסומת ליקווידיטי</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
||||||
<context context-type="linenumber">141,144</context>
|
<context context-type="linenumber">141,144</context>
|
||||||
@@ -6563,6 +6577,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="bc84b5a9a70217104a53c7139e30b392be6520b7" datatype="html">
|
<trans-unit id="bc84b5a9a70217104a53c7139e30b392be6520b7" datatype="html">
|
||||||
<source>Lease fee rate</source>
|
<source>Lease fee rate</source>
|
||||||
|
<target>שיעור עמלת שכירות</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
||||||
<context context-type="linenumber">147,150</context>
|
<context context-type="linenumber">147,150</context>
|
||||||
@@ -6572,6 +6587,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ee807dd54b4a45eeba284744c64774de1ab5e4f1" datatype="html">
|
<trans-unit id="ee807dd54b4a45eeba284744c64774de1ab5e4f1" datatype="html">
|
||||||
<source>Lease base fee</source>
|
<source>Lease base fee</source>
|
||||||
|
<target>עמלת בסיס לשכירות</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
||||||
<context context-type="linenumber">155,157</context>
|
<context context-type="linenumber">155,157</context>
|
||||||
@@ -6608,6 +6624,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="e8e09fa12864e94f094a2a7c8c97cfdf0cff8aab" datatype="html">
|
<trans-unit id="e8e09fa12864e94f094a2a7c8c97cfdf0cff8aab" datatype="html">
|
||||||
<source>Compact lease</source>
|
<source>Compact lease</source>
|
||||||
|
<target>שכירות קומפקטית</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
||||||
<context context-type="linenumber">191,193</context>
|
<context context-type="linenumber">191,193</context>
|
||||||
@@ -6616,6 +6633,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="aa687f4987e2d4e0010be692d402174962ece70e" datatype="html">
|
<trans-unit id="aa687f4987e2d4e0010be692d402174962ece70e" datatype="html">
|
||||||
<source>TLV extension records</source>
|
<source>TLV extension records</source>
|
||||||
|
<target>תיעוד TLV מורחב</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
||||||
<context context-type="linenumber">202,205</context>
|
<context context-type="linenumber">202,205</context>
|
||||||
@@ -6671,6 +6689,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8199511328474154549" datatype="html">
|
<trans-unit id="8199511328474154549" datatype="html">
|
||||||
<source>Lightning Nodes Channels World Map</source>
|
<source>Lightning Nodes Channels World Map</source>
|
||||||
|
<target>מפת ערוצי רשת הברק העולמית</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts</context>
|
||||||
<context context-type="linenumber">69</context>
|
<context context-type="linenumber">69</context>
|
||||||
@@ -6793,6 +6812,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4498ec29c37744fef46809ebc3db67c5fb789917" datatype="html">
|
<trans-unit id="4498ec29c37744fef46809ebc3db67c5fb789917" datatype="html">
|
||||||
<source>ISP Count</source>
|
<source>ISP Count</source>
|
||||||
|
<target>כמות ספקיות</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-country/nodes-per-country.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-country/nodes-per-country.component.html</context>
|
||||||
<context context-type="linenumber">34,38</context>
|
<context context-type="linenumber">34,38</context>
|
||||||
@@ -6801,6 +6821,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="90a6a964ba53464578003e3b4b2873ef5d2132a1" datatype="html">
|
<trans-unit id="90a6a964ba53464578003e3b4b2873ef5d2132a1" datatype="html">
|
||||||
<source>Top ISP</source>
|
<source>Top ISP</source>
|
||||||
|
<target>ספקיות מובילות</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-country/nodes-per-country.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-country/nodes-per-country.component.html</context>
|
||||||
<context context-type="linenumber">38,40</context>
|
<context context-type="linenumber">38,40</context>
|
||||||
@@ -6830,6 +6851,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ccabb31683868066778a1d664aa53ee9fcf77d6b" datatype="html">
|
<trans-unit id="ccabb31683868066778a1d664aa53ee9fcf77d6b" datatype="html">
|
||||||
<source>How much liquidity is running on nodes advertising at least one clearnet IP address</source>
|
<source>How much liquidity is running on nodes advertising at least one clearnet IP address</source>
|
||||||
|
<target>כמה ליקווידיטי רץ על צמתים המפרסמים לפחות כתובת IP גלויה אחת</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
||||||
<context context-type="linenumber">8,9</context>
|
<context context-type="linenumber">8,9</context>
|
||||||
@@ -6851,6 +6873,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="26fb07e8754b87bba4bf12c5137ffa77dac389a8" datatype="html">
|
<trans-unit id="26fb07e8754b87bba4bf12c5137ffa77dac389a8" datatype="html">
|
||||||
<source>How much liquidity is running on nodes which ISP was not identifiable</source>
|
<source>How much liquidity is running on nodes which ISP was not identifiable</source>
|
||||||
|
<target>כמה ליקווידיטי רץ על צמתים ללא ספקית רשת מזוהה</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
||||||
<context context-type="linenumber">15,16</context>
|
<context context-type="linenumber">15,16</context>
|
||||||
@@ -6872,6 +6895,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="23549ef4e1f846f06abcf07ceecb115945a0cf61" datatype="html">
|
<trans-unit id="23549ef4e1f846f06abcf07ceecb115945a0cf61" datatype="html">
|
||||||
<source>How much liquidity is running on nodes advertising only Tor addresses</source>
|
<source>How much liquidity is running on nodes advertising only Tor addresses</source>
|
||||||
|
<target>כמה ליקווידיטי רץ על צמתים המפרסמים כתובות תור בלבד</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
||||||
<context context-type="linenumber">22,23</context>
|
<context context-type="linenumber">22,23</context>
|
||||||
@@ -6880,6 +6904,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="e008f2a76179fdcd7110b41ca624131f91075949" datatype="html">
|
<trans-unit id="e008f2a76179fdcd7110b41ca624131f91075949" datatype="html">
|
||||||
<source>Top 100 ISPs hosting LN nodes</source>
|
<source>Top 100 ISPs hosting LN nodes</source>
|
||||||
|
<target>100 הספקיות המובילות באיחסון צמתי רשת הברק</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
||||||
<context context-type="linenumber">31,33</context>
|
<context context-type="linenumber">31,33</context>
|
||||||
@@ -6900,6 +6925,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="c18497e4f0db0d0ad0c71ba294295f42b3d312c9" datatype="html">
|
<trans-unit id="c18497e4f0db0d0ad0c71ba294295f42b3d312c9" datatype="html">
|
||||||
<source>Lightning ISP</source>
|
<source>Lightning ISP</source>
|
||||||
|
<target>ספקיות ברק</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.html</context>
|
||||||
<context context-type="linenumber">3,5</context>
|
<context context-type="linenumber">3,5</context>
|
||||||
@@ -6930,6 +6956,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5735693498020397727" datatype="html">
|
<trans-unit id="5735693498020397727" datatype="html">
|
||||||
<source>Lightning nodes on ISP: <x id="PH" equiv-text="response.isp"/> [AS<x id="PH_1" equiv-text="this.route.snapshot.params.isp"/>]</source>
|
<source>Lightning nodes on ISP: <x id="PH" equiv-text="response.isp"/> [AS<x id="PH_1" equiv-text="this.route.snapshot.params.isp"/>]</source>
|
||||||
|
<target>צמתי ברק אצל ספקיות: <x id="PH" equiv-text="response.isp"/> [כ <x id="PH_1" equiv-text="this.route.snapshot.params.isp"/>]</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.ts</context>
|
||||||
<context context-type="linenumber">44</context>
|
<context context-type="linenumber">44</context>
|
||||||
@@ -6941,6 +6968,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="d82f436f033a7d81680b8430275f94dda530151c" datatype="html">
|
<trans-unit id="d82f436f033a7d81680b8430275f94dda530151c" datatype="html">
|
||||||
<source>Lightning nodes on ISP: <x id="INTERPOLATION" equiv-text="{{ isp?.name }}"/></source>
|
<source>Lightning nodes on ISP: <x id="INTERPOLATION" equiv-text="{{ isp?.name }}"/></source>
|
||||||
|
<target>צמתי ברק ברשת הגלויה: <x id="INTERPOLATION" equiv-text="{{ isp?.name }}"/></target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp.component.html</context>
|
||||||
<context context-type="linenumber">2,4</context>
|
<context context-type="linenumber">2,4</context>
|
||||||
@@ -6949,6 +6977,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ca0b795795658155d44ddca02e95f1feeeb4a88f" datatype="html">
|
<trans-unit id="ca0b795795658155d44ddca02e95f1feeeb4a88f" datatype="html">
|
||||||
<source>ASN</source>
|
<source>ASN</source>
|
||||||
|
<target>ASN</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp.component.html</context>
|
||||||
<context context-type="linenumber">11,14</context>
|
<context context-type="linenumber">11,14</context>
|
||||||
|
|||||||
@@ -3203,6 +3203,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
|
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blokkra várva</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">13</context>
|
<context context-type="linenumber">13</context>
|
||||||
@@ -3211,6 +3212,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
|
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blokk várva</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">14</context>
|
<context context-type="linenumber">14</context>
|
||||||
@@ -3219,6 +3221,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
|
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blokk bányászva</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">18</context>
|
<context context-type="linenumber">18</context>
|
||||||
@@ -3227,6 +3230,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
|
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blokk bányászva</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">19</context>
|
<context context-type="linenumber">19</context>
|
||||||
@@ -3667,6 +3671,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5ee5eb7db86675abd5f0b0db835bf362ee9b23ff" datatype="html">
|
<trans-unit id="5ee5eb7db86675abd5f0b0db835bf362ee9b23ff" datatype="html">
|
||||||
<source>Indexing network hashrate</source>
|
<source>Indexing network hashrate</source>
|
||||||
|
<target>Hálózati hashrate indexelése</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/indexing-progress/indexing-progress.component.html</context>
|
<context context-type="sourcefile">src/app/components/indexing-progress/indexing-progress.component.html</context>
|
||||||
<context context-type="linenumber">2</context>
|
<context context-type="linenumber">2</context>
|
||||||
@@ -3881,6 +3886,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="500e13dffc7300bf7e4822a6bbf29a71a55d7b75" datatype="html">
|
<trans-unit id="500e13dffc7300bf7e4822a6bbf29a71a55d7b75" datatype="html">
|
||||||
<source>How many unique pools found at least one block over the past week.</source>
|
<source>How many unique pools found at least one block over the past week.</source>
|
||||||
|
<target>Hány egyedi pool talált legalább egy blokkot az elmúlt héten.</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
|
||||||
<context context-type="linenumber">19,23</context>
|
<context context-type="linenumber">19,23</context>
|
||||||
@@ -3906,6 +3912,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="c9e8defa185fa8e342548958bf206de97afc97a6" datatype="html">
|
<trans-unit id="c9e8defa185fa8e342548958bf206de97afc97a6" datatype="html">
|
||||||
<source>The number of blocks found over the past week.</source>
|
<source>The number of blocks found over the past week.</source>
|
||||||
|
<target>Az elmúlt héten talált blokkok száma.</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
|
||||||
<context context-type="linenumber">27,31</context>
|
<context context-type="linenumber">27,31</context>
|
||||||
@@ -4278,6 +4285,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="79b0842a2010172290ad09062bf51f09d8842f65" datatype="html">
|
<trans-unit id="79b0842a2010172290ad09062bf51f09d8842f65" datatype="html">
|
||||||
<source>Amount being paid to miners in the past 144 blocks</source>
|
<source>Amount being paid to miners in the past 144 blocks</source>
|
||||||
|
<target>A bányászoknak fizetett összeg az elmúlt 144 blokkban</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context>
|
<context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context>
|
||||||
<context context-type="linenumber">6,8</context>
|
<context context-type="linenumber">6,8</context>
|
||||||
@@ -4299,6 +4307,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="a0d4ab5b063e7be1c9ea980f5fd6ce1b5384ad0b" datatype="html">
|
<trans-unit id="a0d4ab5b063e7be1c9ea980f5fd6ce1b5384ad0b" datatype="html">
|
||||||
<source>Average fees per block in the past 144 blocks</source>
|
<source>Average fees per block in the past 144 blocks</source>
|
||||||
|
<target>Átlagos díjak blokkonként az elmúlt 144 blokkban</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context>
|
<context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context>
|
||||||
<context context-type="linenumber">18,20</context>
|
<context context-type="linenumber">18,20</context>
|
||||||
@@ -5049,6 +5058,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="d70397ee91f6c9ec91f1c1dff88126f8f9b7c2c4" datatype="html">
|
<trans-unit id="d70397ee91f6c9ec91f1c1dff88126f8f9b7c2c4" datatype="html">
|
||||||
<source>Show more inputs to reveal fee data</source>
|
<source>Show more inputs to reveal fee data</source>
|
||||||
|
<target>További bemenetek megjelenítése a díjadatok megjelenítéséhez</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/transactions-list/transactions-list.component.html</context>
|
<context context-type="sourcefile">src/app/components/transactions-list/transactions-list.component.html</context>
|
||||||
<context context-type="linenumber">290,293</context>
|
<context context-type="linenumber">290,293</context>
|
||||||
@@ -5110,6 +5120,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="25d58cd5c18fd9c1c89d6062d67dcc2482161410" datatype="html">
|
<trans-unit id="25d58cd5c18fd9c1c89d6062d67dcc2482161410" datatype="html">
|
||||||
<source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using native SegWit</source>
|
<source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using native SegWit</source>
|
||||||
|
<target>Ez a tranzakció <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% -ot takarított meg a díjakból a natív SegWit használatával</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
||||||
<context context-type="linenumber">2</context>
|
<context context-type="linenumber">2</context>
|
||||||
@@ -5136,6 +5147,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="b6a3f6afdac6873e2d261647d834c02c91376893" datatype="html">
|
<trans-unit id="b6a3f6afdac6873e2d261647d834c02c91376893" datatype="html">
|
||||||
<source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using SegWit and could save <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% more by fully upgrading to native SegWit</source>
|
<source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using SegWit and could save <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% more by fully upgrading to native SegWit</source>
|
||||||
|
<target>Ez a tranzakció <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% -os díjakat takarított meg a SegWit használatával, és további <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% -os megtakarítást érhetett el, ha teljes mértékben vált a natív SegWitre</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
||||||
<context context-type="linenumber">4</context>
|
<context context-type="linenumber">4</context>
|
||||||
@@ -5144,6 +5156,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="a67530e246368aa7e5d010061fd84c3c4fe755c2" datatype="html">
|
<trans-unit id="a67530e246368aa7e5d010061fd84c3c4fe755c2" datatype="html">
|
||||||
<source>This transaction could save <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% on fees by upgrading to native SegWit or <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/>% by upgrading to SegWit-P2SH</source>
|
<source>This transaction could save <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% on fees by upgrading to native SegWit or <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/>% by upgrading to SegWit-P2SH</source>
|
||||||
|
<target>Ez a tranzakció <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% -ot takaríthat meg a díjakból, ha natív SegWitre vált, vagy <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/>% -ot, ha SegWit-P2SH-ra frissít</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
||||||
<context context-type="linenumber">6</context>
|
<context context-type="linenumber">6</context>
|
||||||
@@ -5152,6 +5165,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="17e9c05e053cbd29d3835d8ecb19508d0f07241b" datatype="html">
|
<trans-unit id="17e9c05e053cbd29d3835d8ecb19508d0f07241b" datatype="html">
|
||||||
<source>This transaction uses Taproot and thereby saved at least <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}"/>% on fees</source>
|
<source>This transaction uses Taproot and thereby saved at least <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}"/>% on fees</source>
|
||||||
|
<target>Ez a tranzakció Taprootot használ, és ezáltal legalább <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}"/>% -ot takarít meg a díjakon</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
||||||
<context context-type="linenumber">12</context>
|
<context context-type="linenumber">12</context>
|
||||||
@@ -5186,6 +5200,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="47b821c7df420c96de0b22844a88c04d52628540" datatype="html">
|
<trans-unit id="47b821c7df420c96de0b22844a88c04d52628540" datatype="html">
|
||||||
<source>This transaction uses Taproot and already saved at least <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}"/>% on fees, but could save an additional <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialTaprootGains * 100 | number: '1.0-0' }}"/>% by fully using Taproot</source>
|
<source>This transaction uses Taproot and already saved at least <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}"/>% on fees, but could save an additional <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialTaprootGains * 100 | number: '1.0-0' }}"/>% by fully using Taproot</source>
|
||||||
|
<target>Ez a tranzakció Taprootot használ, és már legalább <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}"/>% -ot megtakarított a díjakból, de további <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialTaprootGains * 100 | number: '1.0-0' }}"/>% -ot takaríthat meg a Taproot teljes használatával</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
||||||
<context context-type="linenumber">14</context>
|
<context context-type="linenumber">14</context>
|
||||||
@@ -5194,6 +5209,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="aa31fc4d29f35b2fd36080bb6ff84be8eaab66fd" datatype="html">
|
<trans-unit id="aa31fc4d29f35b2fd36080bb6ff84be8eaab66fd" datatype="html">
|
||||||
<source>This transaction could save <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialTaprootGains * 100 | number: '1.0-0' }}"/>% on fees by using Taproot</source>
|
<source>This transaction could save <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialTaprootGains * 100 | number: '1.0-0' }}"/>% on fees by using Taproot</source>
|
||||||
|
<target>Ez a tranzakció <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialTaprootGains * 100 | number: '1.0-0' }}"/>% -ot takaríthat meg a díjakból a Taproot használatával</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
||||||
<context context-type="linenumber">16</context>
|
<context context-type="linenumber">16</context>
|
||||||
@@ -5220,6 +5236,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="07883574bb93ea23b764861f56a525bdaf907513" datatype="html">
|
<trans-unit id="07883574bb93ea23b764861f56a525bdaf907513" datatype="html">
|
||||||
<source>This transaction supports Replace-By-Fee (RBF) allowing fee bumping</source>
|
<source>This transaction supports Replace-By-Fee (RBF) allowing fee bumping</source>
|
||||||
|
<target>Ez a tranzakció támogatja a Replace-By-Fee (RBF) funkciót, amely lehetővé teszi a díjak felfutását</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
|
||||||
<context context-type="linenumber">28</context>
|
<context context-type="linenumber">28</context>
|
||||||
@@ -5345,6 +5362,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="8f2791f5d9656271dd6c385f5ad572716e90f4a2" datatype="html">
|
<trans-unit id="8f2791f5d9656271dd6c385f5ad572716e90f4a2" datatype="html">
|
||||||
<source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="mempool.space merely provides data about the Bitcoin network.</b> It cannot help you with"/>mempool.space merely provides data about the Bitcoin network.<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="</b>"/> It cannot help you with retrieving funds, confirming your transaction quicker, etc.</source>
|
<source><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="mempool.space merely provides data about the Bitcoin network.</b> It cannot help you with"/>mempool.space merely provides data about the Bitcoin network.<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="</b>"/> It cannot help you with retrieving funds, confirming your transaction quicker, etc.</source>
|
||||||
|
<target><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="mempool.space merely provides data about the Bitcoin network.</b> It cannot help you with"/>A mempool.space csupán adatokat szolgáltat a Bitcoin hálózatáról.<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="</b>"/> Nem segíthet a pénzeszközök visszaszerzésében, a tranzakció gyorsabb visszaigazolásában stb.</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/docs/api-docs/api-docs.component.html</context>
|
<context context-type="sourcefile">src/app/docs/api-docs/api-docs.component.html</context>
|
||||||
<context context-type="linenumber">13</context>
|
<context context-type="linenumber">13</context>
|
||||||
@@ -5497,6 +5515,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="fb2137ba0df55f21a9d6b6ad08d56d74ad852e0e" datatype="html">
|
<trans-unit id="fb2137ba0df55f21a9d6b6ad08d56d74ad852e0e" datatype="html">
|
||||||
<source>This channel supports zero base fee routing</source>
|
<source>This channel supports zero base fee routing</source>
|
||||||
|
<target>Ez a csatorna támogatja a nulla alapdíjas útválasztást</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
||||||
<context context-type="linenumber">44</context>
|
<context context-type="linenumber">44</context>
|
||||||
@@ -5514,6 +5533,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="b5e42e06ea8a4012a38eef209104bbd9dd1a0fc0" datatype="html">
|
<trans-unit id="b5e42e06ea8a4012a38eef209104bbd9dd1a0fc0" datatype="html">
|
||||||
<source>This channel does not support zero base fee routing</source>
|
<source>This channel does not support zero base fee routing</source>
|
||||||
|
<target>Ez a csatorna nem támogatja a nulla alapdíjas útválasztást</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
|
||||||
<context context-type="linenumber">50</context>
|
<context context-type="linenumber">50</context>
|
||||||
@@ -6046,6 +6066,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="db1f0c0605ab0c4a904523635982253ff72eed40" datatype="html">
|
<trans-unit id="db1f0c0605ab0c4a904523635982253ff72eed40" datatype="html">
|
||||||
<source>The average fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm</source>
|
<source>The average fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm</source>
|
||||||
|
<target>Az útválasztási nódok által felszámított átlagos díjtétel, figyelmen kívül hagyva a > 0,5% -os vagy 5000ppm-es díjakat</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">28,30</context>
|
<context context-type="linenumber">28,30</context>
|
||||||
@@ -6067,6 +6088,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="0a46218f4a7b17b6445460898d75ab78e7e7979b" datatype="html">
|
<trans-unit id="0a46218f4a7b17b6445460898d75ab78e7e7979b" datatype="html">
|
||||||
<source>The average base fee charged by routing nodes, ignoring base fees > 5000ppm</source>
|
<source>The average base fee charged by routing nodes, ignoring base fees > 5000ppm</source>
|
||||||
|
<target>Az útválasztási nódok által felszámított átlagos alapdíj, figyelmen kívül hagyva az alapdíjakat > 5000ppm</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">43,45</context>
|
<context context-type="linenumber">43,45</context>
|
||||||
@@ -6093,6 +6115,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="cb4dae32e1b4d6a2ba6287d9f7bd859ca7259468" datatype="html">
|
<trans-unit id="cb4dae32e1b4d6a2ba6287d9f7bd859ca7259468" datatype="html">
|
||||||
<source>The median fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm</source>
|
<source>The median fee rate charged by routing nodes, ignoring fee rates > 0.5% or 5000ppm</source>
|
||||||
|
<target>Az útválasztási nódok által felszámított medián díjtétel, figyelmen kívül hagyva a > 0,5% vagy 5000 ppm díjakat</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">74,76</context>
|
<context context-type="linenumber">74,76</context>
|
||||||
@@ -6110,6 +6133,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="b8539025268617abfcab1c3f2a2c60cd8d7485fb" datatype="html">
|
<trans-unit id="b8539025268617abfcab1c3f2a2c60cd8d7485fb" datatype="html">
|
||||||
<source>The median base fee charged by routing nodes, ignoring base fees > 5000ppm</source>
|
<source>The median base fee charged by routing nodes, ignoring base fees > 5000ppm</source>
|
||||||
|
<target>Az útválasztási nódok által felszámított medián alapdíj, figyelmen kívül hagyva a > 5000ppm alapdíjakat</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
|
||||||
<context context-type="linenumber">89,91</context>
|
<context context-type="linenumber">89,91</context>
|
||||||
@@ -6426,6 +6450,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="027f48063a5512e5c26b6ca88f7d7734e2d333a7" datatype="html">
|
<trans-unit id="027f48063a5512e5c26b6ca88f7d7734e2d333a7" datatype="html">
|
||||||
<source>Percentage change past week</source>
|
<source>Percentage change past week</source>
|
||||||
|
<target>Százalékos változás a múlt héten</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node-statistics/node-statistics.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/node-statistics/node-statistics.component.html</context>
|
||||||
<context context-type="linenumber">5,7</context>
|
<context context-type="linenumber">5,7</context>
|
||||||
@@ -6543,6 +6568,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="e128630e07a4c467f51b246a31c5734d5fb1a2c2" datatype="html">
|
<trans-unit id="e128630e07a4c467f51b246a31c5734d5fb1a2c2" datatype="html">
|
||||||
<source>Liquidity ad</source>
|
<source>Liquidity ad</source>
|
||||||
|
<target>Likviditási hirdetés</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
||||||
<context context-type="linenumber">141,144</context>
|
<context context-type="linenumber">141,144</context>
|
||||||
@@ -6570,6 +6596,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5e348f3d51c3bb283c16572bee1e293ea991cf49" datatype="html">
|
<trans-unit id="5e348f3d51c3bb283c16572bee1e293ea991cf49" datatype="html">
|
||||||
<source>Funding weight</source>
|
<source>Funding weight</source>
|
||||||
|
<target>A finanszírozás súlya</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
|
||||||
<context context-type="linenumber">161,162</context>
|
<context context-type="linenumber">161,162</context>
|
||||||
@@ -6824,6 +6851,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ccabb31683868066778a1d664aa53ee9fcf77d6b" datatype="html">
|
<trans-unit id="ccabb31683868066778a1d664aa53ee9fcf77d6b" datatype="html">
|
||||||
<source>How much liquidity is running on nodes advertising at least one clearnet IP address</source>
|
<source>How much liquidity is running on nodes advertising at least one clearnet IP address</source>
|
||||||
|
<target>Mennyi likviditás fut a legalább egy clearnet IP-címet hirdető nódokon</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
||||||
<context context-type="linenumber">8,9</context>
|
<context context-type="linenumber">8,9</context>
|
||||||
@@ -6845,6 +6873,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="26fb07e8754b87bba4bf12c5137ffa77dac389a8" datatype="html">
|
<trans-unit id="26fb07e8754b87bba4bf12c5137ffa77dac389a8" datatype="html">
|
||||||
<source>How much liquidity is running on nodes which ISP was not identifiable</source>
|
<source>How much liquidity is running on nodes which ISP was not identifiable</source>
|
||||||
|
<target>Mennyi likviditás fut azon nódokon, amelyek internetszolgáltatója nem volt azonosítható</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
||||||
<context context-type="linenumber">15,16</context>
|
<context context-type="linenumber">15,16</context>
|
||||||
@@ -6866,6 +6895,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="23549ef4e1f846f06abcf07ceecb115945a0cf61" datatype="html">
|
<trans-unit id="23549ef4e1f846f06abcf07ceecb115945a0cf61" datatype="html">
|
||||||
<source>How much liquidity is running on nodes advertising only Tor addresses</source>
|
<source>How much liquidity is running on nodes advertising only Tor addresses</source>
|
||||||
|
<target>Mennyi likviditás fut a csak Tor-címeket hirdető nódokon</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
||||||
<context context-type="linenumber">22,23</context>
|
<context context-type="linenumber">22,23</context>
|
||||||
@@ -6874,6 +6904,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="e008f2a76179fdcd7110b41ca624131f91075949" datatype="html">
|
<trans-unit id="e008f2a76179fdcd7110b41ca624131f91075949" datatype="html">
|
||||||
<source>Top 100 ISPs hosting LN nodes</source>
|
<source>Top 100 ISPs hosting LN nodes</source>
|
||||||
|
<target>A 100 legjobb LN-nódot szolgáltató internetszolgáltató</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.html</context>
|
||||||
<context context-type="linenumber">31,33</context>
|
<context context-type="linenumber">31,33</context>
|
||||||
@@ -6925,6 +6956,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5735693498020397727" datatype="html">
|
<trans-unit id="5735693498020397727" datatype="html">
|
||||||
<source>Lightning nodes on ISP: <x id="PH" equiv-text="response.isp"/> [AS<x id="PH_1" equiv-text="this.route.snapshot.params.isp"/>]</source>
|
<source>Lightning nodes on ISP: <x id="PH" equiv-text="response.isp"/> [AS<x id="PH_1" equiv-text="this.route.snapshot.params.isp"/>]</source>
|
||||||
|
<target>Villám nódok az internetszolgáltatón: <x id="PH" equiv-text="response.isp"/> [MINT<x id="PH_1" equiv-text="this.route.snapshot.params.isp"/>]</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.ts</context>
|
||||||
<context context-type="linenumber">44</context>
|
<context context-type="linenumber">44</context>
|
||||||
@@ -6936,6 +6968,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="d82f436f033a7d81680b8430275f94dda530151c" datatype="html">
|
<trans-unit id="d82f436f033a7d81680b8430275f94dda530151c" datatype="html">
|
||||||
<source>Lightning nodes on ISP: <x id="INTERPOLATION" equiv-text="{{ isp?.name }}"/></source>
|
<source>Lightning nodes on ISP: <x id="INTERPOLATION" equiv-text="{{ isp?.name }}"/></source>
|
||||||
|
<target>Villámnódok az internetszolgáltatón: <x id="INTERPOLATION" equiv-text="{{ isp?.name }}"/></target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp.component.html</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp.component.html</context>
|
||||||
<context context-type="linenumber">2,4</context>
|
<context context-type="linenumber">2,4</context>
|
||||||
|
|||||||
@@ -3775,7 +3775,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="26e78cd052d05a0c1a7db43fac8df52ec6950672" datatype="html">
|
<trans-unit id="26e78cd052d05a0c1a7db43fac8df52ec6950672" datatype="html">
|
||||||
<source>Reward stats</source>
|
<source>Reward stats</source>
|
||||||
<target>Belonnings-statistikk</target>
|
<target>Belønnings-statistikk</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
|
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
|
||||||
<context context-type="linenumber">9</context>
|
<context context-type="linenumber">9</context>
|
||||||
@@ -3850,7 +3850,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ea1a87734b5cc78ea8b268343497d92136855cd1" datatype="html">
|
<trans-unit id="ea1a87734b5cc78ea8b268343497d92136855cd1" datatype="html">
|
||||||
<source>Pools luck</source>
|
<source>Pools luck</source>
|
||||||
<target>Utvinningsgrupper flaks</target>
|
<target>Flaks</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
|
||||||
<context context-type="linenumber">9,11</context>
|
<context context-type="linenumber">9,11</context>
|
||||||
@@ -3877,7 +3877,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1107f1b39cd8474087d438971892967a331a6c7d" datatype="html">
|
<trans-unit id="1107f1b39cd8474087d438971892967a331a6c7d" datatype="html">
|
||||||
<source>Pools count</source>
|
<source>Pools count</source>
|
||||||
<target>Antall utvinningsgrupper</target>
|
<target>Antall grupper</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
|
||||||
<context context-type="linenumber">17,19</context>
|
<context context-type="linenumber">17,19</context>
|
||||||
@@ -4294,7 +4294,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1d9f405ab98a5f79d98b439de29fc8baca46b97c" datatype="html">
|
<trans-unit id="1d9f405ab98a5f79d98b439de29fc8baca46b97c" datatype="html">
|
||||||
<source>Avg Block Fees</source>
|
<source>Avg Block Fees</source>
|
||||||
<target>Gjennomsnittlig blokkavgift</target>
|
<target>Gj.sn. blokkavgift</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context>
|
<context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context>
|
||||||
<context context-type="linenumber">17</context>
|
<context context-type="linenumber">17</context>
|
||||||
|
|||||||
@@ -3203,6 +3203,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
|
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blokken verwacht</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">13</context>
|
<context context-type="linenumber">13</context>
|
||||||
@@ -3211,6 +3212,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
|
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blok verwacht</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">14</context>
|
<context context-type="linenumber">14</context>
|
||||||
@@ -3219,6 +3221,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
|
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blokken gemined</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">18</context>
|
<context context-type="linenumber">18</context>
|
||||||
@@ -3227,6 +3230,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
|
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blok gemined</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">19</context>
|
<context context-type="linenumber">19</context>
|
||||||
@@ -3235,6 +3239,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
|
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
|
||||||
|
<target>Nog <x id="INTERPOLATION" equiv-text="{{ i }}"/> blokken over </target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">24</context>
|
<context context-type="linenumber">24</context>
|
||||||
@@ -3243,6 +3248,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
|
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
|
||||||
|
<target>Nog <x id="INTERPOLATION" equiv-text="{{ i }}"/> blok over</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">25</context>
|
<context context-type="linenumber">25</context>
|
||||||
@@ -3251,6 +3257,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
|
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blokken verder</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">29</context>
|
<context context-type="linenumber">29</context>
|
||||||
@@ -3259,6 +3266,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
|
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blok verder</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">30</context>
|
<context context-type="linenumber">30</context>
|
||||||
@@ -3267,6 +3275,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
|
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blokken achter</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">34</context>
|
<context context-type="linenumber">34</context>
|
||||||
@@ -3275,6 +3284,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
|
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
|
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> blok achter</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
|
||||||
<context context-type="linenumber">35</context>
|
<context context-type="linenumber">35</context>
|
||||||
@@ -3283,6 +3293,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
|
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
|
||||||
<source>Average block time</source>
|
<source>Average block time</source>
|
||||||
|
<target>Gemiddelde bloktijd</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
|
||||||
<context context-type="linenumber">42,45</context>
|
<context context-type="linenumber">42,45</context>
|
||||||
@@ -3984,6 +3995,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="312539377512157124" datatype="html">
|
<trans-unit id="312539377512157124" datatype="html">
|
||||||
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
|
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
|
||||||
|
<target><x id="INTERPOLATION" equiv-text="i"/> blokken</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
||||||
<context context-type="linenumber">165,163</context>
|
<context context-type="linenumber">165,163</context>
|
||||||
@@ -4003,6 +4015,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3666195172774554282" datatype="html">
|
<trans-unit id="3666195172774554282" datatype="html">
|
||||||
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
|
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
|
||||||
|
<target>Ander (<x id="PH" equiv-text="percentage"/>)</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
||||||
<context context-type="linenumber">201</context>
|
<context context-type="linenumber">201</context>
|
||||||
@@ -6713,6 +6726,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="599038141003770125" datatype="html">
|
<trans-unit id="599038141003770125" datatype="html">
|
||||||
<source>Clearnet and Darknet</source>
|
<source>Clearnet and Darknet</source>
|
||||||
|
<target>Clearnet en Darknet</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
||||||
<context context-type="linenumber">164,161</context>
|
<context context-type="linenumber">164,161</context>
|
||||||
@@ -6724,6 +6738,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1282458597026430784" datatype="html">
|
<trans-unit id="1282458597026430784" datatype="html">
|
||||||
<source>Clearnet Only (IPv4, IPv6)</source>
|
<source>Clearnet Only (IPv4, IPv6)</source>
|
||||||
|
<target>Alleen Clearnet (IPv4, IPv6)</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
||||||
<context context-type="linenumber">185,182</context>
|
<context context-type="linenumber">185,182</context>
|
||||||
@@ -6735,6 +6750,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2165336009914523952" datatype="html">
|
<trans-unit id="2165336009914523952" datatype="html">
|
||||||
<source>Darknet Only (Tor, I2P, cjdns)</source>
|
<source>Darknet Only (Tor, I2P, cjdns)</source>
|
||||||
|
<target>Alleen Darknet (Tor, I2P, cjdns)</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
||||||
<context context-type="linenumber">206,203</context>
|
<context context-type="linenumber">206,203</context>
|
||||||
@@ -6759,6 +6775,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5222540403093176126" datatype="html">
|
<trans-unit id="5222540403093176126" datatype="html">
|
||||||
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
|
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
|
||||||
|
<target><x id="PH" equiv-text="nodeCount"/> nodes</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
|
||||||
<context context-type="linenumber">104,103</context>
|
<context context-type="linenumber">104,103</context>
|
||||||
|
|||||||
@@ -4452,7 +4452,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2abc4d0d3ae0b49fa9e94a2efb8c2e1a47e680f4" datatype="html">
|
<trans-unit id="2abc4d0d3ae0b49fa9e94a2efb8c2e1a47e680f4" datatype="html">
|
||||||
<source>Go to "<x id="INTERPOLATION" equiv-text="{{ x }}"/>"</source>
|
<source>Go to "<x id="INTERPOLATION" equiv-text="{{ x }}"/>"</source>
|
||||||
<target>"<x id="INTERPOLATION" equiv-text="{{ x }}"/>" 'a git</target>
|
<target>"<x id="INTERPOLATION" equiv-text="{{ x }}"/>" 'e git</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/search-form/search-results/search-results.component.html</context>
|
<context context-type="sourcefile">src/app/components/search-form/search-results/search-results.component.html</context>
|
||||||
<context context-type="linenumber">52</context>
|
<context context-type="linenumber">52</context>
|
||||||
|
|||||||
@@ -3283,6 +3283,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
|
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
|
||||||
<source>Average block time</source>
|
<source>Average block time</source>
|
||||||
|
<target>Thời gian khối trung bình</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
|
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
|
||||||
<context context-type="linenumber">42,45</context>
|
<context context-type="linenumber">42,45</context>
|
||||||
@@ -4004,6 +4005,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3666195172774554282" datatype="html">
|
<trans-unit id="3666195172774554282" datatype="html">
|
||||||
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
|
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
|
||||||
|
<target>Khác (<x id="PH" equiv-text="percentage"/>)</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
||||||
<context context-type="linenumber">201</context>
|
<context context-type="linenumber">201</context>
|
||||||
@@ -6726,6 +6728,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1282458597026430784" datatype="html">
|
<trans-unit id="1282458597026430784" datatype="html">
|
||||||
<source>Clearnet Only (IPv4, IPv6)</source>
|
<source>Clearnet Only (IPv4, IPv6)</source>
|
||||||
|
<target>Chỉ Clearnet (IPv4, IPv6)</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
||||||
<context context-type="linenumber">185,182</context>
|
<context context-type="linenumber">185,182</context>
|
||||||
@@ -6737,6 +6740,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="2165336009914523952" datatype="html">
|
<trans-unit id="2165336009914523952" datatype="html">
|
||||||
<source>Darknet Only (Tor, I2P, cjdns)</source>
|
<source>Darknet Only (Tor, I2P, cjdns)</source>
|
||||||
|
<target>Chỉ Darknet (Tor, I2P, cjdns)</target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
|
||||||
<context context-type="linenumber">206,203</context>
|
<context context-type="linenumber">206,203</context>
|
||||||
@@ -6761,6 +6765,7 @@
|
|||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5222540403093176126" datatype="html">
|
<trans-unit id="5222540403093176126" datatype="html">
|
||||||
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
|
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
|
||||||
|
<target>nút <x id="PH" equiv-text="nodeCount"/></target>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
|
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
|
||||||
<context context-type="linenumber">104,103</context>
|
<context context-type="linenumber">104,103</context>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 6.4 KiB |
BIN
frontend/src/resources/profile/mynodebtc.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 8.3 KiB |
46
frontend/src/resources/profile/phoenix.svg
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 62.449287 55.101883"
|
||||||
|
version="1.1"
|
||||||
|
id="svg395"
|
||||||
|
sodipodi:docname="phoenix.svg"
|
||||||
|
width="62.449287"
|
||||||
|
height="55.101883"
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview397"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="12.259259"
|
||||||
|
inkscape:cx="29.936556"
|
||||||
|
inkscape:cy="27.978852"
|
||||||
|
inkscape:window-width="3840"
|
||||||
|
inkscape:window-height="2091"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="32"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg395" />
|
||||||
|
<defs
|
||||||
|
id="defs389">
|
||||||
|
<style
|
||||||
|
id="style387">.outline{fill:#50b338;}.bg{fill:#fff;}</style>
|
||||||
|
</defs>
|
||||||
|
<path
|
||||||
|
class="outline"
|
||||||
|
d="m 58.070086,17.34 a 6,6 0 0 0 0.58,-0.65 7.16,7.16 0 0 0 1,-7 c -2.14,-6.51 -10.58,-9.69 -25.75,-9.69 -11.82,0 -23,0 -28.8400005,19.87 -7.53,25.62 -6.16,34.13 0.84,35.13 4.2400005,0.61 6.6200005,-1.62 9.0000005,-4 2,-2 4,-4.46 7,-4 14,2 24.1,-0.21 29.85,-4.83 a 7.7,7.7 0 0 0 3.15,-6.17 5.52,5.52 0 0 0 -0.49,-2.38 c 4.61,-1.11 7.58,-3.4 8,-7.76 0.33,-3.86 -1.45,-6.59 -4.34,-8.52 z m -0.67,8.07 c -0.43,4.74 -11.72,4.46 -26.44,3.59 a 1,1 0 0 0 -1.06,0.91 1,1 0 0 0 0.88,1.09 l 2.43,0.3 c 5.83,0.7 16.69,1.98 16.69,4.7 a 3.44,3.44 0 0 1 -1.41,2.56 c -4,3.4 -15.54,5.16 -24.77,3.76 -4.9,-0.74 -7.55,1.45 -9.9,3.38 -2.09,1.71 -3.73,3.06 -6.6800005,2.33 a 1.59,1.59 0 0 1 -1,-0.83 c -1.74,-3.2 -0.36,-12.85 3.76,-25.9 C 14.950086,5 22.490086,5 33.900086,5 c 12.22,0 19.69,2.24 21,6.32 a 2.17,2.17 0 0 1 -0.2,2.25 c -2.47,3.16 -15.44,1.86 -19.7,1.43 a 1.0054974,1.0054974 0 0 0 -0.21,2 l 2.06,0.23 c 8.4,0.88 21.1,2.22 20.55,8.18 z"
|
||||||
|
id="path391" />
|
||||||
|
<path
|
||||||
|
class="bg"
|
||||||
|
d="m 36.900086,17.22 -2.11,-0.22 a 1.0054974,1.0054974 0 0 1 0.21,-2 c 4.26,0.43 17.23,1.73 19.75,-1.43 a 2.17,2.17 0 0 0 0.2,-2.25 c -1.36,-4.08 -8.83,-6.32 -21.05,-6.32 -11.41,0 -19,0 -24.0000005,16.3 -4.12,13.05 -5.5,22.7 -3.72,25.9 a 1.59,1.59 0 0 0 1,0.83 c 2.9500005,0.73 4.5900005,-0.62 6.6800005,-2.33 2.35,-1.93 5,-4.12 9.9,-3.38 9.23,1.4 20.81,-0.36 24.77,-3.76 a 3.44,3.44 0 0 0 1.37,-2.56 c 0,-2.72 -10.86,-4 -16.69,-4.71 l -2.43,-0.29 a 1,1 0 0 1 -0.88,-1.09 1,1 0 0 1 1.06,-0.91 c 14.72,0.87 26,1.15 26.44,-3.59 0.55,-5.96 -12.15,-7.3 -20.5,-8.19 z"
|
||||||
|
id="path393" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.7 KiB |
1
frontend/src/resources/profile/raspiblitz.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52.67 80.82"><defs><style>.cls-1{fill:#ffe000;}</style></defs><title>RaspiBlitz_Logo_Icon_Negative</title><path class="cls-1" d="M133.56,119l-17-24.25,4.94-28.13L80.89,95l17,24.25-5,28.13ZM91.94,97l18.43-12.91-2.19,12.49L122.5,117l-18.43,12.88,2.22-12.49Z" transform="translate(-80.89 -66.59)"/></svg>
|
||||||
|
After Width: | Height: | Size: 388 B |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
These instructions are for setting up a serious production Mempool website for Bitcoin (mainnet, testnet, signet), Liquid (mainnet, testnet), and Bisq.
|
These instructions are for setting up a serious production Mempool website for Bitcoin (mainnet, testnet, signet), Liquid (mainnet, testnet), and Bisq.
|
||||||
|
|
||||||
Again, this setup is no joke—home users should use [one of the other installation methods](../#installation-methods).
|
This setup is no joke—home users should use [one of the other installation methods](../#installation-methods). We only provide support for this installation method to <a href="https://mempool.space/enterprise">Enterprise sponsors</a>.
|
||||||
|
|
||||||
### Server Hardware
|
### Server Hardware
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ do
|
|||||||
--db-dir __ELECTRS_DATA_ROOT__ \
|
--db-dir __ELECTRS_DATA_ROOT__ \
|
||||||
--network liquid \
|
--network liquid \
|
||||||
--daemon-dir "${HOME}" \
|
--daemon-dir "${HOME}" \
|
||||||
--http-addr '[::]:3001' \
|
--http-socket-file '/elements/socket/esplora-liquid-mainnet' \
|
||||||
--cookie '__ELEMENTS_RPC_USER__:__ELEMENTS_RPC_PASS__' \
|
--cookie '__ELEMENTS_RPC_USER__:__ELEMENTS_RPC_PASS__' \
|
||||||
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ do
|
|||||||
--db-dir __ELECTRS_DATA_ROOT__ \
|
--db-dir __ELECTRS_DATA_ROOT__ \
|
||||||
--network liquidtestnet \
|
--network liquidtestnet \
|
||||||
--daemon-dir "${HOME}" \
|
--daemon-dir "${HOME}" \
|
||||||
--http-addr '[::]:3004' \
|
--http-socket-file '/elements/socket/esplora-liquid-testnet' \
|
||||||
--cookie '__ELEMENTS_RPC_USER__:__ELEMENTS_RPC_PASS__' \
|
--cookie '__ELEMENTS_RPC_USER__:__ELEMENTS_RPC_PASS__' \
|
||||||
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ do
|
|||||||
--cors '*' \
|
--cors '*' \
|
||||||
--db-dir __ELECTRS_DATA_ROOT__ \
|
--db-dir __ELECTRS_DATA_ROOT__ \
|
||||||
--daemon-dir "${HOME}" \
|
--daemon-dir "${HOME}" \
|
||||||
--http-addr '[::]:3000' \
|
--http-socket-file '/bitcoin/socket/esplora-bitcoin-mainnet' \
|
||||||
--cookie '__BITCOIN_RPC_USER__:__BITCOIN_RPC_PASS__' \
|
--cookie '__BITCOIN_RPC_USER__:__BITCOIN_RPC_PASS__' \
|
||||||
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ do
|
|||||||
--db-dir __ELECTRS_DATA_ROOT__ \
|
--db-dir __ELECTRS_DATA_ROOT__ \
|
||||||
--daemon-rpc-addr '127.0.0.1:38332' \
|
--daemon-rpc-addr '127.0.0.1:38332' \
|
||||||
--daemon-dir "${HOME}" \
|
--daemon-dir "${HOME}" \
|
||||||
--http-addr '[::]:3003' \
|
--http-socket-file '/bitcoin/socket/esplora-bitcoin-signet' \
|
||||||
--cookie '__BITCOIN_RPC_USER__:__BITCOIN_RPC_PASS__' \
|
--cookie '__BITCOIN_RPC_USER__:__BITCOIN_RPC_PASS__' \
|
||||||
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ do
|
|||||||
--cors '*' \
|
--cors '*' \
|
||||||
--db-dir __ELECTRS_DATA_ROOT__ \
|
--db-dir __ELECTRS_DATA_ROOT__ \
|
||||||
--daemon-dir "${HOME}" \
|
--daemon-dir "${HOME}" \
|
||||||
--http-addr '[::]:3002' \
|
--http-socket-file '/bitcoin/socket/esplora-bitcoin-testnet' \
|
||||||
--cookie '__BITCOIN_RPC_USER__:__BITCOIN_RPC_PASS__' \
|
--cookie '__BITCOIN_RPC_USER__:__BITCOIN_RPC_PASS__' \
|
||||||
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
--precache-scripts "${HOME}/electrs/contrib/popular-scripts.txt"
|
||||||
|
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ case $OS in
|
|||||||
TOR_USER=_tor
|
TOR_USER=_tor
|
||||||
TOR_GROUP=_tor
|
TOR_GROUP=_tor
|
||||||
NGINX_USER=www
|
NGINX_USER=www
|
||||||
|
NGINX_GROUP=www
|
||||||
NGINX_ETC_FOLDER=/usr/local/etc/nginx
|
NGINX_ETC_FOLDER=/usr/local/etc/nginx
|
||||||
NGINX_CONFIGURATION=/usr/local/etc/nginx/nginx.conf
|
NGINX_CONFIGURATION=/usr/local/etc/nginx/nginx.conf
|
||||||
CERTBOT_PKG=py39-certbot
|
CERTBOT_PKG=py39-certbot
|
||||||
@@ -209,6 +210,7 @@ case $OS in
|
|||||||
TOR_GROUP=debian-tor
|
TOR_GROUP=debian-tor
|
||||||
CERTBOT_PKG=python3-certbot-nginx
|
CERTBOT_PKG=python3-certbot-nginx
|
||||||
NGINX_USER=www-data
|
NGINX_USER=www-data
|
||||||
|
NGINX_GROUP=www-data
|
||||||
NGINX_ETC_FOLDER=/etc/nginx
|
NGINX_ETC_FOLDER=/etc/nginx
|
||||||
NGINX_CONFIGURATION=/etc/nginx/nginx.conf
|
NGINX_CONFIGURATION=/etc/nginx/nginx.conf
|
||||||
;;
|
;;
|
||||||
@@ -301,12 +303,6 @@ BISQ_HOME=/bisq
|
|||||||
# tor HS folder
|
# tor HS folder
|
||||||
BISQ_TOR_HS=bisq
|
BISQ_TOR_HS=bisq
|
||||||
|
|
||||||
# Unfurl user/group
|
|
||||||
UNFURL_USER=unfurl
|
|
||||||
UNFURL_GROUP=unfurl
|
|
||||||
# Unfurl home folder
|
|
||||||
UNFURL_HOME=/unfurl
|
|
||||||
|
|
||||||
# liquid user/group
|
# liquid user/group
|
||||||
ELEMENTS_USER=elements
|
ELEMENTS_USER=elements
|
||||||
ELEMENTS_GROUP=elements
|
ELEMENTS_GROUP=elements
|
||||||
@@ -396,7 +392,7 @@ DEBIAN_UNFURL_PKG+=(libxdamage-dev libxrandr-dev libgbm-dev libpango1.0-dev liba
|
|||||||
# packages needed for mempool ecosystem
|
# packages needed for mempool ecosystem
|
||||||
FREEBSD_PKG=()
|
FREEBSD_PKG=()
|
||||||
FREEBSD_PKG+=(zsh sudo git git-lfs screen curl wget calc neovim)
|
FREEBSD_PKG+=(zsh sudo git git-lfs screen curl wget calc neovim)
|
||||||
FREEBSD_PKG+=(openssh-portable py39-pip rust llvm90 jq base64 libzmq4)
|
FREEBSD_PKG+=(openssh-portable py39-pip rust llvm10 jq base64 libzmq4)
|
||||||
FREEBSD_PKG+=(boost-libs autoconf automake gmake gcc libevent libtool pkgconf)
|
FREEBSD_PKG+=(boost-libs autoconf automake gmake gcc libevent libtool pkgconf)
|
||||||
FREEBSD_PKG+=(nginx rsync py39-certbot-nginx mariadb105-server keybase)
|
FREEBSD_PKG+=(nginx rsync py39-certbot-nginx mariadb105-server keybase)
|
||||||
FREEBSD_PKG+=(geoipupdate)
|
FREEBSD_PKG+=(geoipupdate)
|
||||||
@@ -547,6 +543,12 @@ zfsCreateFilesystems()
|
|||||||
zfs create -o "mountpoint=${ELEMENTS_HOME}/liquidv1" "${ZPOOL}/elements/liquidv1"
|
zfs create -o "mountpoint=${ELEMENTS_HOME}/liquidv1" "${ZPOOL}/elements/liquidv1"
|
||||||
zfs create -o "mountpoint=${ELEMENTS_ELECTRS_HOME}" "${ZPOOL}/elements/electrs"
|
zfs create -o "mountpoint=${ELEMENTS_ELECTRS_HOME}" "${ZPOOL}/elements/electrs"
|
||||||
|
|
||||||
|
# create /bitcoin/socket with custom ACL for electrs unix sockets
|
||||||
|
zfs create -o "mountpoint=${BITCOIN_HOME}/socket" "${ZPOOL}/bitcoin/socket"
|
||||||
|
|
||||||
|
# create /elements/socket with custom ACL for electrs unix sockets
|
||||||
|
zfs create -o "mountpoint=${ELEMENTS_HOME}/socket" "${ZPOOL}/elements/socket"
|
||||||
|
|
||||||
# Bitcoin Mainnet
|
# Bitcoin Mainnet
|
||||||
if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then
|
if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then
|
||||||
for folder in chainstate indexes blocks
|
for folder in chainstate indexes blocks
|
||||||
@@ -630,6 +632,7 @@ zfsCreateFilesystems()
|
|||||||
ext4CreateDir()
|
ext4CreateDir()
|
||||||
{
|
{
|
||||||
mkdir -p "/backup" "${ELEMENTS_HOME}" "${BITCOIN_HOME}" "${MINFEE_HOME}" "${ELECTRS_HOME}" "${MEMPOOL_HOME}" "${MYSQL_HOME}" "${BITCOIN_ELECTRS_HOME}" "${ELEMENTS_HOME}/liquidv1" "${ELEMENTS_ELECTRS_HOME}"
|
mkdir -p "/backup" "${ELEMENTS_HOME}" "${BITCOIN_HOME}" "${MINFEE_HOME}" "${ELECTRS_HOME}" "${MEMPOOL_HOME}" "${MYSQL_HOME}" "${BITCOIN_ELECTRS_HOME}" "${ELEMENTS_HOME}/liquidv1" "${ELEMENTS_ELECTRS_HOME}"
|
||||||
|
|
||||||
# Bitcoin Mainnet
|
# Bitcoin Mainnet
|
||||||
if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then
|
if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then
|
||||||
for folder in chainstate indexes blocks
|
for folder in chainstate indexes blocks
|
||||||
@@ -1019,7 +1022,7 @@ case $OS in
|
|||||||
osSudo "${ROOT_USER}" mkdir -p /usr/local/etc/syslog.d
|
osSudo "${ROOT_USER}" mkdir -p /usr/local/etc/syslog.d
|
||||||
osSudo "${ROOT_USER}" install -c -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/mempool-logger" /usr/local/bin/mempool-logger
|
osSudo "${ROOT_USER}" install -c -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/mempool-logger" /usr/local/bin/mempool-logger
|
||||||
osSudo "${ROOT_USER}" install -c -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/syslog.conf" /usr/local/etc/syslog.d/mempool.conf
|
osSudo "${ROOT_USER}" install -c -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/syslog.conf" /usr/local/etc/syslog.d/mempool.conf
|
||||||
|
|
||||||
echo "[*] Installing newsyslog configuration"
|
echo "[*] Installing newsyslog configuration"
|
||||||
osSudo "${ROOT_USER}" mkdir -p /usr/local/etc/newsyslog.conf.d
|
osSudo "${ROOT_USER}" mkdir -p /usr/local/etc/newsyslog.conf.d
|
||||||
osSudo "${ROOT_USER}" install -c -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/newsyslog-mempool-backend.conf" /usr/local/etc/newsyslog.conf.d/newsyslog-mempool-backend.conf
|
osSudo "${ROOT_USER}" install -c -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/newsyslog-mempool-backend.conf" /usr/local/etc/newsyslog.conf.d/newsyslog-mempool-backend.conf
|
||||||
@@ -1057,17 +1060,8 @@ if [ "${TOR_INSTALL}" = ON ];then
|
|||||||
osSudo "${ROOT_USER}" install -c -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/torrc" "${TOR_CONFIGURATION}"
|
osSudo "${ROOT_USER}" install -c -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/torrc" "${TOR_CONFIGURATION}"
|
||||||
osSudo "${ROOT_USER}" sed -i.orig "s!__TOR_RESOURCES__!${TOR_RESOURCES}!" "${TOR_CONFIGURATION}"
|
osSudo "${ROOT_USER}" sed -i.orig "s!__TOR_RESOURCES__!${TOR_RESOURCES}!" "${TOR_CONFIGURATION}"
|
||||||
|
|
||||||
echo "[*] Adding Tor HS configuration for Mempool"
|
|
||||||
if [ "${MEMPOOL_ENABLE}" = "ON" ];then
|
|
||||||
if ! grep "${MEMPOOL_TOR_HS}" "${TOR_CONFIGURATION}" >/dev/null 2>&1;then
|
|
||||||
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServiceDir ${TOR_RESOURCES}/${MEMPOOL_TOR_HS}/ >> ${TOR_CONFIGURATION}"
|
|
||||||
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServicePort 80 127.0.0.1:81 >> ${TOR_CONFIGURATION}"
|
|
||||||
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServiceVersion 3 >> ${TOR_CONFIGURATION}"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[*] Adding Tor HS configuration for Bisq"
|
echo "[*] Adding Tor HS configuration for Bisq"
|
||||||
if [ "${BISQ_ENABLE}" = "ON" ];then
|
if [ "${BISQ_MAINNET_ENABLE}" = "ON" ];then
|
||||||
if ! grep "${BISQ_TOR_HS}" "${TOR_CONFIGURATION}" >/dev/null 2>&1;then
|
if ! grep "${BISQ_TOR_HS}" "${TOR_CONFIGURATION}" >/dev/null 2>&1;then
|
||||||
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServiceDir ${TOR_RESOURCES}/${BISQ_TOR_HS}/ >> ${TOR_CONFIGURATION}"
|
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServiceDir ${TOR_RESOURCES}/${BISQ_TOR_HS}/ >> ${TOR_CONFIGURATION}"
|
||||||
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServicePort 80 127.0.0.1:82 >> ${TOR_CONFIGURATION}"
|
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServicePort 80 127.0.0.1:82 >> ${TOR_CONFIGURATION}"
|
||||||
@@ -1076,7 +1070,7 @@ if [ "${TOR_INSTALL}" = ON ];then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "[*] Adding Tor HS configuration for Liquid"
|
echo "[*] Adding Tor HS configuration for Liquid"
|
||||||
if [ "${LIQUID_ENABLE}" = "ON" ];then
|
if [ "${ELEMENTS_LIQUID_ENABLE}" = "ON" ];then
|
||||||
if ! grep "${LIQUID_TOR_HS}" "${TOR_CONFIGURATION}" >/dev/null 2>&1;then
|
if ! grep "${LIQUID_TOR_HS}" "${TOR_CONFIGURATION}" >/dev/null 2>&1;then
|
||||||
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServiceDir ${TOR_RESOURCES}/${LIQUID_TOR_HS}/ >> ${TOR_CONFIGURATION}"
|
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServiceDir ${TOR_RESOURCES}/${LIQUID_TOR_HS}/ >> ${TOR_CONFIGURATION}"
|
||||||
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServicePort 80 127.0.0.1:83 >> ${TOR_CONFIGURATION}"
|
osSudo "${ROOT_USER}" /bin/sh -c "echo HiddenServicePort 80 127.0.0.1:83 >> ${TOR_CONFIGURATION}"
|
||||||
@@ -1273,25 +1267,25 @@ if [ "${ELEMENTS_ELECTRS_INSTALL}" = ON ];then
|
|||||||
if [ "${ELEMENTS_LIQUIDTESTNET_ENABLE}" = ON ];then
|
if [ "${ELEMENTS_LIQUIDTESTNET_ENABLE}" = ON ];then
|
||||||
osSudo "${ROOT_USER}" chown -R "${ELEMENTS_USER}:${ELEMENTS_GROUP}" "${ELECTRS_LIQUIDTESTNET_DATA}"
|
osSudo "${ROOT_USER}" chown -R "${ELEMENTS_USER}:${ELEMENTS_GROUP}" "${ELECTRS_LIQUIDTESTNET_DATA}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "[*] Cloning Liquid Electrs repo from ${ELEMENTS_ELECTRS_REPO_URL}"
|
echo "[*] Cloning Liquid Electrs repo from ${ELEMENTS_ELECTRS_REPO_URL}"
|
||||||
osSudo "${ELEMENTS_USER}" git config --global advice.detachedHead false
|
osSudo "${ELEMENTS_USER}" git config --global advice.detachedHead false
|
||||||
osSudo "${ELEMENTS_USER}" git clone --branch "${ELEMENTS_ELECTRS_REPO_BRANCH}" "${ELEMENTS_ELECTRS_REPO_URL}" "${ELEMENTS_HOME}/${ELEMENTS_ELECTRS_REPO_NAME}"
|
osSudo "${ELEMENTS_USER}" git clone --branch "${ELEMENTS_ELECTRS_REPO_BRANCH}" "${ELEMENTS_ELECTRS_REPO_URL}" "${ELEMENTS_HOME}/${ELEMENTS_ELECTRS_REPO_NAME}"
|
||||||
|
|
||||||
echo "[*] Checking out Liquid Electrs ${ELEMENTS_ELECTRS_LATEST_RELEASE}"
|
echo "[*] Checking out Liquid Electrs ${ELEMENTS_ELECTRS_LATEST_RELEASE}"
|
||||||
osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_HOME}/${ELEMENTS_ELECTRS_REPO_NAME} && git checkout ${ELEMENTS_ELECTRS_LATEST_RELEASE}"
|
osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_HOME}/${ELEMENTS_ELECTRS_REPO_NAME} && git checkout ${ELEMENTS_ELECTRS_LATEST_RELEASE}"
|
||||||
|
|
||||||
echo "[*] Cloning Liquid Asset Registry repo from ${LIQUID_ASSET_REGISTRY_DB_URL}"
|
echo "[*] Cloning Liquid Asset Registry repo from ${LIQUID_ASSET_REGISTRY_DB_URL}"
|
||||||
osSudo "${ELEMENTS_USER}" git config --global advice.detachedHead false
|
osSudo "${ELEMENTS_USER}" git config --global advice.detachedHead false
|
||||||
osSudo "${ELEMENTS_USER}" git clone "${LIQUID_ASSET_REGISTRY_DB_URL}" "${ELEMENTS_HOME}/${LIQUID_ASSET_REGISTRY_DB_NAME}"
|
osSudo "${ELEMENTS_USER}" git clone "${LIQUID_ASSET_REGISTRY_DB_URL}" "${ELEMENTS_HOME}/${LIQUID_ASSET_REGISTRY_DB_NAME}"
|
||||||
|
|
||||||
echo "[*] Cloning Liquid Asset Registry testnet repo from ${LIQUIDTESTNET_ASSET_REGISTRY_DB_URL}"
|
echo "[*] Cloning Liquid Asset Registry testnet repo from ${LIQUIDTESTNET_ASSET_REGISTRY_DB_URL}"
|
||||||
osSudo "${ELEMENTS_USER}" git config --global advice.detachedHead false
|
osSudo "${ELEMENTS_USER}" git config --global advice.detachedHead false
|
||||||
osSudo "${ELEMENTS_USER}" git clone "${LIQUIDTESTNET_ASSET_REGISTRY_DB_URL}" "${ELEMENTS_HOME}/${LIQUIDTESTNET_ASSET_REGISTRY_DB_NAME}"
|
osSudo "${ELEMENTS_USER}" git clone "${LIQUIDTESTNET_ASSET_REGISTRY_DB_URL}" "${ELEMENTS_HOME}/${LIQUIDTESTNET_ASSET_REGISTRY_DB_NAME}"
|
||||||
|
|
||||||
echo "[*] Building Liquid Electrs release binary"
|
echo "[*] Building Liquid Electrs release binary"
|
||||||
osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_ELECTRS_HOME} && cargo run --release --features liquid --bin electrs -- --network liquid --version" || true
|
osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_ELECTRS_HOME} && cargo run --release --features liquid --bin electrs -- --network liquid --version" || true
|
||||||
|
|
||||||
case $OS in
|
case $OS in
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
echo "[*] Patching Liquid Electrs code for FreeBSD"
|
echo "[*] Patching Liquid Electrs code for FreeBSD"
|
||||||
@@ -1300,11 +1294,11 @@ if [ "${ELEMENTS_ELECTRS_INSTALL}" = ON ];then
|
|||||||
Debian)
|
Debian)
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo "[*] Building Liquid Electrs release binary"
|
echo "[*] Building Liquid Electrs release binary"
|
||||||
osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_ELECTRS_HOME} && cargo run --release --features liquid --bin electrs -- --network liquid --version" || true
|
osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_ELECTRS_HOME} && cargo run --release --features liquid --bin electrs -- --network liquid --version" || true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
# Core Lightning for Bitcoin #
|
# Core Lightning for Bitcoin #
|
||||||
##############################
|
##############################
|
||||||
@@ -1430,16 +1424,6 @@ fi
|
|||||||
|
|
||||||
if [ "${UNFURL_INSTALL}" = ON ];then
|
if [ "${UNFURL_INSTALL}" = ON ];then
|
||||||
|
|
||||||
echo "[*] Creating Unfurl user"
|
|
||||||
osGroupCreate "${UNFURL_GROUP}"
|
|
||||||
osUserCreate "${UNFURL_USER}" "${UNFURL_HOME}" "${UNFURL_GROUP}"
|
|
||||||
osSudo "${ROOT_USER}" chsh -s `which zsh` "${UNFURL_USER}"
|
|
||||||
|
|
||||||
echo "[*] Creating Unfurl folder"
|
|
||||||
osSudo "${ROOT_USER}" mkdir -p "${UNFURL_HOME}"
|
|
||||||
osSudo "${ROOT_USER}" chown -R "${UNFURL_USER}:${UNFURL_GROUP}" "${UNFURL_HOME}"
|
|
||||||
osSudo "${UNFURL_USER}" touch "${UNFURL_HOME}/.zshrc"
|
|
||||||
|
|
||||||
echo "[*] Insalling Unfurl source"
|
echo "[*] Insalling Unfurl source"
|
||||||
case $OS in
|
case $OS in
|
||||||
|
|
||||||
@@ -1530,7 +1514,6 @@ if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then
|
|||||||
case $OS in
|
case $OS in
|
||||||
|
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
echo "[*] FIXME: Bitcoin Minfee service must be installed manually on FreeBSD"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
Debian)
|
Debian)
|
||||||
@@ -1548,7 +1531,6 @@ if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then
|
|||||||
case $OS in
|
case $OS in
|
||||||
|
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
echo "[*] FIXME: Bitcoin Testnet service must be installed manually on FreeBSD"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
Debian)
|
Debian)
|
||||||
@@ -1566,7 +1548,6 @@ if [ "${BITCOIN_SIGNET_ENABLE}" = ON ];then
|
|||||||
case $OS in
|
case $OS in
|
||||||
|
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
echo "[*] FIXME: Bitcoin Signet service must be installed manually on FreeBSD"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
Debian)
|
Debian)
|
||||||
@@ -1584,7 +1565,6 @@ if [ "${ELEMENTS_LIQUID_ENABLE}" = ON ];then
|
|||||||
case $OS in
|
case $OS in
|
||||||
|
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
echo "[*] FIXME: Bitcoin Liquid service must be installed manually on FreeBSD"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
Debian)
|
Debian)
|
||||||
@@ -1602,7 +1582,6 @@ if [ "${ELEMENTS_LIQUID_ENABLE}" = ON ];then
|
|||||||
case $OS in
|
case $OS in
|
||||||
|
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
echo "[*] FIXME: Bitcoin Liquid service must be installed manually on FreeBSD"
|
|
||||||
;;
|
;;
|
||||||
|
|
||||||
Debian)
|
Debian)
|
||||||
@@ -1841,6 +1820,9 @@ case $OS in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
# wait for mysql to start
|
||||||
|
sleep 5
|
||||||
|
|
||||||
mysql << _EOF_
|
mysql << _EOF_
|
||||||
create database mempool;
|
create database mempool;
|
||||||
grant all on mempool.* to '${MEMPOOL_MAINNET_USER}'@'localhost' identified by '${MEMPOOL_MAINNET_PASS}';
|
grant all on mempool.* to '${MEMPOOL_MAINNET_USER}'@'localhost' identified by '${MEMPOOL_MAINNET_PASS}';
|
||||||
@@ -1895,39 +1877,60 @@ chown "${MEMPOOL_USER}:${MEMPOOL_GROUP}" "${MEMPOOL_MYSQL_CREDENTIALS}"
|
|||||||
|
|
||||||
##### nginx
|
##### nginx
|
||||||
|
|
||||||
|
echo "[*] Adding Nginx configuration"
|
||||||
|
osSudo "${ROOT_USER}" install -c -o "${ROOT_USER}" -g "${ROOT_GROUP}" -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/nginx/nginx.conf" "${NGINX_CONFIGURATION}"
|
||||||
|
mkdir -p /var/cache/nginx/services /var/cache/nginx/api
|
||||||
|
chown "${NGINX_USER}:${NGINX_GROUP}" /var/cache/nginx/services /var/cache/nginx/api
|
||||||
|
ln -s "${MEMPOOL_HOME}/mempool" "${NGINX_ETC_FOLDER}/mempool"
|
||||||
|
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_USER__!${NGINX_USER}!" "${NGINX_CONFIGURATION}"
|
||||||
|
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_ETC_FOLDER__!${NGINX_ETC_FOLDER}!" "${NGINX_CONFIGURATION}"
|
||||||
|
|
||||||
|
if [ "${TOR_INSTALL}" = ON ];then
|
||||||
|
echo "[*] Read tor v3 onion hostnames"
|
||||||
|
|
||||||
|
NGINX_MEMPOOL_ONION=$(cat "${TOR_RESOURCES}/mempool/hostname")
|
||||||
|
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_MEMPOOL_ONION__!${NGINX_MEMPOOL_ONION%.onion}!" "${NGINX_CONFIGURATION}"
|
||||||
|
|
||||||
|
if [ "${ELEMENTS_LIQUID_ENABLE}" = "ON" ];then
|
||||||
|
NGINX_LIQUID_ONION=$(cat "${TOR_RESOURCES}/liquid/hostname")
|
||||||
|
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_LIQUID_ONION__!${NGINX_LIQUID_ONIONi%.onion}!" "${NGINX_CONFIGURATION}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${BISQ_MAINNET_ENABLE}" = "ON" ];then
|
||||||
|
NGINX_BISQ_ONION=$(cat "${TOR_RESOURCES}/bisq/hostname")
|
||||||
|
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_BISQ_ONION__!${NGINX_BISQ_ONION%.onion}!" "${NGINX_CONFIGURATION}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
##### OS systemd
|
||||||
|
|
||||||
|
echo "[*] Setting permissions for electrs sockets"
|
||||||
case $OS in
|
case $OS in
|
||||||
|
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
|
setfacl -m "user:bitcoin:full_set:f:allow,user:mempool:full_set:f:allow,user:www:full_set:f:allow,everyone@::f:allow" "${BITCOIN_HOME}/socket"
|
||||||
|
chown "${BITCOIN_USER}:${BITCOIN_GROUP}" "${BITCOIN_HOME}/socket"
|
||||||
|
setfacl -m "user:elements:full_set:f:allow,user:mempool:full_set:f:allow,user:www:full_set:f:allow,everyone@::f:allow" "${ELEMENTS_HOME}/socket"
|
||||||
|
chown "${ELEMENTS_USER}:${ELEMENTS_GROUP}" "${ELEMENTS_HOME}/socket"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
Debian)
|
Debian)
|
||||||
echo "[*] Adding Nginx configuration"
|
|
||||||
osSudo "${ROOT_USER}" install -c -o "${ROOT_USER}" -g "${ROOT_GROUP}" -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/nginx/nginx.conf" "${NGINX_CONFIGURATION}"
|
|
||||||
mkdir -p /var/cache/nginx/services /var/cache/nginx/api
|
|
||||||
chown ${NGINX_USER}: /var/cache/nginx/services /var/cache/nginx/api
|
|
||||||
ln -s /mempool/mempool /etc/nginx/mempool
|
|
||||||
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_USER__!${NGINX_USER}!" "${NGINX_CONFIGURATION}"
|
|
||||||
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_ETC_FOLDER__!${NGINX_ETC_FOLDER}!" "${NGINX_CONFIGURATION}"
|
|
||||||
if [ "${TOR_INSTALL}" = ON ];then
|
|
||||||
echo "[*] Read tor v3 onion hostnames"
|
|
||||||
NGINX_MEMPOOL_ONION=$(cat "${TOR_RESOURCES}/mempool/hostname")
|
|
||||||
NGINX_BISQ_ONION=$(cat "${TOR_RESOURCES}/bisq/hostname")
|
|
||||||
NGINX_LIQUID_ONION=$(cat "${TOR_RESOURCES}/liquid/hostname")
|
|
||||||
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_MEMPOOL_ONION__!${NGINX_MEMPOOL_ONION%.onion}!" "${NGINX_CONFIGURATION}"
|
|
||||||
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_BISQ_ONION__!${NGINX_BISQ_ONION%.onion}!" "${NGINX_CONFIGURATION}"
|
|
||||||
osSudo "${ROOT_USER}" sed -i.orig "s!__NGINX_LIQUID_ONION__!${NGINX_LIQUID_ONIONi%.onion}!" "${NGINX_CONFIGURATION}"
|
|
||||||
fi
|
|
||||||
echo "[*] Restarting Nginx"
|
|
||||||
osSudo "${ROOT_USER}" service nginx restart
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
##### OS systemd
|
##### OS systemd
|
||||||
|
|
||||||
echo "[*] Updating systemd daemon configuration"
|
echo "[*] Updating system startup configuration"
|
||||||
case $OS in
|
case $OS in
|
||||||
|
|
||||||
FreeBSD)
|
FreeBSD)
|
||||||
|
echo 'nginx_enable="YES"' >> /etc/rc.conf
|
||||||
|
echo 'bitcoin_enable="YES"' >> /etc/rc.conf
|
||||||
|
echo 'tor_enable="YES"' >> /etc/rc.conf
|
||||||
|
echo 'postfix_enable="YES"' >> /etc/rc.conf
|
||||||
|
echo 'mysql_enable="YES"' >> /etc/rc.conf
|
||||||
|
echo 'mysql_dbdir="/mysql"' >> /etc/rc.conf
|
||||||
|
echo 'tor_enable="YES"' >> /etc/rc.conf
|
||||||
;;
|
;;
|
||||||
|
|
||||||
Debian)
|
Debian)
|
||||||
@@ -1959,6 +1962,9 @@ case $OS in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
echo "[*] Restarting Nginx"
|
||||||
|
osSudo "${ROOT_USER}" service nginx restart
|
||||||
|
|
||||||
##### OS set Linux user ulimits
|
##### OS set Linux user ulimits
|
||||||
|
|
||||||
echo "[*] Setting ulimits for users"
|
echo "[*] Setting ulimits for users"
|
||||||
@@ -2060,20 +2066,12 @@ osSudo "${MEMPOOL_USER}" sh -c "cd ${MEMPOOL_HOME} && ./upgrade" || true
|
|||||||
|
|
||||||
##### finish
|
##### finish
|
||||||
|
|
||||||
case $OS in
|
if [ "${TOR_INSTALL}" = ON ];then
|
||||||
|
echo "Your auto-generated Tor addresses are:"
|
||||||
FreeBSD)
|
echo "${NGINX_MEMPOOL_ONION}"
|
||||||
;;
|
echo "${NGINX_BISQ_ONION}"
|
||||||
|
echo "${NGINX_LIQUID_ONION}"
|
||||||
Debian)
|
fi
|
||||||
if [ "${TOR_INSTALL}" = ON ];then
|
|
||||||
echo "This are the generated Tor addresses:"
|
|
||||||
echo "${NGINX_MEMPOOL_ONION}"
|
|
||||||
echo "${NGINX_BISQ_ONION}"
|
|
||||||
echo "${NGINX_LIQUID_ONION}"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo 'Please reboot to start all the services.'
|
echo 'Please reboot to start all the services.'
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
||||||
},
|
},
|
||||||
"ESPLORA": {
|
"ESPLORA": {
|
||||||
"REST_API_URL": "http://127.0.0.1:4001"
|
"UNIX_SOCKET_PATH": "/elements/socket/esplora-liquid-mainnet"
|
||||||
},
|
},
|
||||||
"DATABASE": {
|
"DATABASE": {
|
||||||
"ENABLED": true,
|
"ENABLED": true,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
||||||
},
|
},
|
||||||
"ESPLORA": {
|
"ESPLORA": {
|
||||||
"REST_API_URL": "http://127.0.0.1:4004"
|
"UNIX_SOCKET_PATH": "/elements/socket/esplora-liquid-testnet"
|
||||||
},
|
},
|
||||||
"DATABASE": {
|
"DATABASE": {
|
||||||
"ENABLED": true,
|
"ENABLED": true,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"MEMPOOL": {
|
"MEMPOOL": {
|
||||||
"ENABLED": false,
|
|
||||||
"NETWORK": "mainnet",
|
"NETWORK": "mainnet",
|
||||||
"BACKEND": "esplora",
|
"BACKEND": "esplora",
|
||||||
"HTTP_PORT": 8993,
|
"HTTP_PORT": 8993,
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
||||||
},
|
},
|
||||||
"ESPLORA": {
|
"ESPLORA": {
|
||||||
"REST_API_URL": "http://127.0.0.1:4000"
|
"UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-mainnet"
|
||||||
},
|
},
|
||||||
"DATABASE": {
|
"DATABASE": {
|
||||||
"ENABLED": true,
|
"ENABLED": true,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"MEMPOOL": {
|
"MEMPOOL": {
|
||||||
"ENABLED": false,
|
|
||||||
"NETWORK": "signet",
|
"NETWORK": "signet",
|
||||||
"BACKEND": "esplora",
|
"BACKEND": "esplora",
|
||||||
"HTTP_PORT": 8991,
|
"HTTP_PORT": 8991,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
||||||
},
|
},
|
||||||
"ESPLORA": {
|
"ESPLORA": {
|
||||||
"REST_API_URL": "http://127.0.0.1:4003"
|
"UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-signet"
|
||||||
},
|
},
|
||||||
"DATABASE": {
|
"DATABASE": {
|
||||||
"ENABLED": true,
|
"ENABLED": true,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"MEMPOOL": {
|
"MEMPOOL": {
|
||||||
"ENABLED": false,
|
|
||||||
"NETWORK": "testnet",
|
"NETWORK": "testnet",
|
||||||
"BACKEND": "esplora",
|
"BACKEND": "esplora",
|
||||||
"HTTP_PORT": 8992,
|
"HTTP_PORT": 8992,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
"PASSWORD": "__BITCOIN_RPC_PASS__"
|
||||||
},
|
},
|
||||||
"ESPLORA": {
|
"ESPLORA": {
|
||||||
"REST_API_URL": "http://127.0.0.1:4002"
|
"UNIX_SOCKET_PATH": "/bitcoin/socket/esplora-bitcoin-testnet"
|
||||||
},
|
},
|
||||||
"DATABASE": {
|
"DATABASE": {
|
||||||
"ENABLED": true,
|
"ENABLED": true,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/var/log/nginx/access.log nobody:nobody 644 10 * @T00 C /var/run/mempool.pid 30
|
/var/log/nginx/access.log www:www 644 10 * @T00 C /var/run/mempool.pid 30
|
||||||
/var/log/nginx/error.log nobody:nobody 644 10 * @T00 C /var/run/mempool.pid 30
|
/var/log/nginx/error.log www:www 644 10 * @T00 C /var/run/mempool.pid 30
|
||||||
/var/log/nginx/bisq-access.log nobody:nobody 644 10 * @T00 C /var/run/mempool.pid 30
|
/var/log/nginx/bisq-access.log www:www 644 10 * @T00 C /var/run/mempool.pid 30
|
||||||
/var/log/nginx/bisq-error.log nobody:nobody 644 10 * @T00 C /var/run/mempool.pid 30
|
/var/log/nginx/bisq-error.log www:www 644 10 * @T00 C /var/run/mempool.pid 30
|
||||||
/var/log/nginx/liquid-access.log nobody:nobody 644 10 * @T00 C /var/run/mempool.pid 30
|
/var/log/nginx/liquid-access.log www:www 644 10 * @T00 C /var/run/mempool.pid 30
|
||||||
/var/log/nginx/liquid-error.log nobody:nobody 644 10 * @T00 C /var/run/mempool.pid 30
|
/var/log/nginx/liquid-error.log www:www 644 10 * @T00 C /var/run/mempool.pid 30
|
||||||
/var/log/nginx/mempool-access.log nobody:nobody 644 10 * @T00 C /var/run/mempool.pid 30
|
/var/log/nginx/mempool-access.log www:www 644 10 * @T00 C /var/run/mempool.pid 30
|
||||||
/var/log/nginx/mempool-error.log nobody:nobody 644 10 * @T00 C /var/run/mempool.pid 30
|
/var/log/nginx/mempool-error.log www:www 644 10 * @T00 C /var/run/mempool.pid 30
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
upstream esplora-bitcoin-mainnet {
|
upstream esplora-bitcoin-mainnet {
|
||||||
server [::1]:3000 fail_timeout=10s max_fails=10 weight=99999;
|
server unix:/bitcoin/socket/esplora-bitcoin-mainnet fail_timeout=10s max_fails=10 weight=99999;
|
||||||
}
|
}
|
||||||
upstream esplora-liquid-mainnet {
|
upstream esplora-liquid-mainnet {
|
||||||
server [::1]:3001 fail_timeout=10s max_fails=10 weight=99999;
|
server unix:/elements/socket/esplora-liquid-mainnet fail_timeout=10s max_fails=10 weight=99999;
|
||||||
}
|
}
|
||||||
upstream esplora-bitcoin-testnet {
|
upstream esplora-bitcoin-testnet {
|
||||||
server [::1]:3002 fail_timeout=10s max_fails=10 weight=99999;
|
server unix:/bitcoin/socket/esplora-bitcoin-testnet fail_timeout=10s max_fails=10 weight=99999;
|
||||||
}
|
}
|
||||||
upstream esplora-bitcoin-signet {
|
upstream esplora-bitcoin-signet {
|
||||||
server [::1]:3003 fail_timeout=10s max_fails=10 weight=99999;
|
server unix:/bitcoin/socket/esplora-bitcoin-signet fail_timeout=10s max_fails=10 weight=99999;
|
||||||
}
|
}
|
||||||
upstream esplora-liquid-testnet {
|
upstream esplora-liquid-testnet {
|
||||||
server [::1]:3004 fail_timeout=10s max_fails=10 weight=99999;
|
server unix:/elements/socket/esplora-liquid-testnet fail_timeout=10s max_fails=10 weight=99999;
|
||||||
}
|
}
|
||||||
|
|||||||