mirror of
https://github.com/mempool/mempool.git
synced 2025-01-19 05:34:03 +01:00
Merge branch 'master' into junderw/fix-armv7-docker
This commit is contained in:
commit
7ba627e243
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -9,7 +9,7 @@ jobs:
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')"
|
||||
strategy:
|
||||
matrix:
|
||||
node: ["16", "17", "18"]
|
||||
node: ["16", "17", "18", "20"]
|
||||
flavor: ["dev", "prod"]
|
||||
fail-fast: false
|
||||
runs-on: "ubuntu-latest"
|
||||
@ -60,7 +60,7 @@ jobs:
|
||||
if: "!contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')"
|
||||
strategy:
|
||||
matrix:
|
||||
node: ["16", "17", "18"]
|
||||
node: ["16", "17", "18", "20"]
|
||||
flavor: ["dev", "prod"]
|
||||
fail-fast: false
|
||||
runs-on: "ubuntu-latest"
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
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. Mempool only provides support for custom setups to [enterprise sponsors](https://mempool.space/enterprise).
|
||||
|
||||
See other ways to set up Mempool on [the main README](/../../#installation-methods).
|
||||
|
||||
|
@ -64,7 +64,9 @@ li.nav-item {
|
||||
|
||||
|
||||
.navbar-collapse {
|
||||
flex-basis: auto;
|
||||
@media (min-width: 564px) {
|
||||
flex-basis: auto;
|
||||
}
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
|
@ -139,6 +139,8 @@
|
||||
<td class="" *ngIf="this.miningWindowPreference === '24h'"><b>{{ miningStats.lastEstimatedHashrate}} {{
|
||||
miningStats.miningUnits.hashrateUnit }}</b></td>
|
||||
<td class=""><b>{{ miningStats.blockCount }}</b></td>
|
||||
<td *ngIf="auditAvailable"></td>
|
||||
<td *ngIf="auditAvailable"></td>
|
||||
<td class="d-none d-md-table-cell"><b>{{ miningStats.totalEmptyBlock }} ({{ miningStats.totalEmptyBlockRatio
|
||||
}}%)</b></td>
|
||||
</tr>
|
||||
|
@ -92,9 +92,9 @@
|
||||
<table class="table table-xs table-data">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.reward">Reward</th>
|
||||
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.hashrate">Hashrate (24h)</th>
|
||||
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="latest-blocks.avg_health" *ngIf="auditAvailable">Avg Health</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.reward">Reward</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.hashrate">Hashrate (24h)</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="latest-blocks.avg_health" *ngIf="auditAvailable">Avg Health</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -117,9 +117,9 @@
|
||||
<table class="table table-xs table-data">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.reward">Reward</th>
|
||||
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="mining.hashrate">Hashrate (24h)</th>
|
||||
<th scope="col" class="block-count-title text-center" style="width: 33%" i18n="latest-blocks.avg_health" *ngIf="auditAvailable">Avg Health</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.reward">Reward</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.hashrate">Hashrate (24h)</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="latest-blocks.avg_health" *ngIf="auditAvailable">Avg Health</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -143,9 +143,9 @@
|
||||
<table class="table table-xs table-data">
|
||||
<thead>
|
||||
<tr>
|
||||
<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>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="24h">Blocks 24h</th>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="1w">1w</th>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="all">All</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -165,9 +165,9 @@
|
||||
<table class="table table-xs table-data">
|
||||
<thead>
|
||||
<tr>
|
||||
<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>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="24h">Blocks 24h</th>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="1w">1w</th>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="all">All</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -382,9 +382,9 @@
|
||||
<table class="table table-xs table-data text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<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" *ngIf="auditAvailable">Avg Health</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.total-reward">Reward</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.estimated">Hashrate (24h)</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.luck" *ngIf="auditAvailable">Avg Health</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -407,9 +407,9 @@
|
||||
<table class="table table-xs table-data text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<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" *ngIf="auditAvailable">Avg Health</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.total-reward">Reward</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.estimated">Hashrate (24h)</th>
|
||||
<th scope="col" class="data-title clip text-center" style="width: 33%" i18n="mining.luck" *ngIf="auditAvailable">Avg Health</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -433,9 +433,9 @@
|
||||
<table class="table table-xs table-data text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<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>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="24h">Blocks 24h</th>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="1w">1w</th>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="all">All</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -458,9 +458,9 @@
|
||||
<table class="table table-xs table-data text-center">
|
||||
<thead>
|
||||
<tr>
|
||||
<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>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="24h">Blocks 24h</th>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="1w">1w</th>
|
||||
<th scope="col" class="data-title text-center" style="width: 33%" i18n="all">All</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -188,11 +188,19 @@ div.scrollable {
|
||||
}
|
||||
}
|
||||
|
||||
.block-count-title {
|
||||
.data-title {
|
||||
color: #4a68b9;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.clip {
|
||||
@media (max-width: 576px) {
|
||||
max-width: 85px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.table-data tr {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
@ -18,9 +18,10 @@
|
||||
|
||||
form {
|
||||
margin-top: 5px;
|
||||
@media (min-width: 576px) {
|
||||
@media (min-width: 564px) {
|
||||
margin-top: 0px;
|
||||
margin-left: 8px;
|
||||
margin-left: 5px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
width: 100%;
|
||||
|
@ -73,7 +73,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" style="max-height: 410px">
|
||||
<div class="card">
|
||||
<div class="card" *ngIf="(network$ | async) !== 'liquid' && (network$ | async) !== 'liquidtestnet'; else latestBlocks">
|
||||
<div class="card-body">
|
||||
<a class="title-link" href="" [routerLink]="['/rbf' | relativeUrl]">
|
||||
<h5 class="card-title d-inline" i18n="dashboard.latest-rbf-replacements">Latest replacements</h5>
|
||||
@ -106,6 +106,46 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #latestBlocks>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<a class="title-link" href="" [routerLink]="['/blocks' | relativeUrl]">
|
||||
<h5 class="card-title d-inline" i18n="dashboard.latest-blocks">Latest blocks</h5>
|
||||
<span> </span>
|
||||
<fa-icon [icon]="['fas', 'external-link-alt']" [fixedWidth]="true" style="vertical-align: 'text-top'; font-size: 13px; color: '#4a68b9'"></fa-icon>
|
||||
</a>
|
||||
<table class="table lastest-blocks-table">
|
||||
<thead>
|
||||
<th class="table-cell-height" i18n="dashboard.latest-blocks.height">Height</th>
|
||||
<th *ngIf="!stateService.env.MINING_DASHBOARD" class="table-cell-mined" i18n="dashboard.latest-blocks.mined">Mined</th>
|
||||
<th *ngIf="stateService.env.MINING_DASHBOARD" class="table-cell-mined pl-lg-4" i18n="mining.pool-name">Pool</th>
|
||||
<th class="table-cell-transaction-count" i18n="dashboard.latest-blocks.transaction-count">TXs</th>
|
||||
<th class="table-cell-size" i18n="dashboard.latest-blocks.size">Size</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let block of blocks$ | async; let i = index; trackBy: trackByBlock">
|
||||
<td class="table-cell-height" ><a [routerLink]="['/block' | relativeUrl, block.id]" [state]="{ data: { block: block } }">{{ block.height }}</a></td>
|
||||
<td *ngIf="!stateService.env.MINING_DASHBOARD" class="table-cell-mined" ><app-time kind="since" [time]="block.timestamp" [fastRender]="true"></app-time></td>
|
||||
<td *ngIf="stateService.env.MINING_DASHBOARD" class="table-cell-mined pl-lg-4">
|
||||
<a class="clear-link" [routerLink]="[('/mining/pool/' + block.extras.pool.slug) | relativeUrl]">
|
||||
<img width="22" height="22" src="{{ block.extras.pool['logo'] }}"
|
||||
onError="this.src = '/resources/mining-pools/default.svg'">
|
||||
<span class="pool-name">{{ block.extras.pool.name }}</span>
|
||||
</a>
|
||||
</td>
|
||||
<td class="table-cell-transaction-count">{{ block.tx_count | number }}</td>
|
||||
<td class="table-cell-size">
|
||||
<div class="progress">
|
||||
<div class="progress-bar progress-mempool {{ network$ | async }}" role="progressbar" [ngStyle]="{'width': (block.weight / stateService.env.BLOCK_WEIGHT_UNITS)*100 + '%' }"> </div>
|
||||
<div class="progress-text" [innerHTML]="block.size | bytes: 2"></div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div class="col" style="max-height: 410px">
|
||||
<div class="card">
|
||||
@ -180,10 +220,10 @@
|
||||
<ng-template #mempoolTable let-mempoolInfoData>
|
||||
<div class="mempool-info-data">
|
||||
<div class="item">
|
||||
<h5 *ngIf="!mempoolInfoData.value || mempoolInfoData.value.memPoolInfo.mempoolminfee === 0.00001 || (stateService.env.BASE_MODULE === 'liquid' && mempoolInfoData.value.memPoolInfo.mempoolminfee === 0.000001) else purgingText" class="card-title" i18n="dashboard.minimum-fee|Minimum mempool fee">Minimum fee</h5>
|
||||
<h5 *ngIf="!mempoolInfoData.value || mempoolInfoData.value.memPoolInfo.mempoolminfee === mempoolInfoData.value.memPoolInfo.minrelaytxfee || (stateService.env.BASE_MODULE === 'liquid' && mempoolInfoData.value.memPoolInfo.mempoolminfee === 0.000001) else purgingText" class="card-title" i18n="dashboard.minimum-fee|Minimum mempool fee">Minimum fee</h5>
|
||||
<ng-template #purgingText><h5 class="card-title" i18n="dashboard.purging|Purgin below fee">Purging</h5></ng-template>
|
||||
<p class="card-text" *ngIf="(isLoadingWebSocket$ | async) === false && mempoolInfoData.value; else loading">
|
||||
<ng-template [ngIf]="mempoolInfoData.value.memPoolInfo.mempoolminfee > 0.00001">< </ng-template><app-fee-rate [fee]="mempoolInfoData.value.memPoolInfo.mempoolminfee * 100000"></app-fee-rate>
|
||||
<ng-template [ngIf]="mempoolInfoData.value.memPoolInfo.mempoolminfee !== mempoolInfoData.value.memPoolInfo.minrelaytxfee">< </ng-template><app-fee-rate [fee]="mempoolInfoData.value.memPoolInfo.mempoolminfee * 100000"></app-fee-rate>
|
||||
</p>
|
||||
</div>
|
||||
<div class="item">
|
||||
|
@ -175,6 +175,43 @@
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.lastest-blocks-table {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
tr, td, th {
|
||||
border: 0px;
|
||||
padding-top: 0.65rem !important;
|
||||
padding-bottom: 0.7rem !important;
|
||||
}
|
||||
.table-cell-height {
|
||||
width: 15%;
|
||||
}
|
||||
.table-cell-mined {
|
||||
width: 35%;
|
||||
text-align: left;
|
||||
}
|
||||
.table-cell-transaction-count {
|
||||
display: none;
|
||||
text-align: right;
|
||||
width: 20%;
|
||||
display: table-cell;
|
||||
}
|
||||
.table-cell-size {
|
||||
display: none;
|
||||
text-align: center;
|
||||
width: 30%;
|
||||
@media (min-width: 485px) {
|
||||
display: table-cell;
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
display: none;
|
||||
}
|
||||
@media (min-width: 992px) {
|
||||
display: table-cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lastest-replacements-table {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { combineLatest, merge, Observable, of, Subscription } from 'rxjs';
|
||||
import { filter, map, scan, share, switchMap } from 'rxjs/operators';
|
||||
import { filter, map, scan, share, switchMap, tap } from 'rxjs/operators';
|
||||
import { BlockExtended, OptimizedMempoolStats, RbfTree } from '../interfaces/node-api.interface';
|
||||
import { MempoolInfo, TransactionStripped, ReplacementInfo } from '../interfaces/websocket.interface';
|
||||
import { ApiService } from '../services/api.service';
|
||||
@ -39,6 +39,7 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
||||
mempoolLoadingStatus$: Observable<number>;
|
||||
vBytesPerSecondLimit = 1667;
|
||||
transactions$: Observable<TransactionStripped[]>;
|
||||
blocks$: Observable<BlockExtended[]>;
|
||||
replacements$: Observable<ReplacementInfo[]>;
|
||||
latestBlockHeight: number;
|
||||
mempoolTransactionsWeightPerSecondData: any;
|
||||
@ -144,6 +145,23 @@ export class DashboardComponent implements OnInit, OnDestroy {
|
||||
}, []),
|
||||
);
|
||||
|
||||
this.blocks$ = this.stateService.blocks$
|
||||
.pipe(
|
||||
tap((blocks) => {
|
||||
this.latestBlockHeight = blocks[0].height;
|
||||
}),
|
||||
switchMap((blocks) => {
|
||||
if (this.stateService.env.MINING_DASHBOARD === true) {
|
||||
for (const block of blocks) {
|
||||
// @ts-ignore: Need to add an extra field for the template
|
||||
block.extras.pool.logo = `/resources/mining-pools/` +
|
||||
block.extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg';
|
||||
}
|
||||
}
|
||||
return of(blocks.slice(0, 6));
|
||||
})
|
||||
);
|
||||
|
||||
this.replacements$ = this.stateService.rbfLatestSummary$;
|
||||
|
||||
this.mempoolStats$ = this.stateService.connectionState$
|
||||
|
@ -8936,8 +8936,8 @@ export const faqData = [
|
||||
type: "endpoint",
|
||||
category: "self-hosting",
|
||||
showConditions: bitcoinNetworks,
|
||||
fragment: "host-my-own-instance-linux-server",
|
||||
title: "How can I host my own instance on a Linux server?",
|
||||
fragment: "host-my-own-instance-server",
|
||||
title: "How can I host a Mempool instance on my own server?",
|
||||
},
|
||||
{
|
||||
type: "endpoint",
|
||||
|
@ -40,7 +40,7 @@
|
||||
<div class="doc-content">
|
||||
|
||||
<p class="doc-welcome-note">Below is a reference for the {{ network.val === '' ? 'Bitcoin' : network.val.charAt(0).toUpperCase() + network.val.slice(1) }} <ng-container i18n="api-docs.title">REST API service</ng-container>.</p>
|
||||
<p class="doc-welcome-note api-note" *ngIf="officialMempoolInstance">Note that we enforce rate limits. If you exceed these limits, you will get an HTTP 429 error. If you repeatedly exceed the limits, you may be banned from accessing the service altogether. Consider an <a [routerLink]="['/enterprise']">enterprise sponsorship</a> if you need higher API limits.</p>
|
||||
<p class="doc-welcome-note api-note" *ngIf="officialMempoolInstance">Note that we enforce rate limits. If you exceed these limits, you will get an HTTP 429 error. If you repeatedly exceed the limits, you may be banned from accessing the service altogether. Consider an <a href="/enterprise">enterprise sponsorship</a> if you need higher API limits.</p>
|
||||
|
||||
<div class="doc-item-container" *ngFor="let item of restDocs">
|
||||
<h3 *ngIf="( item.type === 'category' ) && ( item.showConditions.indexOf(network.val) > -1 )">{{ item.title }}</h3>
|
||||
@ -279,8 +279,9 @@
|
||||
We support one-click installation on a number of Raspberry Pi full-node distros including Umbrel, RaspiBlitz, MyNode, RoninDojo, and Start9's Embassy.
|
||||
</ng-template>
|
||||
|
||||
<ng-template type="host-my-own-instance-linux-server">
|
||||
You can manually install Mempool on your own Linux server, but this requires advanced sysadmin skills since you will be manually configuring everything. We do not provide support for manual deployments.
|
||||
<ng-template type="host-my-own-instance-server">
|
||||
<p>You can manually install Mempool on your own server, but this requires advanced sysadmin skills since you will be manually configuring everything. You could also use our <a href="https://github.com/mempool/mempool/tree/master/docker" target="_blank">Docker images</a>.</p><p>In any case, we only provide support for manual deployments to <a href="/enterprise">enterprise sponsors</a>.</p>
|
||||
<p>For casual users, we strongly suggest installing Mempool using one of the <a href="https://github.com/mempool/mempool#one-click-installation" target="_blank">1-click install methods</a>.</p>
|
||||
</ng-template>
|
||||
|
||||
<ng-template type="install-mempool-with-docker">
|
||||
|
@ -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.
|
||||
|
||||
Again, this setup is no joke—home users should use [one of the other installation methods](../#installation-methods).
|
||||
Again, this setup is no joke—home users should use [one of the other installation methods](../#installation-methods). Support is only provided to [enterprise sponsors](https://mempool.space/enterprise).
|
||||
|
||||
### Server Hardware
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user