Add new stats in mining pool page
This commit is contained in:
		
							parent
							
								
									870a7e51b1
								
							
						
					
					
						commit
						0ebe0a5dc9
					
				@ -13,6 +13,7 @@ import BlocksAuditsRepository from '../../repositories/BlocksAuditsRepository';
 | 
			
		||||
import PricesRepository from '../../repositories/PricesRepository';
 | 
			
		||||
import { bitcoinCoreApi } from '../bitcoin/bitcoin-api-factory';
 | 
			
		||||
import { IEsploraApi } from '../bitcoin/esplora-api.interface';
 | 
			
		||||
import database from '../../database';
 | 
			
		||||
 | 
			
		||||
class Mining {
 | 
			
		||||
  private blocksPriceIndexingRunning = false;
 | 
			
		||||
@ -141,6 +142,9 @@ class Mining {
 | 
			
		||||
    const blockCount1w: number = await BlocksRepository.$blockCount(pool.id, '1w');
 | 
			
		||||
    const totalBlock1w: number = await BlocksRepository.$blockCount(null, '1w');
 | 
			
		||||
 | 
			
		||||
    const avgHealth = await BlocksRepository.$getAvgBlockHealthPerPoolId(pool.id);    
 | 
			
		||||
    const totalReward = await BlocksRepository.$getTotalRewardForPoolId(pool.id);    
 | 
			
		||||
 | 
			
		||||
    let currentEstimatedHashrate = 0;
 | 
			
		||||
    try {
 | 
			
		||||
      currentEstimatedHashrate = await bitcoinClient.getNetworkHashPs(totalBlock24h);
 | 
			
		||||
@ -162,6 +166,8 @@ class Mining {
 | 
			
		||||
      },
 | 
			
		||||
      estimatedHashrate: currentEstimatedHashrate * (blockCount24h / totalBlock24h),
 | 
			
		||||
      reportedHashrate: null,
 | 
			
		||||
      avgBlockHealth: avgHealth,
 | 
			
		||||
      totalReward: totalReward,
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -330,6 +330,55 @@ class BlocksRepository {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get average block health for all blocks for a single pool
 | 
			
		||||
   */
 | 
			
		||||
  public async $getAvgBlockHealthPerPoolId(poolId: number): Promise<number> {
 | 
			
		||||
    const params: any[] = [];
 | 
			
		||||
    const query = `
 | 
			
		||||
      SELECT AVG(blocks_audits.match_rate) AS avg_match_rate
 | 
			
		||||
      FROM blocks
 | 
			
		||||
      JOIN blocks_audits ON blocks.height = blocks_audits.height
 | 
			
		||||
      WHERE blocks.pool_id = ?
 | 
			
		||||
    `;
 | 
			
		||||
    params.push(poolId);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      const [rows] = await DB.query(query, params);
 | 
			
		||||
      if (!rows[0] || !rows[0].avg_match_rate) {
 | 
			
		||||
        return 0;
 | 
			
		||||
      }
 | 
			
		||||
      return Math.round(rows[0].avg_match_rate * 100) / 100;
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.err(`Cannot get average block health for pool id ${poolId}. Reason: ` + (e instanceof Error ? e.message : e));
 | 
			
		||||
      throw e;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get average block health for all blocks for a single pool
 | 
			
		||||
   */
 | 
			
		||||
  public async $getTotalRewardForPoolId(poolId: number): Promise<number> {
 | 
			
		||||
    const params: any[] = [];
 | 
			
		||||
    const query = `
 | 
			
		||||
      SELECT sum(reward) as total_reward
 | 
			
		||||
      FROM blocks
 | 
			
		||||
      WHERE blocks.pool_id = ?
 | 
			
		||||
    `;
 | 
			
		||||
    params.push(poolId);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      const [rows] = await DB.query(query, params);
 | 
			
		||||
      if (!rows[0] || !rows[0].total_reward) {
 | 
			
		||||
        return 0;
 | 
			
		||||
      }
 | 
			
		||||
      return rows[0].total_reward;
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      logger.err(`Cannot get total reward for pool id ${poolId}. Reason: ` + (e instanceof Error ? e.message : e));
 | 
			
		||||
      throw e;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Get the oldest indexed block
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
@ -86,11 +86,6 @@ export class PoolPreviewComponent implements OnInit {
 | 
			
		||||
            regexes += regex + '", "';
 | 
			
		||||
          }
 | 
			
		||||
          poolStats.pool.regexes = regexes.slice(0, -3);
 | 
			
		||||
          poolStats.pool.addresses = poolStats.pool.addresses;
 | 
			
		||||
 | 
			
		||||
          if (poolStats.reportedHashrate) {
 | 
			
		||||
            poolStats.luck = poolStats.estimatedHashrate / poolStats.reportedHashrate * 100;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          this.openGraphService.waitOver('pool-stats-' + this.slug);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -37,13 +37,13 @@
 | 
			
		||||
              <!-- Addresses desktop -->
 | 
			
		||||
              <tr *ngIf="!isMobile()" class="taller-row">
 | 
			
		||||
                <td class="label addresses" i18n="mining.addresses">Addresses</td>
 | 
			
		||||
                <td *ngIf="poolStats.pool.addresses.length else nodata" style="padding-top: 25px">
 | 
			
		||||
                  <a [routerLink]="['/address' | relativeUrl, poolStats.pool.addresses[0]]" class="first-address">
 | 
			
		||||
                <td *ngIf="poolStats.pool.addresses.length else nodata" style="padding-top: 15px">
 | 
			
		||||
                  <a  class="addresses-data" [routerLink]="['/address' | relativeUrl, poolStats.pool.addresses[0]]">
 | 
			
		||||
                    {{ poolStats.pool.addresses[0] }}
 | 
			
		||||
                  </a>
 | 
			
		||||
                  <div>
 | 
			
		||||
                    <div #collapse="ngbCollapse" [(ngbCollapse)]="gfg">
 | 
			
		||||
                      <a *ngFor="let address of poolStats.pool.addresses | slice: 1"
 | 
			
		||||
                      <a class="addresses-data" *ngFor="let address of poolStats.pool.addresses | slice: 1"
 | 
			
		||||
                        [routerLink]="['/address' | relativeUrl, address]">{{
 | 
			
		||||
                        address }}<br></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
@ -67,13 +67,13 @@
 | 
			
		||||
                      [attr.aria-expanded]="!gfg" aria-controls="collapseExample">
 | 
			
		||||
                      <span i18n="show-all">Show all</span> ({{ poolStats.pool.addresses.length }})
 | 
			
		||||
                    </button>
 | 
			
		||||
                    <a [routerLink]="['/address' | relativeUrl, poolStats.pool.addresses[0]]">
 | 
			
		||||
                      {{ poolStats.pool.addresses[0] | shortenString: 40 }}
 | 
			
		||||
                    <a class="addresses-data" [routerLink]="['/address' | relativeUrl, poolStats.pool.addresses[0]]">
 | 
			
		||||
                      {{ poolStats.pool.addresses[0] | shortenString: 30 }}
 | 
			
		||||
                    </a>
 | 
			
		||||
                    <div #collapse="ngbCollapse" [(ngbCollapse)]="gfg" style="width: 100%">
 | 
			
		||||
                      <a *ngFor="let address of poolStats.pool.addresses | slice: 1"
 | 
			
		||||
                      <a class="addresses-data" *ngFor="let address of poolStats.pool.addresses | slice: 1"
 | 
			
		||||
                        [routerLink]="['/address' | relativeUrl, address]">{{
 | 
			
		||||
                        address | shortenString: 40 }}<br></a>
 | 
			
		||||
                        address | shortenString: 30 }}<br></a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </td>
 | 
			
		||||
@ -88,22 +88,25 @@
 | 
			
		||||
 | 
			
		||||
              <!-- Hashrate desktop -->
 | 
			
		||||
              <tr *ngIf="!isMobile()" class="taller-row">
 | 
			
		||||
                <td class="label" i18n="mining.hashrate-24h">Hashrate (24h)</td>
 | 
			
		||||
                <td class="data">
 | 
			
		||||
                  <table class="table table-xs table-data">
 | 
			
		||||
                    <thead>
 | 
			
		||||
                      <tr>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 37%" i18n="mining.estimated">Estimated</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 26%" i18n="mining.luck">Luck</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.total-reward">Reward</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.estimated">Hashrate (24h)</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.luck">Avg Health</th>
 | 
			
		||||
                      </tr>
 | 
			
		||||
                    </thead>
 | 
			
		||||
                    <tbody>
 | 
			
		||||
                      <td>{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}</td>
 | 
			
		||||
                      <ng-template *ngIf="poolStats.luck; else noreported">
 | 
			
		||||
                        <td>{{ poolStats.reportedHashrate | amountShortener : 1 : 'H/s' }}</td>
 | 
			
		||||
                        <td>{{ formatNumber(poolStats.luck, this.locale, '1.2-2') }}%</td>
 | 
			
		||||
                      <td class="text-center"><app-amount [satoshis]="poolStats.totalReward" digitsInfo="1.0-0" [noFiat]="true"></app-amount></td>
 | 
			
		||||
                      <td class="text-center">{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}</td>
 | 
			
		||||
                      <td class="text-center"><span class="health-badge badge" [class.badge-success]="poolStats.avgBlockHealth >= 99"
 | 
			
		||||
                          [class.badge-warning]="poolStats.avgBlockHealth >= 75 && poolStats.avgBlockHealth < 99" [class.badge-danger]="poolStats.avgBlockHealth < 75"
 | 
			
		||||
                          *ngIf="poolStats.avgBlockHealth != null; else nullHealth">{{ poolStats.avgBlockHealth }}%</span>
 | 
			
		||||
                          <ng-template #nullHealth>
 | 
			
		||||
                            <span class="health-badge badge badge-secondary" i18n="unknown">Unknown</span>
 | 
			
		||||
                          </ng-template>
 | 
			
		||||
                      </td>
 | 
			
		||||
                    </tbody>
 | 
			
		||||
                  </table>
 | 
			
		||||
                </td>
 | 
			
		||||
@ -111,49 +114,46 @@
 | 
			
		||||
              <!-- Hashrate mobile -->
 | 
			
		||||
              <tr *ngIf="isMobile()">
 | 
			
		||||
                <td colspan="2">
 | 
			
		||||
                  <span class="label" i18n="mining.hashrate-24h">Hashrate (24h)</span>
 | 
			
		||||
                  <table class="table table-xs table-data">
 | 
			
		||||
                    <thead>
 | 
			
		||||
                      <tr>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 33%" i18n="mining.estimated">Estimated</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 37%" i18n="mining.reported">Reported</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 30%" i18n="mining.luck">Luck</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.total-reward">Reward</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.estimated">Hashrate (24h)</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.luck">Avg Health</th>
 | 
			
		||||
                      </tr>
 | 
			
		||||
                    </thead>
 | 
			
		||||
                    <tbody>
 | 
			
		||||
                      <td>{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}</td>
 | 
			
		||||
                      <ng-template *ngIf="poolStats.luck; else noreported">
 | 
			
		||||
                        <td>{{ poolStats.reportedHashrate | amountShortener : 1 : 'H/s' }}</td>
 | 
			
		||||
                        <td>{{ formatNumber(poolStats.luck, this.locale, '1.2-2') }}%</td>
 | 
			
		||||
                      <td class="text-center"><app-amount [satoshis]="poolStats.totalReward" digitsInfo="1.0-0" [noFiat]="true"></app-amount></td>
 | 
			
		||||
                      <td class="text-center">{{ poolStats.estimatedHashrate | amountShortener : 1 : 'H/s' }}</td>
 | 
			
		||||
                      <td class="text-center"><span class="health-badge badge" [class.badge-success]="poolStats.avgBlockHealth >= 99"
 | 
			
		||||
                          [class.badge-warning]="poolStats.avgBlockHealth >= 75 && poolStats.avgBlockHealth < 99" [class.badge-danger]="poolStats.avgBlockHealth < 75"
 | 
			
		||||
                          *ngIf="poolStats.avgBlockHealth != null; else nullHealth">{{ poolStats.avgBlockHealth }}%</span>
 | 
			
		||||
                          <ng-template #nullHealth>
 | 
			
		||||
                            <span class="health-badge badge badge-secondary" i18n="unknown">Unknown</span>
 | 
			
		||||
                          </ng-template>
 | 
			
		||||
                      </td>
 | 
			
		||||
                    </tbody>
 | 
			
		||||
                  </table>
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
 | 
			
		||||
              <ng-template #noreported>
 | 
			
		||||
                <td>~</td>
 | 
			
		||||
                <td>~</td>
 | 
			
		||||
              </ng-template>
 | 
			
		||||
 | 
			
		||||
              <!-- Mined blocks desktop -->
 | 
			
		||||
              <tr *ngIf="!isMobile()" class="taller-row">
 | 
			
		||||
                <td class="label" i18n="mining.mined-blocks">Mined blocks</td>
 | 
			
		||||
                <td class="data">
 | 
			
		||||
                  <table class="table table-xs table-data">
 | 
			
		||||
                    <thead>
 | 
			
		||||
                      <tr>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 37%" i18n="24h">24h</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 37%" i18n="1w">1w</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 26%" i18n="all">All</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="24h">Blocks 24h</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="1w">1w</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="all">All</th>
 | 
			
		||||
                      </tr>
 | 
			
		||||
                    </thead>
 | 
			
		||||
                    <tbody>
 | 
			
		||||
                      <td>{{ formatNumber(poolStats.blockCount['24h'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                      <td class="text-center">{{ formatNumber(poolStats.blockCount['24h'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                        poolStats.blockShare['24h'], this.locale, '1.0-0') }}%)</td>
 | 
			
		||||
                      <td>{{ formatNumber(poolStats.blockCount['1w'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                      <td class="text-center">{{ formatNumber(poolStats.blockCount['1w'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                        poolStats.blockShare['1w'], this.locale, '1.0-0') }}%)</td>
 | 
			
		||||
                      <td>{{ formatNumber(poolStats.blockCount['all'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                      <td class="text-center">{{ formatNumber(poolStats.blockCount['all'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                        poolStats.blockShare['all'], this.locale, '1.0-0') }}%)</td>
 | 
			
		||||
                    </tbody>
 | 
			
		||||
                  </table>
 | 
			
		||||
@ -162,21 +162,20 @@
 | 
			
		||||
              <!-- Mined blocks mobile -->
 | 
			
		||||
              <tr *ngIf="isMobile()">
 | 
			
		||||
                <td colspan=2>
 | 
			
		||||
                  <span class="label" i18n="mining.mined-blocks">Mined blocks</span>
 | 
			
		||||
                  <table class="table table-xs table-data">
 | 
			
		||||
                    <thead>
 | 
			
		||||
                      <tr>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 33%" i18n="24h">24h</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 37%" i18n="1w">1w</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title" style="width: 30%" i18n="all">All</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="24h">Blocks 24h</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="1w">1w</th>
 | 
			
		||||
                        <th scope="col" class="block-count-title text-center" style="width: 33%" i18n="all">All</th>
 | 
			
		||||
                      </tr>
 | 
			
		||||
                    </thead>
 | 
			
		||||
                    <tbody>
 | 
			
		||||
                      <td>{{ formatNumber(poolStats.blockCount['24h'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                      <td class="text-center">{{ formatNumber(poolStats.blockCount['24h'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                        poolStats.blockShare['24h'], this.locale, '1.0-0') }}%)</td>
 | 
			
		||||
                      <td>{{ formatNumber(poolStats.blockCount['1w'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                      <td class="text-center">{{ formatNumber(poolStats.blockCount['1w'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                        poolStats.blockShare['1w'], this.locale, '1.0-0') }}%)</td>
 | 
			
		||||
                      <td>{{ formatNumber(poolStats.blockCount['all'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                      <td class="text-center">{{ formatNumber(poolStats.blockCount['all'], this.locale, '1.0-0') }} ({{ formatNumber(100 *
 | 
			
		||||
                        poolStats.blockShare['all'], this.locale, '1.0-0') }}%)</td>
 | 
			
		||||
                    </tbody>
 | 
			
		||||
                  </table>
 | 
			
		||||
@ -213,8 +212,9 @@
 | 
			
		||||
        <th class="timestamp" i18n="latest-blocks.timestamp">Timestamp</th>
 | 
			
		||||
        <th class="mined" i18n="latest-blocks.mined">Mined</th>
 | 
			
		||||
        <th class="coinbase text-left" i18n="latest-blocks.coinbasetag">Coinbase tag</th>
 | 
			
		||||
        <th *ngIf="auditAvailable" class="health text-right" i18n="latest-blocks.health">Health</th>
 | 
			
		||||
        <th class="reward text-right" i18n="latest-blocks.reward">Reward</th>
 | 
			
		||||
        <th class="fees text-right" i18n="latest-blocks.fees">Fees</th>
 | 
			
		||||
        <th *ngIf="!auditAvailable" class="fees text-right" i18n="latest-blocks.fees">Fees</th>
 | 
			
		||||
        <th class="txs text-right" i18n="dashboard.txs">TXs</th>
 | 
			
		||||
        <th class="size" i18n="latest-blocks.size">Size</th>
 | 
			
		||||
      </thead>
 | 
			
		||||
@ -234,10 +234,24 @@
 | 
			
		||||
              {{ block.extras.coinbaseRaw | hex2ascii }}
 | 
			
		||||
            </span>
 | 
			
		||||
          </td>
 | 
			
		||||
          <td *ngIf="auditAvailable" class="health text-right">
 | 
			
		||||
            <a
 | 
			
		||||
              class="health-badge badge"
 | 
			
		||||
              [class.badge-success]="block.extras.matchRate >= 99"
 | 
			
		||||
              [class.badge-warning]="block.extras.matchRate >= 75 && block.extras.matchRate < 99"
 | 
			
		||||
              [class.badge-danger]="block.extras.matchRate < 75"
 | 
			
		||||
              [routerLink]="block.extras.matchRate != null ? ['/block/' | relativeUrl, block.id] : null"
 | 
			
		||||
              [state]="{ data: { block: block } }"
 | 
			
		||||
              *ngIf="block.extras.matchRate != null; else nullHealth"
 | 
			
		||||
            >{{ block.extras.matchRate }}%</a>
 | 
			
		||||
            <ng-template #nullHealth>
 | 
			
		||||
              <span class="health-badge badge badge-secondary" i18n="unknown">Unknown</span>
 | 
			
		||||
            </ng-template>
 | 
			
		||||
          </td>
 | 
			
		||||
          <td class="reward text-right">
 | 
			
		||||
            <app-amount [satoshis]="block.extras.reward" digitsInfo="1.2-2" [noFiat]="true"></app-amount>
 | 
			
		||||
          </td>
 | 
			
		||||
          <td class="fees text-right">
 | 
			
		||||
          <td *ngIf="!auditAvailable" class="fees text-right">
 | 
			
		||||
            <app-amount [satoshis]="block.extras.totalFees" digitsInfo="1.2-2" [noFiat]="true"></app-amount>
 | 
			
		||||
          </td>
 | 
			
		||||
          <td class="txs text-right">
 | 
			
		||||
 | 
			
		||||
@ -68,6 +68,11 @@ div.scrollable {
 | 
			
		||||
  vertical-align: top;
 | 
			
		||||
  padding-top: 25px;
 | 
			
		||||
}
 | 
			
		||||
.addresses-data {
 | 
			
		||||
  vertical-align: top;
 | 
			
		||||
  font-family: monospace;
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.data {
 | 
			
		||||
  text-align: right;
 | 
			
		||||
@ -100,7 +105,7 @@ div.scrollable {
 | 
			
		||||
  @media (max-width: 875px) {
 | 
			
		||||
    padding-left: 50px;
 | 
			
		||||
  }
 | 
			
		||||
  @media (max-width: 650px) {
 | 
			
		||||
  @media (max-width: 685px) {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -118,7 +123,7 @@ div.scrollable {
 | 
			
		||||
    padding-right: 10px;
 | 
			
		||||
  }
 | 
			
		||||
  @media (max-width: 875px) {
 | 
			
		||||
    padding-right: 50px;
 | 
			
		||||
    padding-right: 20px;
 | 
			
		||||
  }
 | 
			
		||||
  @media (max-width: 567px) {
 | 
			
		||||
    padding-right: 10px;
 | 
			
		||||
@ -186,10 +191,6 @@ div.scrollable {
 | 
			
		||||
.block-count-title {
 | 
			
		||||
  color: #4a68b9;
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
  text-align: left;
 | 
			
		||||
  @media (max-width: 767.98px) {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.table-data tr {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { ChangeDetectionStrategy, Component, Inject, Input, LOCALE_ID, OnInit } from '@angular/core';
 | 
			
		||||
import { ActivatedRoute } from '@angular/router';
 | 
			
		||||
import { EChartsOption, graphic } from 'echarts';
 | 
			
		||||
import { BehaviorSubject, Observable, timer } from 'rxjs';
 | 
			
		||||
import { BehaviorSubject, Observable } from 'rxjs';
 | 
			
		||||
import { distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators';
 | 
			
		||||
import { BlockExtended, PoolStat } from '../../interfaces/node-api.interface';
 | 
			
		||||
import { ApiService } from '../../services/api.service';
 | 
			
		||||
@ -35,6 +35,8 @@ export class PoolComponent implements OnInit {
 | 
			
		||||
  blocks: BlockExtended[] = [];
 | 
			
		||||
  slug: string = undefined;
 | 
			
		||||
 | 
			
		||||
  auditAvailable = false;
 | 
			
		||||
 | 
			
		||||
  loadMoreSubject: BehaviorSubject<number> = new BehaviorSubject(this.blocks[this.blocks.length - 1]?.height);
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
@ -44,6 +46,7 @@ export class PoolComponent implements OnInit {
 | 
			
		||||
    public stateService: StateService,
 | 
			
		||||
    private seoService: SeoService,
 | 
			
		||||
  ) {
 | 
			
		||||
    this.auditAvailable = this.stateService.env.AUDIT;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
@ -74,11 +77,6 @@ export class PoolComponent implements OnInit {
 | 
			
		||||
            regexes += regex + '", "';
 | 
			
		||||
          }
 | 
			
		||||
          poolStats.pool.regexes = regexes.slice(0, -3);
 | 
			
		||||
          poolStats.pool.addresses = poolStats.pool.addresses;
 | 
			
		||||
 | 
			
		||||
          if (poolStats.reportedHashrate) {
 | 
			
		||||
            poolStats.luck = poolStats.estimatedHashrate / poolStats.reportedHashrate * 100;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          return Object.assign({
 | 
			
		||||
            logo: `/resources/mining-pools/` + poolStats.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg'
 | 
			
		||||
 | 
			
		||||
@ -107,8 +107,8 @@ export interface PoolStat {
 | 
			
		||||
    '1w': number,
 | 
			
		||||
  };
 | 
			
		||||
  estimatedHashrate: number;
 | 
			
		||||
  reportedHashrate: number;
 | 
			
		||||
  luck?: number;
 | 
			
		||||
  avgBlockHealth: number;
 | 
			
		||||
  totalReward: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface BlockExtension {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user