Merge branch 'master' into simon/loading-indicator-ux
This commit is contained in:
commit
6f3739feb7
@ -2,7 +2,7 @@ import { IEsploraApi } from './esplora-api.interface';
|
||||
|
||||
export interface AbstractBitcoinApi {
|
||||
$getRawMempool(): Promise<IEsploraApi.Transaction['txid'][]>;
|
||||
$getRawTransaction(txId: string, skipConversion?: boolean, addPrevout?: boolean, blockHash?: string): Promise<IEsploraApi.Transaction>;
|
||||
$getRawTransaction(txId: string, skipConversion?: boolean, addPrevout?: boolean): Promise<IEsploraApi.Transaction>;
|
||||
$getBlockHeightTip(): Promise<number>;
|
||||
$getTxIdsForBlock(hash: string): Promise<string[]>;
|
||||
$getBlockHash(height: number): Promise<string>;
|
||||
|
@ -14,14 +14,31 @@ class BitcoinApi implements AbstractBitcoinApi {
|
||||
this.bitcoindClient = bitcoinClient;
|
||||
}
|
||||
|
||||
$getRawTransaction(txId: string, skipConversion = false, addPrevout = false, blockHash?: string): Promise<IEsploraApi.Transaction> {
|
||||
static convertBlock(block: IBitcoinApi.Block): IEsploraApi.Block {
|
||||
return {
|
||||
id: block.hash,
|
||||
height: block.height,
|
||||
version: block.version,
|
||||
timestamp: block.time,
|
||||
bits: parseInt(block.bits, 16),
|
||||
nonce: block.nonce,
|
||||
difficulty: block.difficulty,
|
||||
merkle_root: block.merkleroot,
|
||||
tx_count: block.nTx,
|
||||
size: block.size,
|
||||
weight: block.weight,
|
||||
previousblockhash: block.previousblockhash,
|
||||
};
|
||||
}
|
||||
|
||||
$getRawTransaction(txId: string, skipConversion = false, addPrevout = false): Promise<IEsploraApi.Transaction> {
|
||||
// If the transaction is in the mempool we already converted and fetched the fee. Only prevouts are missing
|
||||
const txInMempool = mempool.getMempool()[txId];
|
||||
if (txInMempool && addPrevout) {
|
||||
return this.$addPrevouts(txInMempool);
|
||||
}
|
||||
|
||||
return this.bitcoindClient.getRawTransaction(txId, true, blockHash)
|
||||
return this.bitcoindClient.getRawTransaction(txId, true)
|
||||
.then((transaction: IBitcoinApi.Transaction) => {
|
||||
if (skipConversion) {
|
||||
transaction.vout.forEach((vout) => {
|
||||
@ -174,35 +191,18 @@ class BitcoinApi implements AbstractBitcoinApi {
|
||||
};
|
||||
}
|
||||
|
||||
if (transaction.confirmations) {
|
||||
esploraTransaction = await this.$calculateFeeFromInputs(esploraTransaction, addPrevout);
|
||||
} else {
|
||||
esploraTransaction = await this.$appendMempoolFeeData(esploraTransaction);
|
||||
if (addPrevout) {
|
||||
esploraTransaction = await this.$calculateFeeFromInputs(esploraTransaction, addPrevout);
|
||||
if (addPrevout) {
|
||||
if (transaction.confirmations) {
|
||||
esploraTransaction = await this.$calculateFeeFromInputs(esploraTransaction);
|
||||
} else {
|
||||
esploraTransaction = await this.$appendMempoolFeeData(esploraTransaction);
|
||||
esploraTransaction = await this.$calculateFeeFromInputs(esploraTransaction);
|
||||
}
|
||||
}
|
||||
|
||||
return esploraTransaction;
|
||||
}
|
||||
|
||||
static convertBlock(block: IBitcoinApi.Block): IEsploraApi.Block {
|
||||
return {
|
||||
id: block.hash,
|
||||
height: block.height,
|
||||
version: block.version,
|
||||
timestamp: block.time,
|
||||
bits: parseInt(block.bits, 16),
|
||||
nonce: block.nonce,
|
||||
difficulty: block.difficulty,
|
||||
merkle_root: block.merkleroot,
|
||||
tx_count: block.nTx,
|
||||
size: block.size,
|
||||
weight: block.weight,
|
||||
previousblockhash: block.previousblockhash,
|
||||
};
|
||||
}
|
||||
|
||||
private translateScriptPubKeyType(outputType: string): string {
|
||||
const map = {
|
||||
'pubkey': 'p2pk',
|
||||
@ -245,7 +245,7 @@ class BitcoinApi implements AbstractBitcoinApi {
|
||||
if (vin.prevout) {
|
||||
continue;
|
||||
}
|
||||
const innerTx = await this.$getRawTransaction(vin.txid, false);
|
||||
const innerTx = await this.$getRawTransaction(vin.txid, false, false);
|
||||
vin.prevout = innerTx.vout[vin.vout];
|
||||
this.addInnerScriptsToVin(vin);
|
||||
}
|
||||
@ -271,18 +271,16 @@ class BitcoinApi implements AbstractBitcoinApi {
|
||||
return this.bitcoindClient.getRawMemPool(true);
|
||||
}
|
||||
|
||||
private async $calculateFeeFromInputs(transaction: IEsploraApi.Transaction, addPrevout: boolean): Promise<IEsploraApi.Transaction> {
|
||||
private async $calculateFeeFromInputs(transaction: IEsploraApi.Transaction): Promise<IEsploraApi.Transaction> {
|
||||
if (transaction.vin[0].is_coinbase) {
|
||||
transaction.fee = 0;
|
||||
return transaction;
|
||||
}
|
||||
let totalIn = 0;
|
||||
for (const vin of transaction.vin) {
|
||||
const innerTx = await this.$getRawTransaction(vin.txid, !addPrevout);
|
||||
if (addPrevout) {
|
||||
vin.prevout = innerTx.vout[vin.vout];
|
||||
this.addInnerScriptsToVin(vin);
|
||||
}
|
||||
const innerTx = await this.$getRawTransaction(vin.txid, false, false);
|
||||
vin.prevout = innerTx.vout[vin.vout];
|
||||
this.addInnerScriptsToVin(vin);
|
||||
totalIn += innerTx.vout[vin.vout].value;
|
||||
}
|
||||
const totalOut = transaction.vout.reduce((p, output) => p + output.value, 0);
|
||||
|
@ -32,7 +32,7 @@ class DifficultyAdjustmentApi {
|
||||
}
|
||||
}
|
||||
|
||||
let timeAvgMins = blocksInEpoch ? diff / blocksInEpoch / 60 : 10;
|
||||
let timeAvgMins = blocksInEpoch && blocksInEpoch > 146 ? diff / blocksInEpoch / 60 : 10;
|
||||
|
||||
// Testnet difficulty is set to 1 after 20 minutes of no blocks,
|
||||
// therefore the time between blocks will always be below 20 minutes (1200s).
|
||||
|
@ -300,24 +300,12 @@ class Server {
|
||||
|
||||
if (Common.indexingEnabled()) {
|
||||
this.app
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/24h', routes.$getPools.bind(routes, '24h'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3d', routes.$getPools.bind(routes, '3d'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/1w', routes.$getPools.bind(routes, '1w'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/1m', routes.$getPools.bind(routes, '1m'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3m', routes.$getPools.bind(routes, '3m'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/6m', routes.$getPools.bind(routes, '6m'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/1y', routes.$getPools.bind(routes, '1y'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/2y', routes.$getPools.bind(routes, '2y'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/3y', routes.$getPools.bind(routes, '3y'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/all', routes.$getPools.bind(routes, 'all'))
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pools/:interval', routes.$getPools)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/hashrate', routes.$getPoolHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/blocks', routes.$getPoolBlocks)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/blocks/:height', routes.$getPoolBlocks)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug', routes.$getPool)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug/:interval', routes.$getPool)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/pools', routes.$getPoolsHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/pools/:interval', routes.$getPoolsHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate', routes.$getHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/:interval', routes.$getHistoricalHashrate)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/reward-stats/:blockCount', routes.$getRewardStats)
|
||||
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/fees/:interval', routes.$getHistoricalBlockFees)
|
||||
|
@ -572,9 +572,9 @@ class Routes {
|
||||
}
|
||||
}
|
||||
|
||||
public async $getPools(interval: string, req: Request, res: Response) {
|
||||
public async $getPools(req: Request, res: Response) {
|
||||
try {
|
||||
const stats = await miningStats.$getPoolsStats(interval);
|
||||
const stats = await miningStats.$getPoolsStats(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -588,7 +588,7 @@ class Routes {
|
||||
|
||||
public async $getPoolsHistoricalHashrate(req: Request, res: Response) {
|
||||
try {
|
||||
const hashrates = await HashratesRepository.$getPoolsWeeklyHashrate(req.params.interval ?? null);
|
||||
const hashrates = await HashratesRepository.$getPoolsWeeklyHashrate(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -620,8 +620,8 @@ class Routes {
|
||||
|
||||
public async $getHistoricalHashrate(req: Request, res: Response) {
|
||||
try {
|
||||
const hashrates = await HashratesRepository.$getNetworkDailyHashrate(req.params.interval ?? null);
|
||||
const difficulty = await BlocksRepository.$getBlocksDifficulty(req.params.interval ?? null);
|
||||
const hashrates = await HashratesRepository.$getNetworkDailyHashrate(req.params.interval);
|
||||
const difficulty = await BlocksRepository.$getBlocksDifficulty(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -640,7 +640,7 @@ class Routes {
|
||||
|
||||
public async $getHistoricalBlockFees(req: Request, res: Response) {
|
||||
try {
|
||||
const blockFees = await mining.$getHistoricalBlockFees(req.params.interval ?? null);
|
||||
const blockFees = await mining.$getHistoricalBlockFees(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -654,7 +654,7 @@ class Routes {
|
||||
|
||||
public async $getHistoricalBlockRewards(req: Request, res: Response) {
|
||||
try {
|
||||
const blockRewards = await mining.$getHistoricalBlockRewards(req.params.interval ?? null);
|
||||
const blockRewards = await mining.$getHistoricalBlockRewards(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -668,7 +668,7 @@ class Routes {
|
||||
|
||||
public async $getHistoricalBlockFeeRates(req: Request, res: Response) {
|
||||
try {
|
||||
const blockFeeRates = await mining.$getHistoricalBlockFeeRates(req.params.interval ?? null);
|
||||
const blockFeeRates = await mining.$getHistoricalBlockFeeRates(req.params.interval);
|
||||
const oldestIndexedBlockTimestamp = await BlocksRepository.$oldestBlockTimestamp();
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
@ -684,8 +684,8 @@ class Routes {
|
||||
|
||||
public async $getHistoricalBlockSizeAndWeight(req: Request, res: Response) {
|
||||
try {
|
||||
const blockSizes = await mining.$getHistoricalBlockSizes(req.params.interval ?? null);
|
||||
const blockWeights = await mining.$getHistoricalBlockWeights(req.params.interval ?? null);
|
||||
const blockSizes = await mining.$getHistoricalBlockSizes(req.params.interval);
|
||||
const blockWeights = await mining.$getHistoricalBlockWeights(req.params.interval);
|
||||
const blockCount = await BlocksRepository.$blockCount(null, null);
|
||||
res.header('Pragma', 'public');
|
||||
res.header('Cache-control', 'public');
|
||||
|
@ -1,8 +1,10 @@
|
||||
const https = require('https');
|
||||
import axios from 'axios';
|
||||
import poolsParser from '../api/pools-parser';
|
||||
import config from '../config';
|
||||
import DB from '../database';
|
||||
import logger from '../logger';
|
||||
import { SocksProxyAgent } from 'socks-proxy-agent';
|
||||
import * as https from 'https';
|
||||
|
||||
/**
|
||||
* Maintain the most recent version of pools.json
|
||||
@ -28,6 +30,13 @@ class PoolsUpdater {
|
||||
|
||||
this.lastRun = now;
|
||||
|
||||
logger.info('Updating latest mining pools from Github');
|
||||
if (config.SOCKS5PROXY.ENABLED) {
|
||||
logger.info('List of public pools will be queried over the Tor network');
|
||||
} else {
|
||||
logger.info('List of public pools will be queried over clearnet');
|
||||
}
|
||||
|
||||
try {
|
||||
const dbSha = await this.getShaFromDb();
|
||||
const githubSha = await this.fetchPoolsSha(); // Fetch pools.json sha from github
|
||||
@ -41,7 +50,10 @@ class PoolsUpdater {
|
||||
}
|
||||
|
||||
logger.warn('Pools.json is outdated, fetch latest from github');
|
||||
const poolsJson = await this.fetchPools();
|
||||
const poolsJson = await this.query('https://raw.githubusercontent.com/mempool/mining-pools/master/pools.json');
|
||||
if (poolsJson === undefined) {
|
||||
return;
|
||||
}
|
||||
await poolsParser.migratePoolsJson(poolsJson);
|
||||
await this.updateDBSha(githubSha);
|
||||
logger.notice('PoolsUpdater completed');
|
||||
@ -52,14 +64,6 @@ class PoolsUpdater {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch pools.json from github repo
|
||||
*/
|
||||
private async fetchPools(): Promise<object> {
|
||||
const response = await this.query('/repos/mempool/mining-pools/contents/pools.json');
|
||||
return JSON.parse(Buffer.from(response['content'], 'base64').toString('utf8'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch our latest pools.json sha from the db
|
||||
*/
|
||||
@ -90,11 +94,13 @@ class PoolsUpdater {
|
||||
* Fetch our latest pools.json sha from github
|
||||
*/
|
||||
private async fetchPoolsSha(): Promise<string | undefined> {
|
||||
const response = await this.query('/repos/mempool/mining-pools/git/trees/master');
|
||||
const response = await this.query('https://api.github.com/repos/mempool/mining-pools/git/trees/master');
|
||||
|
||||
for (const file of response['tree']) {
|
||||
if (file['path'] === 'pools.json') {
|
||||
return file['sha'];
|
||||
if (response !== undefined) {
|
||||
for (const file of response['tree']) {
|
||||
if (file['path'] === 'pools.json') {
|
||||
return file['sha'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,35 +111,45 @@ class PoolsUpdater {
|
||||
/**
|
||||
* Http request wrapper
|
||||
*/
|
||||
private query(path): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const options = {
|
||||
host: 'api.github.com',
|
||||
path: path,
|
||||
method: 'GET',
|
||||
headers: { 'user-agent': 'node.js' }
|
||||
private async query(path): Promise<object | undefined> {
|
||||
type axiosOptions = {
|
||||
httpsAgent?: https.Agent;
|
||||
}
|
||||
const setDelay = (secs: number = 1): Promise<void> => new Promise(resolve => setTimeout(() => resolve(), secs * 1000));
|
||||
const axiosOptions: axiosOptions = {};
|
||||
let retry = 0;
|
||||
|
||||
if (config.SOCKS5PROXY.ENABLED) {
|
||||
const socksOptions: any = {
|
||||
agentOptions: {
|
||||
keepAlive: true,
|
||||
},
|
||||
hostname: config.SOCKS5PROXY.HOST,
|
||||
port: config.SOCKS5PROXY.PORT
|
||||
};
|
||||
|
||||
logger.debug('Querying: api.github.com' + path);
|
||||
if (config.SOCKS5PROXY.USERNAME && config.SOCKS5PROXY.PASSWORD) {
|
||||
socksOptions.username = config.SOCKS5PROXY.USERNAME;
|
||||
socksOptions.password = config.SOCKS5PROXY.PASSWORD;
|
||||
}
|
||||
|
||||
const request = https.get(options, (response) => {
|
||||
const chunks_of_data: any[] = [];
|
||||
response.on('data', (fragments) => {
|
||||
chunks_of_data.push(fragments);
|
||||
});
|
||||
response.on('end', () => {
|
||||
resolve(JSON.parse(Buffer.concat(chunks_of_data).toString()));
|
||||
});
|
||||
response.on('error', (error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
axiosOptions.httpsAgent = new SocksProxyAgent(socksOptions);
|
||||
}
|
||||
|
||||
request.on('error', (error) => {
|
||||
logger.err('Github API query failed. Reason: ' + error);
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
while(retry < 5) {
|
||||
try {
|
||||
const data = await axios.get(path, axiosOptions);
|
||||
if (data.statusText !== 'OK' || !data.data) {
|
||||
throw new Error(`Could not fetch data from Github, Error: ${data.status}`);
|
||||
}
|
||||
return data.data;
|
||||
} catch (e) {
|
||||
logger.err('Could not connect to Github. Reason: ' + (e instanceof Error ? e.message : e));
|
||||
retry++;
|
||||
}
|
||||
await setDelay();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
3
contributors/ayanamidev.txt
Normal file
3
contributors/ayanamidev.txt
Normal file
@ -0,0 +1,3 @@
|
||||
I hereby accept the terms of the Contributor License Agreement in the CONTRIBUTING.md file of the mempool/mempool git repository as of May 15, 2022.
|
||||
|
||||
Signed: ayanamidev
|
@ -67,6 +67,7 @@ import { HashrateChartPoolsComponent } from './components/hashrates-chart-pools/
|
||||
import { MiningStartComponent } from './components/mining-start/mining-start.component';
|
||||
import { AmountShortenerPipe } from './shared/pipes/amount-shortener.pipe';
|
||||
import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-string.pipe';
|
||||
import { CapAddressPipe } from './shared/pipes/cap-address-pipe/cap-address-pipe';
|
||||
import { GraphsComponent } from './components/graphs/graphs.component';
|
||||
import { DifficultyAdjustmentsTable } from './components/difficulty-adjustments-table/difficulty-adjustments-table.components';
|
||||
import { BlocksList } from './components/blocks-list/blocks-list.component';
|
||||
@ -161,6 +162,7 @@ import { BlockSizesWeightsGraphComponent } from './components/block-sizes-weight
|
||||
StorageService,
|
||||
LanguageService,
|
||||
ShortenStringPipe,
|
||||
CapAddressPipe,
|
||||
{ provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptor, multi: true }
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
|
@ -157,7 +157,7 @@ export class BlockFeesGraphComponent implements OnInit {
|
||||
series: [
|
||||
{
|
||||
zlevel: 0,
|
||||
name: 'Fees',
|
||||
name: $localize`:@@c20172223f84462032664d717d739297e5a9e2fe:Fees`,
|
||||
showSymbol: false,
|
||||
symbol: 'none',
|
||||
data: data.blockFees,
|
||||
|
@ -157,7 +157,7 @@ export class BlockRewardsGraphComponent implements OnInit {
|
||||
series: [
|
||||
{
|
||||
zlevel: 0,
|
||||
name: 'Reward',
|
||||
name: $localize`:@@12f86e6747a5ad39e62d3480ddc472b1aeab5b76:Reward`,
|
||||
showSymbol: false,
|
||||
symbol: 'none',
|
||||
data: data.blockRewards,
|
||||
|
@ -178,7 +178,7 @@ export class BlockSizesWeightsGraphComponent implements OnInit {
|
||||
padding: 10,
|
||||
data: [
|
||||
{
|
||||
name: 'Size',
|
||||
name: $localize`:@@7faaaa08f56427999f3be41df1093ce4089bbd75:Size`,
|
||||
inactiveColor: 'rgb(110, 112, 121)',
|
||||
textStyle: {
|
||||
color: 'white',
|
||||
@ -186,7 +186,7 @@ export class BlockSizesWeightsGraphComponent implements OnInit {
|
||||
icon: 'roundRect',
|
||||
},
|
||||
{
|
||||
name: 'Weight',
|
||||
name: $localize`:@@919f2fd60a898850c24b1584362bbf18a4628bcb:Weight`,
|
||||
inactiveColor: 'rgb(110, 112, 121)',
|
||||
textStyle: {
|
||||
color: 'white',
|
||||
@ -224,7 +224,7 @@ export class BlockSizesWeightsGraphComponent implements OnInit {
|
||||
series: data.sizes.length === 0 ? [] : [
|
||||
{
|
||||
zlevel: 1,
|
||||
name: 'Size',
|
||||
name: $localize`:@@7faaaa08f56427999f3be41df1093ce4089bbd75:Size`,
|
||||
showSymbol: false,
|
||||
symbol: 'none',
|
||||
data: data.sizes,
|
||||
@ -255,7 +255,7 @@ export class BlockSizesWeightsGraphComponent implements OnInit {
|
||||
{
|
||||
zlevel: 1,
|
||||
yAxisIndex: 0,
|
||||
name: 'Weight',
|
||||
name: $localize`:@@919f2fd60a898850c24b1584362bbf18a4628bcb:Weight`,
|
||||
showSymbol: false,
|
||||
symbol: 'none',
|
||||
data: data.weights,
|
||||
|
@ -195,7 +195,7 @@
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
|
||||
<app-transactions-list [transactions]="transactions"></app-transactions-list>
|
||||
<app-transactions-list [transactions]="transactions" [paginated]="true"></app-transactions-list>
|
||||
|
||||
<ng-template [ngIf]="isLoadingTransactions">
|
||||
<div class="text-center mb-4" class="tx-skeleton">
|
||||
|
@ -40,10 +40,10 @@
|
||||
<app-time-since [time]="block.timestamp" [fastRender]="true"></app-time-since>
|
||||
</td>
|
||||
<td class="reward text-right" [class]="widget ? 'widget' : ''">
|
||||
<app-amount [satoshis]="block.extras.reward" digitsInfo="1.2-2"></app-amount>
|
||||
<app-amount [satoshis]="block.extras.reward" [noFiat]="true" digitsInfo="1.2-2"></app-amount>
|
||||
</td>
|
||||
<td class="fees text-right" *ngIf="!widget">
|
||||
<app-amount [satoshis]="block.extras.totalFees" digitsInfo="1.2-2"></app-amount>
|
||||
<app-amount [satoshis]="block.extras.totalFees" [noFiat]="true" digitsInfo="1.2-2"></app-amount>
|
||||
</td>
|
||||
<td class="txs text-right" [class]="widget ? 'widget' : ''">
|
||||
{{ block.tx_count | number }}
|
||||
|
@ -11,7 +11,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<h5 class="card-title" i18n="master-page.blocks">Difficulty</h5>
|
||||
<h5 class="card-title" i18n="block.difficulty">Difficulty</h5>
|
||||
<p class="card-text">
|
||||
{{ hashrates.currentDifficulty | amountShortener }}
|
||||
</p>
|
||||
@ -64,13 +64,13 @@
|
||||
<ng-template #loadingStats>
|
||||
<div class="pool-distribution">
|
||||
<div class="item">
|
||||
<h5 class="card-title" i18n="mining.miners-luck">Hashrate</h5>
|
||||
<h5 class="card-title" i18n="mining.hashrate">Hashrate</h5>
|
||||
<p class="card-text">
|
||||
<span class="skeleton-loader skeleton-loader-big"></span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
<h5 class="card-title" i18n="master-page.blocks">Difficulty</h5>
|
||||
<h5 class="card-title" i18n="block.difficulty">Difficulty</h5>
|
||||
<p class="card-text">
|
||||
<span class="skeleton-loader skeleton-loader-big"></span>
|
||||
</p>
|
||||
|
@ -223,7 +223,7 @@ export class HashrateChartComponent implements OnInit {
|
||||
legend: (this.widget || data.hashrates.length === 0) ? undefined : {
|
||||
data: [
|
||||
{
|
||||
name: 'Hashrate',
|
||||
name: $localize`:@@79a9dc5b1caca3cbeb1733a19515edacc5fc7920:Hashrate`,
|
||||
inactiveColor: 'rgb(110, 112, 121)',
|
||||
textStyle: {
|
||||
color: 'white',
|
||||
@ -234,9 +234,9 @@ export class HashrateChartComponent implements OnInit {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Difficulty',
|
||||
name: $localize`:@@25148835d92465353fc5fe8897c27d5369978e5a:Difficulty`,
|
||||
inactiveColor: 'rgb(110, 112, 121)',
|
||||
textStyle: {
|
||||
textStyle: {
|
||||
color: 'white',
|
||||
},
|
||||
icon: 'roundRect',
|
||||
@ -290,7 +290,7 @@ export class HashrateChartComponent implements OnInit {
|
||||
series: data.hashrates.length === 0 ? [] : [
|
||||
{
|
||||
zlevel: 0,
|
||||
name: 'Hashrate',
|
||||
name: $localize`:@@79a9dc5b1caca3cbeb1733a19515edacc5fc7920:Hashrate`,
|
||||
showSymbol: false,
|
||||
symbol: 'none',
|
||||
data: data.hashrates,
|
||||
@ -302,7 +302,7 @@ export class HashrateChartComponent implements OnInit {
|
||||
{
|
||||
zlevel: 1,
|
||||
yAxisIndex: 1,
|
||||
name: 'Difficulty',
|
||||
name: $localize`:@@25148835d92465353fc5fe8897c27d5369978e5a:Difficulty`,
|
||||
showSymbol: false,
|
||||
symbol: 'none',
|
||||
data: data.difficulty,
|
||||
|
@ -7,7 +7,6 @@
|
||||
<button class="btn" style="margin: 0 0 4px 0px" (click)="onSaveChart()">
|
||||
<fa-icon [icon]="['fas', 'download']" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
<span i18n="mining.pools-dominance">Pools Dominance</span>
|
||||
<form [formGroup]="radioGroupForm" class="formRadioGroup" *ngIf="(hashrateObservable$ | async) as stats">
|
||||
<div class="btn-group btn-group-toggle" ngbRadioGroup name="radioBasic" formControlName="dateSpan">
|
||||
<label ngbButtonLabel class="btn-primary btn-sm" *ngIf="stats.blockCount >= 4320">
|
||||
|
@ -153,13 +153,14 @@ export class PoolRankingComponent implements OnInit {
|
||||
},
|
||||
borderColor: '#000',
|
||||
formatter: () => {
|
||||
const i = pool.blockCount.toString();
|
||||
if (this.miningWindowPreference === '24h') {
|
||||
return `<b style="color: white">${pool.name} (${pool.share}%)</b><br>` +
|
||||
pool.lastEstimatedHashrate.toString() + ' PH/s' +
|
||||
`<br>` + pool.blockCount.toString() + ` blocks`;
|
||||
`<br>` + $localize`${i} blocks`;
|
||||
} else {
|
||||
return `<b style="color: white">${pool.name} (${pool.share}%)</b><br>` +
|
||||
pool.blockCount.toString() + ` blocks`;
|
||||
$localize`${i} blocks`;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -65,7 +65,10 @@
|
||||
<ng-template #defaultAddress>
|
||||
<a [routerLink]="['/address/' | relativeUrl, vin.prevout.scriptpubkey_address]" title="{{ vin.prevout.scriptpubkey_address }}">
|
||||
<span class="d-block d-lg-none">{{ vin.prevout.scriptpubkey_address | shortenString : 16 }}</span>
|
||||
<span class="d-none d-lg-block">{{ vin.prevout.scriptpubkey_address | shortenString : 35 }}</span>
|
||||
<span class="d-none d-lg-flex justify-content-start">
|
||||
<span class="addr-left flex-grow-1" [style]="vin.prevout.scriptpubkey_address.length > 40 ? 'max-width: 235px' : ''">{{ vin.prevout.scriptpubkey_address }}</span>
|
||||
<span *ngIf="vin.prevout.scriptpubkey_address.length > 40" class="addr-right">{{ vin.prevout.scriptpubkey_address | capAddress: 40: 10 }}</span>
|
||||
</span>
|
||||
</a>
|
||||
<div>
|
||||
<app-address-labels [vin]="vin"></app-address-labels>
|
||||
@ -156,7 +159,10 @@
|
||||
<td>
|
||||
<a *ngIf="vout.scriptpubkey_address; else scriptpubkey_type" [routerLink]="['/address/' | relativeUrl, vout.scriptpubkey_address]" title="{{ vout.scriptpubkey_address }}">
|
||||
<span class="d-block d-lg-none">{{ vout.scriptpubkey_address | shortenString : 16 }}</span>
|
||||
<span class="d-none d-lg-block">{{ vout.scriptpubkey_address | shortenString : 35 }}</span>
|
||||
<span class="d-none d-lg-flex justify-content-start">
|
||||
<span class="addr-left flex-grow-1" [style]="vout.scriptpubkey_address.length > 40 ? 'max-width: 235px' : ''">{{ vout.scriptpubkey_address }}</span>
|
||||
<span *ngIf="vout.scriptpubkey_address.length > 40" class="addr-right">{{ vout.scriptpubkey_address | capAddress: 40: 10 }}</span>
|
||||
</span>
|
||||
</a>
|
||||
<div>
|
||||
<app-address-labels [vout]="vout"></app-address-labels>
|
||||
|
@ -129,3 +129,14 @@ h2 {
|
||||
.summary {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.addr-left {
|
||||
font-family: monospace;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: -7px
|
||||
}
|
||||
|
||||
.addr-right {
|
||||
font-family: monospace;
|
||||
}
|
@ -22,6 +22,7 @@ export class TransactionsListComponent implements OnInit, OnChanges {
|
||||
@Input() showConfirmations = false;
|
||||
@Input() transactionPage = false;
|
||||
@Input() errorUnblinded = false;
|
||||
@Input() paginated = false;
|
||||
@Input() outputIndex: number;
|
||||
@Input() address: string = '';
|
||||
|
||||
@ -84,6 +85,9 @@ export class TransactionsListComponent implements OnInit, OnChanges {
|
||||
if (!this.transactions || !this.transactions.length) {
|
||||
return;
|
||||
}
|
||||
if (this.paginated) {
|
||||
this.outspends = [];
|
||||
}
|
||||
if (this.outputIndex) {
|
||||
setTimeout(() => {
|
||||
const assetBoxElements = document.getElementsByClassName('assetBox');
|
||||
|
@ -39,7 +39,7 @@ export class ApiDocsComponent implements OnInit {
|
||||
}
|
||||
window.addEventListener('scroll', function() {
|
||||
that.desktopDocsNavPosition = ( window.pageYOffset > 182 ) ? "fixed" : "relative";
|
||||
});
|
||||
}, { passive: true} );
|
||||
}, 1 );
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,9 @@ import { take } from 'rxjs/operators';
|
||||
import { TransferState, makeStateKey } from '@angular/platform-browser';
|
||||
import { BlockExtended } from '../interfaces/node-api.interface';
|
||||
|
||||
const OFFLINE_RETRY_AFTER_MS = 10000;
|
||||
const OFFLINE_PING_CHECK_AFTER_MS = 30000;
|
||||
const EXPECT_PING_RESPONSE_AFTER_MS = 4000;
|
||||
const OFFLINE_RETRY_AFTER_MS = 1000;
|
||||
const OFFLINE_PING_CHECK_AFTER_MS = 10000;
|
||||
const EXPECT_PING_RESPONSE_AFTER_MS = 5000;
|
||||
|
||||
const initData = makeStateKey('/api/v1/init-data');
|
||||
|
||||
|
@ -0,0 +1,12 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
@Pipe({ name: 'capAddress' })
|
||||
export class CapAddressPipe implements PipeTransform {
|
||||
transform(str: string, cap: number, leftover: number) {
|
||||
if (!str) { return; }
|
||||
if (str.length <= cap) {
|
||||
return str;
|
||||
}
|
||||
return str.slice(-Math.max(cap - str.length, leftover));
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ import { MempoolBlocksComponent } from '../components/mempool-blocks/mempool-blo
|
||||
import { BlockchainBlocksComponent } from '../components/blockchain-blocks/blockchain-blocks.component';
|
||||
import { AmountComponent } from '../components/amount/amount.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { CapAddressPipe } from './pipes/cap-address-pipe/cap-address-pipe';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@ -51,6 +52,7 @@ import { RouterModule } from '@angular/router';
|
||||
WuBytesPipe,
|
||||
CeilPipe,
|
||||
ShortenStringPipe,
|
||||
CapAddressPipe,
|
||||
Decimal2HexPipe,
|
||||
FeeRoundingPipe,
|
||||
ColoredPriceDirective,
|
||||
@ -103,6 +105,7 @@ import { RouterModule } from '@angular/router';
|
||||
WuBytesPipe,
|
||||
CeilPipe,
|
||||
ShortenStringPipe,
|
||||
CapAddressPipe,
|
||||
Decimal2HexPipe,
|
||||
FeeRoundingPipe,
|
||||
ColoredPriceDirective,
|
||||
|
@ -1878,6 +1878,25 @@
|
||||
</context-group>
|
||||
<note priority="1" from="description">mining.block-fees</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="c20172223f84462032664d717d739297e5a9e2fe" datatype="html">
|
||||
<source>Fees</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block-fees-graph/block-fees-graph.component.ts</context>
|
||||
<context context-type="linenumber">160,158</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/blocks-list/blocks-list.component.html</context>
|
||||
<context context-type="linenumber">16,17</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool/pool.component.html</context>
|
||||
<context context-type="linenumber">217,219</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool/pool.component.html</context>
|
||||
<context context-type="linenumber">265,267</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="8ba8fe810458280a83df7fdf4c614dfc1a826445" datatype="html">
|
||||
<source>Block Rewards</source>
|
||||
<context-group purpose="location">
|
||||
@ -1894,6 +1913,25 @@
|
||||
</context-group>
|
||||
<note priority="1" from="description">mining.block-rewards</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="12f86e6747a5ad39e62d3480ddc472b1aeab5b76" datatype="html">
|
||||
<source>Reward</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block-rewards-graph/block-rewards-graph.component.ts</context>
|
||||
<context context-type="linenumber">160,158</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/blocks-list/blocks-list.component.html</context>
|
||||
<context context-type="linenumber">15,17</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool/pool.component.html</context>
|
||||
<context context-type="linenumber">216,218</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool/pool.component.html</context>
|
||||
<context context-type="linenumber">264,266</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="56fa1cd221491b6478998679cba2dc8d55ba330d" datatype="html">
|
||||
<source>Block Sizes and Weights</source>
|
||||
<context-group purpose="location">
|
||||
@ -1910,32 +1948,16 @@
|
||||
</context-group>
|
||||
<note priority="1" from="description">mining.block-sizes-weights</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bdf0e930eb22431140a2eaeacd809cc5f8ebd38c" datatype="html">
|
||||
<source>Next Block</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
|
||||
<context context-type="linenumber">7,8</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
|
||||
<context context-type="linenumber">19,20</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/mempool-block/mempool-block.component.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">Next Block</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="a0e07a711d171f4d40dd388d70ed32f9b8101e0a" datatype="html">
|
||||
<source>Previous Block</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
|
||||
<context context-type="linenumber">26,27</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">Previous Block</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="7faaaa08f56427999f3be41df1093ce4089bbd75" datatype="html">
|
||||
<source>Size</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts</context>
|
||||
<context context-type="linenumber">181,180</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts</context>
|
||||
<context context-type="linenumber">227,225</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
|
||||
<context context-type="linenumber">64,66</context>
|
||||
@ -1972,10 +1994,17 @@
|
||||
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
|
||||
<context context-type="linenumber">116,119</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">block.size</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="919f2fd60a898850c24b1584362bbf18a4628bcb" datatype="html">
|
||||
<source>Weight</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts</context>
|
||||
<context context-type="linenumber">189,188</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts</context>
|
||||
<context context-type="linenumber">258,255</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
|
||||
<context context-type="linenumber">68,70</context>
|
||||
@ -1984,7 +2013,30 @@
|
||||
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
|
||||
<context context-type="linenumber">220,222</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">block.weight</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="bdf0e930eb22431140a2eaeacd809cc5f8ebd38c" datatype="html">
|
||||
<source>Next Block</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
|
||||
<context context-type="linenumber">7,8</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
|
||||
<context context-type="linenumber">19,20</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/mempool-block/mempool-block.component.ts</context>
|
||||
<context context-type="linenumber">71</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">Next Block</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="a0e07a711d171f4d40dd388d70ed32f9b8101e0a" datatype="html">
|
||||
<source>Previous Block</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
|
||||
<context context-type="linenumber">26,27</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">Previous Block</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="0b47a777f024ab4e3cdf0062acb4d86e9ae1f635" datatype="html">
|
||||
<source>Median fee</source>
|
||||
@ -2167,6 +2219,14 @@
|
||||
<context context-type="sourcefile">src/app/components/hashrate-chart/hashrate-chart.component.html</context>
|
||||
<context context-type="linenumber">73,75</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/hashrate-chart/hashrate-chart.component.ts</context>
|
||||
<context context-type="linenumber">237,236</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/hashrate-chart/hashrate-chart.component.ts</context>
|
||||
<context context-type="linenumber">305,302</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">block.difficulty</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="a6bb63d98a8a67689070a79ccf13960c25b572ef" datatype="html">
|
||||
@ -2253,38 +2313,6 @@
|
||||
</context-group>
|
||||
<note priority="1" from="description">latest-blocks.mined</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="12f86e6747a5ad39e62d3480ddc472b1aeab5b76" datatype="html">
|
||||
<source>Reward</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/blocks-list/blocks-list.component.html</context>
|
||||
<context context-type="linenumber">15,17</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool/pool.component.html</context>
|
||||
<context context-type="linenumber">216,218</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool/pool.component.html</context>
|
||||
<context context-type="linenumber">264,266</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">latest-blocks.reward</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="c20172223f84462032664d717d739297e5a9e2fe" datatype="html">
|
||||
<source>Fees</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/blocks-list/blocks-list.component.html</context>
|
||||
<context context-type="linenumber">16,17</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool/pool.component.html</context>
|
||||
<context context-type="linenumber">217,219</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool/pool.component.html</context>
|
||||
<context context-type="linenumber">265,267</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">latest-blocks.fees</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="e6213c3f05146287cf121868d9f3d3c3ff5f9714" datatype="html">
|
||||
<source>TXs</source>
|
||||
<context-group purpose="location">
|
||||
@ -2559,10 +2587,6 @@
|
||||
<context context-type="sourcefile">src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html</context>
|
||||
<context context-type="linenumber">6,8</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.html</context>
|
||||
<context context-type="linenumber">10,11</context>
|
||||
</context-group>
|
||||
<note priority="1" from="description">mining.pools-dominance</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="3510fc6daa1d975f331e3a717bdf1a34efa06dff" datatype="html">
|
||||
@ -2591,6 +2615,14 @@
|
||||
<context context-type="sourcefile">src/app/components/hashrate-chart/hashrate-chart.component.html</context>
|
||||
<context context-type="linenumber">67,69</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/hashrate-chart/hashrate-chart.component.ts</context>
|
||||
<context context-type="linenumber">226,225</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/hashrate-chart/hashrate-chart.component.ts</context>
|
||||
<context context-type="linenumber">293,291</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
|
||||
<context context-type="linenumber">87,89</context>
|
||||
@ -2816,6 +2848,17 @@
|
||||
<context context-type="linenumber">55</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="6095122426142344316" datatype="html">
|
||||
<source><x id="PH" equiv-text="i"/> blocks</source>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
||||
<context context-type="linenumber">160,158</context>
|
||||
</context-group>
|
||||
<context-group purpose="location">
|
||||
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
|
||||
<context context-type="linenumber">163,162</context>
|
||||
</context-group>
|
||||
</trans-unit>
|
||||
<trans-unit id="cafc87479686947e2590b9f588a88040aeaf660b" datatype="html">
|
||||
<source>Tags</source>
|
||||
<context-group purpose="location">
|
||||
|
@ -44,25 +44,6 @@
|
||||
try_files $uri $uri/ /en-US/index.html =404;
|
||||
}
|
||||
|
||||
# mainnet API
|
||||
location /api/v1/donations {
|
||||
proxy_pass https://mempool.space;
|
||||
}
|
||||
location /api/v1/donations/images {
|
||||
proxy_pass https://mempool.space;
|
||||
}
|
||||
location /api/v1/contributors {
|
||||
proxy_pass https://mempool.space;
|
||||
}
|
||||
location /api/v1/contributors/images {
|
||||
proxy_pass https://mempool.space;
|
||||
}
|
||||
location /api/v1/translators {
|
||||
proxy_pass https://mempool.space;
|
||||
}
|
||||
location /api/v1/translators/images {
|
||||
proxy_pass https://mempool.space;
|
||||
}
|
||||
location /api/v1/ws {
|
||||
proxy_pass http://127.0.0.1:8999/;
|
||||
proxy_http_version 1.1;
|
||||
|
@ -276,7 +276,7 @@ MINFEE_HOME=/minfee
|
||||
MEMPOOL_REPO_URL=https://github.com/mempool/mempool
|
||||
MEMPOOL_REPO_NAME=mempool
|
||||
MEMPOOL_REPO_BRANCH=master
|
||||
MEMPOOL_LATEST_RELEASE=v2.3.1
|
||||
MEMPOOL_LATEST_RELEASE=master
|
||||
|
||||
BITCOIN_REPO_URL=https://github.com/bitcoin/bitcoin
|
||||
BITCOIN_REPO_NAME=bitcoin
|
||||
@ -1016,7 +1016,7 @@ osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_ELECTRS_HOME} && cargo run --releas
|
||||
echo "[*] Patching Bitcoin Electrs code for FreeBSD"
|
||||
osSudo "${BITCOIN_USER}" sh -c "cd \"${BITCOIN_HOME}/.cargo/registry/src/github.com-1ecc6299db9ec823/sysconf-0.3.4\" && patch -p1 < \"${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/freebsd/sysconf.patch\""
|
||||
osSudo "${BITCOIN_USER}" sh -c "cd \"${BITCOIN_ELECTRS_HOME}/src/new_index/\" && sed -i .bak -e s/Snappy/None/ db.rs && rm db.rs.bak"
|
||||
osSudo "${BITCOIN_USER}" sh -c "cd \"${BITCOIN_ELECTRS_HOME}/src/bin/\" && sed -i .bak -e s/from_secs(5)/from_secs(1)/ electrs.rs && rm electrs.rs.bak"
|
||||
osSudo "${BITCOIN_USER}" sh -c "cd \"${BITCOIN_ELECTRS_HOME}/src/bin/\" && sed -i .bak -e 's/from_secs(5)/from_secs(1)/' electrs.rs && rm electrs.rs.bak"
|
||||
|
||||
echo "[*] Building Bitcoin Electrs release binary"
|
||||
osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_ELECTRS_HOME} && cargo run --release --bin electrs -- --version"
|
||||
@ -1299,7 +1299,7 @@ if [ "${ELEMENTS_LIQUIDTESTNET_ENABLE}" = ON ];then
|
||||
osSudo "${MEMPOOL_USER}" sh -c "cd ${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME} && git checkout ${MEMPOOL_LATEST_RELEASE}"
|
||||
fi
|
||||
|
||||
if [ "${BISQ_ENABLE}" = ON ];then
|
||||
if [ "${BISQ_INSTALL}" = ON ];then
|
||||
echo "[*] Creating Mempool instance for Bisq"
|
||||
osSudo "${MEMPOOL_USER}" git config --global advice.detachedHead false
|
||||
osSudo "${MEMPOOL_USER}" git clone --branch "${MEMPOOL_REPO_BRANCH}" "${MEMPOOL_REPO_URL}" "${MEMPOOL_HOME}/bisq"
|
||||
|
@ -1,4 +1,4 @@
|
||||
local7.>=notice |/usr/local/bin/sudo -u mempool /usr/local/bin/mempool-logger mempool.ops alerts
|
||||
local7.info |/usr/local/bin/sudo -u mempool /usr/local/bin/mempool-logger mempool.ops node100
|
||||
local7.info /var/log/mempool
|
||||
local7.>=info |/usr/local/bin/sudo -u mempool /usr/local/bin/mempool-logger mempool.ops node100
|
||||
local7.>=info /var/log/mempool
|
||||
local7.* /var/log/mempool.debug
|
||||
|
Loading…
x
Reference in New Issue
Block a user