mirror of
https://github.com/mempool/mempool.git
synced 2026-08-18 13:08:44 +02:00
Merge branch 'master' into mononaut/cache-wallets
This commit is contained in:
commit
e5c04b9dae
24 changed files with 245 additions and 97 deletions
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
if: "(github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')) || github.event_name == 'push'"
|
||||
strategy:
|
||||
matrix:
|
||||
node: ["22"]
|
||||
node: ["22.14.0"]
|
||||
flavor: ["dev", "prod"]
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -163,7 +163,7 @@ jobs:
|
|||
if: "(github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'ops') && !contains(github.head_ref, 'ops/')) || github.event_name == 'push'"
|
||||
strategy:
|
||||
matrix:
|
||||
node: ["22"]
|
||||
node: ["22.14.0"]
|
||||
flavor: ["dev", "prod"]
|
||||
fail-fast: false
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
4
.github/workflows/e2e_parameterized.yml
vendored
4
.github/workflows/e2e_parameterized.yml
vendored
|
|
@ -43,7 +43,7 @@ jobs:
|
|||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
node-version: 22.14.0
|
||||
registry-url: "https://registry.npmjs.org"
|
||||
|
||||
- name: Install (Prod dependencies only)
|
||||
|
|
@ -151,7 +151,7 @@ jobs:
|
|||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 22
|
||||
node-version: 22.14.0
|
||||
cache: "npm"
|
||||
cache-dependency-path: ${{ matrix.module }}/frontend/package-lock.json
|
||||
|
||||
|
|
|
|||
3
.github/workflows/on-tag.yml
vendored
3
.github/workflows/on-tag.yml
vendored
|
|
@ -105,8 +105,9 @@ jobs:
|
|||
--cache-to "type=local,dest=/tmp/.buildx-cache,mode=max" \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
--tag ${{ secrets.DOCKER_HUB_USER }}/${{ matrix.service }}:$TAG \
|
||||
--tag ${{ secrets.DOCKER_HUB_USER }}/${{ matrix.service }}:latest \
|
||||
--build-context rustgbt=./rust \
|
||||
--build-context backend=./backend \
|
||||
--output "type=registry,push=true" \
|
||||
--build-arg commitHash=$SHORT_SHA \
|
||||
./${{ matrix.service }}/
|
||||
./${{ matrix.service }}/
|
||||
|
|
|
|||
4
backend/package-lock.json
generated
4
backend/package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "mempool-backend",
|
||||
"version": "3.1.0-dev",
|
||||
"version": "3.3-dev",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mempool-backend",
|
||||
"version": "3.1.0-dev",
|
||||
"version": "3.2.0-dev",
|
||||
"hasInstallScript": true,
|
||||
"license": "GNU Affero General Public License v3.0",
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mempool-backend",
|
||||
"version": "3.1.0-dev",
|
||||
"version": "3.3-dev",
|
||||
"description": "Bitcoin mempool visualizer and blockchain explorer backend",
|
||||
"license": "GNU Affero General Public License v3.0",
|
||||
"homepage": "https://mempool.space",
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class FailoverRouter {
|
|||
maxHeight: number = 0;
|
||||
hosts: FailoverHost[];
|
||||
multihost: boolean;
|
||||
gitHashInterval: number = 600000; // 10 minutes
|
||||
gitHashInterval: number = 60000; // 1 minute
|
||||
pollInterval: number = 60000; // 1 minute
|
||||
pollTimer: NodeJS.Timeout | null = null;
|
||||
pollConnection = axios.create();
|
||||
|
|
@ -111,7 +111,7 @@ class FailoverRouter {
|
|||
for (const host of this.hosts) {
|
||||
try {
|
||||
const result = await (host.socket
|
||||
? this.pollConnection.get<number>('/blocks/tip/height', { socketPath: host.host, timeout: config.ESPLORA.FALLBACK_TIMEOUT })
|
||||
? this.pollConnection.get<number>('http://api/blocks/tip/height', { socketPath: host.host, timeout: config.ESPLORA.FALLBACK_TIMEOUT })
|
||||
: this.pollConnection.get<number>(host.host + '/blocks/tip/height', { timeout: config.ESPLORA.FALLBACK_TIMEOUT })
|
||||
);
|
||||
if (result) {
|
||||
|
|
@ -288,7 +288,7 @@ class FailoverRouter {
|
|||
let url;
|
||||
if (host.socket) {
|
||||
axiosConfig = { socketPath: host.host, timeout: config.ESPLORA.REQUEST_TIMEOUT, responseType };
|
||||
url = path;
|
||||
url = 'http://api' + path;
|
||||
} else {
|
||||
axiosConfig = { timeout: config.ESPLORA.REQUEST_TIMEOUT, responseType };
|
||||
url = host.host + path;
|
||||
|
|
|
|||
|
|
@ -1391,7 +1391,7 @@ class Blocks {
|
|||
}
|
||||
|
||||
public async $getBlockAuditSummary(hash: string): Promise<BlockAudit | null> {
|
||||
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK)) {
|
||||
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) && Common.auditIndexingEnabled()) {
|
||||
return BlocksAuditsRepository.$getBlockAudit(hash);
|
||||
} else {
|
||||
return null;
|
||||
|
|
@ -1399,7 +1399,7 @@ class Blocks {
|
|||
}
|
||||
|
||||
public async $getBlockTxAuditSummary(hash: string, txid: string): Promise<TransactionAudit | null> {
|
||||
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK)) {
|
||||
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) && Common.auditIndexingEnabled()) {
|
||||
return BlocksAuditsRepository.$getBlockTxAudit(hash, txid);
|
||||
} else {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -722,6 +722,13 @@ export class Common {
|
|||
);
|
||||
}
|
||||
|
||||
static auditIndexingEnabled(): boolean {
|
||||
return (
|
||||
Common.indexingEnabled() &&
|
||||
config.MEMPOOL.AUDIT === true
|
||||
);
|
||||
}
|
||||
|
||||
static gogglesIndexingEnabled(): boolean {
|
||||
return (
|
||||
Common.blocksSummariesIndexingEnabled() &&
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import mining from './mining/mining';
|
|||
import transactionUtils from './transaction-utils';
|
||||
import BlocksRepository from '../repositories/BlocksRepository';
|
||||
import redisCache from './redis-cache';
|
||||
import blocks from './blocks';
|
||||
|
||||
class PoolsParser {
|
||||
miningPools: any[] = [];
|
||||
|
|
@ -42,6 +43,8 @@ class PoolsParser {
|
|||
await this.$insertUnknownPool();
|
||||
|
||||
let reindexUnknown = false;
|
||||
let clearCache = false;
|
||||
|
||||
|
||||
for (const pool of this.miningPools) {
|
||||
if (!pool.id) {
|
||||
|
|
@ -78,17 +81,20 @@ class PoolsParser {
|
|||
logger.debug(`Inserting new mining pool ${pool.name}`);
|
||||
await PoolsRepository.$insertNewMiningPool(pool, slug);
|
||||
reindexUnknown = true;
|
||||
clearCache = true;
|
||||
} else {
|
||||
if (poolDB.name !== pool.name) {
|
||||
// Pool has been renamed
|
||||
const newSlug = pool.name.replace(/[^a-z0-9]/gi, '').toLowerCase();
|
||||
logger.warn(`Renaming ${poolDB.name} mining pool to ${pool.name}. Slug has been updated. Maybe you want to make a redirection from 'https://mempool.space/mining/pool/${poolDB.slug}' to 'https://mempool.space/mining/pool/${newSlug}`);
|
||||
await PoolsRepository.$renameMiningPool(poolDB.id, newSlug, pool.name);
|
||||
clearCache = true;
|
||||
}
|
||||
if (poolDB.link !== pool.link) {
|
||||
// Pool link has changed
|
||||
logger.debug(`Updating link for ${pool.name} mining pool`);
|
||||
await PoolsRepository.$updateMiningPoolLink(poolDB.id, pool.link);
|
||||
clearCache = true;
|
||||
}
|
||||
if (JSON.stringify(pool.addresses) !== poolDB.addresses ||
|
||||
JSON.stringify(pool.regexes) !== poolDB.regexes) {
|
||||
|
|
@ -96,6 +102,7 @@ class PoolsParser {
|
|||
logger.notice(`Updating addresses and/or coinbase tags for ${pool.name} mining pool.`);
|
||||
await PoolsRepository.$updateMiningPoolTags(poolDB.id, pool.addresses, pool.regexes);
|
||||
reindexUnknown = true;
|
||||
clearCache = true;
|
||||
await this.$reindexBlocksForPool(poolDB.id);
|
||||
}
|
||||
}
|
||||
|
|
@ -111,6 +118,19 @@ class PoolsParser {
|
|||
}
|
||||
await this.$reindexBlocksForPool(unknownPool.id);
|
||||
}
|
||||
|
||||
// refresh the in-memory block cache with the reindexed data
|
||||
if (clearCache) {
|
||||
for (const block of blocks.getBlocks()) {
|
||||
const reindexedBlock = await blocks.$indexBlock(block.height);
|
||||
if (reindexedBlock.id === block.id) {
|
||||
block.extras.pool = reindexedBlock.extras.pool;
|
||||
}
|
||||
}
|
||||
// update persistent cache with the reindexed data
|
||||
diskCache.$saveCacheToDisk();
|
||||
redisCache.$updateBlocks(blocks.getBlocks());
|
||||
}
|
||||
}
|
||||
|
||||
public matchBlockMiner(scriptsig: string, addresses: string[], pools: PoolTag[]): PoolTag | undefined {
|
||||
|
|
|
|||
|
|
@ -1011,15 +1011,19 @@ class WebsocketHandler {
|
|||
const blockTransactions = structuredClone(transactions);
|
||||
|
||||
this.printLogs();
|
||||
await statistics.runStatistics();
|
||||
if (config.STATISTICS.ENABLED && config.DATABASE.ENABLED) {
|
||||
await statistics.runStatistics();
|
||||
}
|
||||
|
||||
const _memPool = memPool.getMempool();
|
||||
const candidateTxs = await memPool.getMempoolCandidates();
|
||||
let candidates: GbtCandidates | undefined = (memPool.limitGBT && candidateTxs) ? { txs: candidateTxs, added: [], removed: [] } : undefined;
|
||||
let transactionIds: string[] = (memPool.limitGBT) ? Object.keys(candidates?.txs || {}) : Object.keys(_memPool);
|
||||
|
||||
const accelerations = Object.values(mempool.getAccelerations());
|
||||
await accelerationRepository.$indexAccelerationsForBlock(block, accelerations, structuredClone(transactions));
|
||||
if (config.DATABASE.ENABLED) {
|
||||
const accelerations = Object.values(mempool.getAccelerations());
|
||||
await accelerationRepository.$indexAccelerationsForBlock(block, accelerations, structuredClone(transactions));
|
||||
}
|
||||
|
||||
const rbfTransactions = Common.findMinedRbfTransactions(transactions, memPool.getSpendMap());
|
||||
memPool.handleRbfTransactions(rbfTransactions);
|
||||
|
|
@ -1095,7 +1099,9 @@ class WebsocketHandler {
|
|||
if (config.CORE_RPC.DEBUG_LOG_PATH && block.extras) {
|
||||
const firstSeen = getRecentFirstSeen(block.id);
|
||||
if (firstSeen) {
|
||||
BlocksRepository.$saveFirstSeenTime(block.id, firstSeen);
|
||||
if (config.DATABASE.ENABLED) {
|
||||
BlocksRepository.$saveFirstSeenTime(block.id, firstSeen);
|
||||
}
|
||||
block.extras.firstSeen = firstSeen;
|
||||
}
|
||||
}
|
||||
|
|
@ -1392,7 +1398,9 @@ class WebsocketHandler {
|
|||
});
|
||||
}
|
||||
|
||||
await statistics.runStatistics();
|
||||
if (config.STATISTICS.ENABLED && config.DATABASE.ENABLED) {
|
||||
await statistics.runStatistics();
|
||||
}
|
||||
}
|
||||
|
||||
public handleNewStratumJob(job: StratumJob): void {
|
||||
|
|
|
|||
|
|
@ -156,7 +156,9 @@ class Server {
|
|||
|
||||
await poolsUpdater.updatePoolsJson(); // Needs to be done before loading the disk cache because we sometimes wipe it
|
||||
await syncAssets.syncAssets$();
|
||||
await mempoolBlocks.updatePools$();
|
||||
if (config.DATABASE.ENABLED) {
|
||||
await mempoolBlocks.updatePools$();
|
||||
}
|
||||
if (config.MEMPOOL.ENABLED) {
|
||||
if (config.MEMPOOL.CACHE_ENABLED) {
|
||||
await diskCache.$loadMempoolCache();
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ class PoolsUpdater {
|
|||
logger.info(`Mining pools-v2.json (${githubSha}) import completed`, this.tag);
|
||||
|
||||
} catch (e) {
|
||||
this.lastRun = now - 600; // Try again in 10 minutes
|
||||
// fast-forward lastRun to 10 minutes before the next scheduled update
|
||||
this.lastRun = now - Math.max(config.MEMPOOL.POOLS_UPDATE_DELAY - 600, 600);
|
||||
logger.err(`PoolsUpdater failed. Will try again in 10 minutes. Exception: ${JSON.stringify(e)}`, this.tag);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ WORKDIR /build
|
|||
RUN apt-get update && \
|
||||
apt-get install -y curl ca-certificates && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
|
||||
apt-get install -y nodejs build-essential python3 pkg-config && \
|
||||
apt-get install -y nodejs=22.14.0-1nodesource1 build-essential python3 pkg-config && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ FROM rust:1.84-bookworm AS runtime
|
|||
RUN apt-get update && \
|
||||
apt-get install -y curl ca-certificates && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \
|
||||
apt-get install -y nodejs && \
|
||||
apt-get install -y nodejs=22.14.0-1nodesource1 && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ __MEMPOOL_EXTERNAL_MAX_RETRY__=${MEMPOOL_EXTERNAL_MAX_RETRY:=1}
|
|||
__MEMPOOL_EXTERNAL_RETRY_INTERVAL__=${MEMPOOL_EXTERNAL_RETRY_INTERVAL:=0}
|
||||
__MEMPOOL_USER_AGENT__=${MEMPOOL_USER_AGENT:=mempool}
|
||||
__MEMPOOL_STDOUT_LOG_MIN_PRIORITY__=${MEMPOOL_STDOUT_LOG_MIN_PRIORITY:=info}
|
||||
__MEMPOOL_AUTOMATIC_POOLS_UPDATE__=${MEMPOOL_AUTOMATIC_POOLS_UPDATE:=false}
|
||||
__MEMPOOL_AUTOMATIC_POOLS_UPDATE__=${MEMPOOL_AUTOMATIC_POOLS_UPDATE:=true}
|
||||
__MEMPOOL_POOLS_JSON_URL__=${MEMPOOL_POOLS_JSON_URL:=https://raw.githubusercontent.com/mempool/mining-pools/master/pools-v2.json}
|
||||
__MEMPOOL_POOLS_JSON_TREE_URL__=${MEMPOOL_POOLS_JSON_TREE_URL:=https://api.github.com/repos/mempool/mining-pools/git/trees/master}
|
||||
__MEMPOOL_POOLS_UPDATE_DELAY__=${MEMPOOL_POOLS_UPDATE_DELAY:=604800}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM node:22-bookworm-slim AS builder
|
||||
FROM node:22.14.0-bookworm-slim AS builder
|
||||
|
||||
ARG commitHash
|
||||
ENV DOCKER_COMMIT_HASH=${commitHash}
|
||||
|
|
|
|||
4
frontend/package-lock.json
generated
4
frontend/package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "mempool-frontend",
|
||||
"version": "3.1.0-dev",
|
||||
"version": "3.3-dev",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mempool-frontend",
|
||||
"version": "3.1.0-dev",
|
||||
"version": "3.2.0-dev",
|
||||
"license": "GNU Affero General Public License v3.0",
|
||||
"dependencies": {
|
||||
"@angular-devkit/build-angular": "^17.3.1",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mempool-frontend",
|
||||
"version": "3.1.0-dev",
|
||||
"version": "3.3-dev",
|
||||
"description": "Bitcoin mempool visualizer and blockchain explorer backend",
|
||||
"license": "GNU Affero General Public License v3.0",
|
||||
"homepage": "https://mempool.space",
|
||||
|
|
@ -121,4 +121,4 @@
|
|||
"scarfSettings": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,74 +84,79 @@ div.scrollable {
|
|||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.progress {
|
||||
background-color: var(--secondary);
|
||||
.progress {
|
||||
background-color: var(--secondary);
|
||||
}
|
||||
|
||||
.coinbase {
|
||||
width: 20%;
|
||||
@media (max-width: 875px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.coinbase {
|
||||
width: 20%;
|
||||
@media (max-width: 875px) {
|
||||
display: none;
|
||||
}
|
||||
.health {
|
||||
@media (max-width: 1150px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.height {
|
||||
width: 10%;
|
||||
.height {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
@media (max-width: 875px) {
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
@media (max-width: 875px) {
|
||||
padding-left: 50px;
|
||||
}
|
||||
@media (max-width: 685px) {
|
||||
display: none;
|
||||
}
|
||||
@media (max-width: 625px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mined {
|
||||
width: 13%;
|
||||
@media (max-width: 1100px) {
|
||||
display: none;
|
||||
}
|
||||
.mined {
|
||||
width: 13%;
|
||||
}
|
||||
|
||||
.txs {
|
||||
@media (max-width: 938px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.txs {
|
||||
padding-right: 40px;
|
||||
@media (max-width: 1100px) {
|
||||
padding-right: 10px;
|
||||
}
|
||||
@media (max-width: 875px) {
|
||||
padding-right: 20px;
|
||||
}
|
||||
@media (max-width: 567px) {
|
||||
padding-right: 10px;
|
||||
}
|
||||
padding-right: 40px;
|
||||
@media (max-width: 1100px) {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.size {
|
||||
width: 12%;
|
||||
@media (max-width: 1000px) {
|
||||
width: 15%;
|
||||
}
|
||||
@media (max-width: 875px) {
|
||||
width: 20%;
|
||||
}
|
||||
@media (max-width: 650px) {
|
||||
width: 20%;
|
||||
}
|
||||
@media (max-width: 450px) {
|
||||
display: none;
|
||||
}
|
||||
@media (max-width: 875px) {
|
||||
padding-right: 20px;
|
||||
}
|
||||
@media (max-width: 567px) {
|
||||
padding-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.scriptmessage {
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
width: auto;
|
||||
text-align: left;
|
||||
.size {
|
||||
min-width: 80px;
|
||||
width: 12%;
|
||||
@media (max-width: 1000px) {
|
||||
width: 15%;
|
||||
}
|
||||
}
|
||||
|
||||
.scriptmessage {
|
||||
max-width: 340px;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
width: auto;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.reward {
|
||||
@media (max-width: 1035px) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ export class TransactionsListComponent implements OnInit, OnChanges {
|
|||
}
|
||||
|
||||
this.transactionsLength = this.transactions.length;
|
||||
|
||||
|
||||
if (!this.txPreview) {
|
||||
this.cacheService.setTxCache(this.transactions);
|
||||
}
|
||||
|
|
@ -316,10 +316,7 @@ export class TransactionsListComponent implements OnInit, OnChanges {
|
|||
|
||||
// Check for address poisoning similarity matches
|
||||
this.similarityMatches.set(tx.txid, new Map());
|
||||
const comparableVouts = [
|
||||
...tx.vout.slice(0, 20),
|
||||
...this.addresses.map(addr => ({ scriptpubkey_address: addr, scriptpubkey_type: detectAddressType(addr, this.stateService.network) }))
|
||||
].filter(v => ['p2pkh', 'p2sh', 'v0_p2wpkh', 'v0_p2wsh', 'v1_p2tr'].includes(v.scriptpubkey_type));
|
||||
const comparableVouts = tx.vout.slice(0, 20).filter(v => ['p2pkh', 'p2sh', 'v0_p2wpkh', 'v0_p2wsh', 'v1_p2tr'].includes(v.scriptpubkey_type));
|
||||
const comparableVins = tx.vin.slice(0, 20).map(v => v.prevout).filter(v => ['p2pkh', 'p2sh', 'v0_p2wpkh', 'v0_p2wsh', 'v1_p2tr'].includes(v?.scriptpubkey_type));
|
||||
for (const vout of comparableVouts) {
|
||||
const address = vout.scriptpubkey_address;
|
||||
|
|
|
|||
|
|
@ -327,6 +327,8 @@ export class StateService {
|
|||
|
||||
this.networkChanged$.subscribe((network) => {
|
||||
this.transactions$ = new BehaviorSubject<TransactionStripped[]>(null);
|
||||
this.stratumJobs$ = new BehaviorSubject<Record<string, StratumJob>>({});
|
||||
this.stratumJobUpdate$.next({ state: {} });
|
||||
this.blocksSubject$.next([]);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@
|
|||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
}
|
||||
location /api/v1/services {
|
||||
proxy_pass https://mempool.space;
|
||||
}
|
||||
location /api/v1 {
|
||||
proxy_pass http://127.0.0.1:8999/api/v1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,9 @@ CLN_INSTALL=ON
|
|||
# install UNFURL
|
||||
UNFURL_INSTALL=ON
|
||||
|
||||
# install CKPOOL
|
||||
CKPOOL_MAINNET_INSTALL=ON
|
||||
|
||||
# configure 4 network instances
|
||||
BITCOIN_MAINNET_ENABLE=ON
|
||||
BITCOIN_MAINNET_MINFEE_ENABLE=ON
|
||||
|
|
@ -56,6 +59,11 @@ BISQ_MAINNET_ENABLE=ON
|
|||
ELEMENTS_LIQUID_ENABLE=ON
|
||||
ELEMENTS_LIQUIDTESTNET_ENABLE=ON
|
||||
|
||||
# configure 3 CKPool instances
|
||||
BITCOIN_MAINNET_CKPOOL=ON
|
||||
BITCOIN_TESTNET_CKPOOL=ON
|
||||
BITCOIN_TESTNET4_CKPOOL=ON
|
||||
|
||||
# enable lightmode and disable compaction to fit on 1TB SSD drive
|
||||
BITCOIN_ELECTRS_INSTALL=ON
|
||||
BITCOIN_ELECTRS_LIGHT_MODE=ON
|
||||
|
|
@ -197,6 +205,18 @@ MEMPOOL_SIGNET_HTTP_PORT=8995
|
|||
MEMPOOL_LIQUIDTESTNET_HTTP_HOST=127.0.0.1
|
||||
MEMPOOL_LIQUIDTESTNET_HTTP_PORT=8994
|
||||
|
||||
# set CKPool bitcoin mainnet port
|
||||
CKPOOL_MAINNET_STRATUM_HOST=127.0.0.1
|
||||
CKPOOL_MAINNET_STRATUM_PORT=3333
|
||||
|
||||
# set CKPool bitcoin mainnet port
|
||||
CKPOOL_TESTNET_STRATUM_HOST=127.0.0.1
|
||||
CKPOOL_TESTNET_STRATUM_PORT=3334
|
||||
|
||||
# set CKPool bitcoin mainnet port
|
||||
CKPOOL_TESTNET4_STRATUM_HOST=127.0.0.1
|
||||
CKPOOL_TESTNET4_STRATUM_PORT=3335
|
||||
|
||||
##### OS options, should be automatically detected
|
||||
|
||||
case $OS in
|
||||
|
|
@ -283,6 +303,11 @@ BITCOIN_GROUP=bitcoin
|
|||
# bitcoin core data folder, needs about 300GB
|
||||
BITCOIN_HOME=/bitcoin
|
||||
|
||||
# ckpool user/group
|
||||
CKPOOL_HOME=/ckpool
|
||||
CKPOOL_USER=ckpool
|
||||
CKPOOL_GROUP=ckpool
|
||||
|
||||
# bitcoin testnet data
|
||||
BITCOIN_TESTNET_DATA=${BITCOIN_HOME}/testnet3
|
||||
# bitcoin testnet4 data
|
||||
|
|
@ -367,6 +392,12 @@ BISQ_REPO_BRANCH=master
|
|||
BISQ_LATEST_RELEASE=master
|
||||
echo -n '.'
|
||||
|
||||
CKPOOL_URL=https://github.com/mempool/ckpool
|
||||
CKPOOL_REPO_NAME=ckpool
|
||||
CKPOOL_REPO_BRANCH=master
|
||||
CKPOOL_LATEST_RELEASE=$(curl -s https://api.github.com/repos/mempool/ckpool/releases/latest|grep tag_name|head -1|cut -d '"' -f4)
|
||||
echo -n '.'
|
||||
|
||||
UNFURL_REPO_URL=https://github.com/mempool/mempool
|
||||
UNFURL_REPO_NAME=unfurl
|
||||
UNFURL_REPO_BRANCH=master
|
||||
|
|
@ -418,9 +449,10 @@ DEBIAN_UNFURL_PKG+=(libxdamage-dev libxrandr-dev libgbm-dev libpango1.0-dev liba
|
|||
FREEBSD_PKG=()
|
||||
FREEBSD_PKG+=(zsh sudo git git-lfs screen curl wget calc neovim)
|
||||
FREEBSD_PKG+=(openssh-portable py311-pip rust llvm17 jq base64 libzmq4)
|
||||
FREEBSD_PKG+=(boost-libs autoconf automake gmake gcc libevent libtool pkgconf)
|
||||
FREEBSD_PKG+=(boost-libs autoconf automake gmake gcc13 libevent libtool pkgconf)
|
||||
FREEBSD_PKG+=(nginx rsync py311-certbot-nginx mariadb1011-server)
|
||||
FREEBSD_PKG+=(geoipupdate redis)
|
||||
FREEBSD_PKG+=(libepoll-shim)
|
||||
|
||||
FREEBSD_UNFURL_PKG=()
|
||||
FREEBSD_UNFURL_PKG+=(nvidia-driver-470 chromium xinit xterm twm ja-sourcehansans-otf)
|
||||
|
|
@ -1113,10 +1145,10 @@ echo "[*] Installing Mempool crontab"
|
|||
osSudo "${ROOT_USER}" crontab -u "${MEMPOOL_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/mempool.crontab"
|
||||
|
||||
echo "[*] Installing nvm.sh from GitHub"
|
||||
osSudo "${MEMPOOL_USER}" sh -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh'
|
||||
osSudo "${MEMPOOL_USER}" sh -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash'
|
||||
|
||||
echo "[*] Building NodeJS via nvm.sh"
|
||||
osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm install v22.14.0 --shared-zlib'
|
||||
osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; CC=gcc CXX=g++ nvm install v22.14.0 --shared-zlib'
|
||||
osSudo "${MEMPOOL_USER}" zsh -c 'source ~/.zshrc ; nvm alias default 22.14.0'
|
||||
|
||||
####################
|
||||
|
|
@ -1223,6 +1255,76 @@ if [ "${BITCOIN_INSTALL}" = ON ];then
|
|||
osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_PASS__/${BITCOIN_RPC_PASS}/" "${MINFEE_HOME}/bitcoin.conf"
|
||||
fi
|
||||
|
||||
#######################
|
||||
# CKPool Installation #
|
||||
#######################
|
||||
|
||||
#CKPool cronjob installer
|
||||
install_ckpool_cron() {
|
||||
local network=$1
|
||||
local network_label=$2
|
||||
local network_cmd=$3
|
||||
local port=$4
|
||||
|
||||
echo "[*] Installing CKPool ${network_label} Cron for 'ckpool' user"
|
||||
case $OS in
|
||||
FreeBSD)
|
||||
osSudo "${CKPOOL_USER}" sh -c "cd ${CKPOOL_HOME} && (crontab -l > ${TEMP_CRON_FILE} 2>/dev/null || echo \"\" > ${TEMP_CRON_FILE})"
|
||||
osSudo "${CKPOOL_USER}" sh -c "cd ${CKPOOL_HOME} && echo '@reboot screen -dmS ckpool-${network} sh -c \"while true; do ${CKPOOL_HOME}/${CKPOOL_REPO_NAME}/start ${network_cmd} ${port}; sleep 1; done\"' >> ${TEMP_CRON_FILE}"
|
||||
osSudo "${CKPOOL_USER}" sh -c "cd ${CKPOOL_HOME} && crontab ${TEMP_CRON_FILE}"
|
||||
osSudo "${CKPOOL_USER}" sh -c "cd ${CKPOOL_HOME} && rm -f ${TEMP_CRON_FILE}"
|
||||
;;
|
||||
Debian)
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
#CKPool binary Installer
|
||||
if [ "${CKPOOL_INSTALL}" = ON ]; then
|
||||
echo "[*] Creating 'ckpool' user"
|
||||
osGroupCreate "${CKPOOL_GROUP}"
|
||||
osUserCreate "${CKPOOL_USER}" "${CKPOOL_HOME}" "${CKPOOL_GROUP}"
|
||||
osSudo "${ROOT_USER}" chsh -s `which zsh` "${CKPOOL_USER}"
|
||||
|
||||
echo "[*] Creating 'ckpool' data folder"
|
||||
osSudo "${ROOT_USER}" mkdir -p "${CKPOOL_HOME}"
|
||||
osSudo "${ROOT_USER}" chown -R "${CKPOOL_USER}:${CKPOOL_GROUP}" "${CKPOOL_HOME}"
|
||||
osSudo "${CKPOOL_USER}" touch "${CKPOOL_HOME}/.zshrc"
|
||||
|
||||
echo "[*] Creating '.ckpool' directory in ckpool user's home to store config files"
|
||||
osSudo "${ROOT_USER}" mkdir -p "${CKPOOL_HOME}/.ckpool"
|
||||
osSudo "${ROOT_USER}" chown "${CKPOOL_USER}:${CKPOOL_GROUP}" "${CKPOOL_HOME}/.ckpool"
|
||||
|
||||
echo "[*] Cloning Mempool CKPool repo from ${CKPOOL_REPO_URL}"
|
||||
osSudo "${CKPOOL_USER}" git config --global advice.detachedHead false
|
||||
osSudo "${CKPOOL_USER}" git clone --branch "${CKPOOL_REPO_BRANCH}" "${CKPOOL_REPO_URL}" "${CKPOOL_HOME}/${CKPOOL_REPO_NAME}"
|
||||
|
||||
echo "[*] Checking out CKPOOL ${CKPOOL_LATEST_RELEASE}"
|
||||
osSudo "${CKPOOL_USER}" sh -c "cd ${CKPOOL_HOME}/${CKPOOL_REPO_NAME} && git checkout ${CKPOOL_LATEST_RELEASE}"
|
||||
|
||||
echo "[*] Building CKPool from source repo"
|
||||
osSudo "${CKPOOL_USER}" sh -c "cd ${CKPOOL_REPO_NAME} && ./autogen.sh --quiet"
|
||||
osSudo "${CKPOOL_USER}" sh -c "cd ${CKPOOL_REPO_NAME} && ./configure CFLAGS='-O3 -march=native -flto -Wall -I/usr/local/include/libepoll-shim' LDFLAGS='-L/usr/local/lib -lepoll-shim -lpthread'"
|
||||
osSudo "${CKPOOL_USER}" sh -c "cd ${CKPOOL_REPO_NAME} && gmake -j${NPROC}"
|
||||
|
||||
echo "[*] Copy CKPool binarary into OS"
|
||||
osSudo "${ROOT_USER}" sh -c "cd ${CKPOOL_HOME}/${CKPOOL_REPO_NAME} && cp src/ckpool /usr/local/bin"
|
||||
|
||||
TEMP_CRON_FILE="tmp_cron"
|
||||
|
||||
if [ "${BITCOIN_MAINNET_CKPOOL}" = ON ]; then
|
||||
install_ckpool_cron "mainnet" "Mainnet" "bitcoin" 2333
|
||||
fi
|
||||
|
||||
if [ "${BITCOIN_TESTNET_CKPOOL}" = ON ]; then
|
||||
install_ckpool_cron "testnet" "Testnet" "testnet" 2334
|
||||
fi
|
||||
|
||||
if [ "${BITCOIN_TESTNET4_CKPOOL}" = ON ]; then
|
||||
install_ckpool_cron "testnet4" "Testnet4" "testnet4" 2335
|
||||
fi
|
||||
fi
|
||||
|
||||
#########################
|
||||
# Elements installation #
|
||||
#########################
|
||||
|
|
@ -1314,7 +1416,7 @@ if [ "${BITCOIN_ELECTRS_INSTALL}" = ON ];then
|
|||
case $OS in
|
||||
FreeBSD)
|
||||
echo "[*] Patching Bitcoin Electrs code for FreeBSD"
|
||||
osSudo "${BITCOIN_USER}" sh -c "cd \"${BITCOIN_HOME}/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sysconf-0.3.4\" && patch -p1 < \"${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/freebsd/sysconf.patch\""
|
||||
osSudo "${BITCOIN_USER}" sh -c "cd \"${BITCOIN_HOME}/.cargo/registry/src/index.crates.io-6f17d22bba15001f/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"
|
||||
;;
|
||||
|
|
|
|||
4
unfurler/package-lock.json
generated
4
unfurler/package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "mempool-unfurl",
|
||||
"version": "3.1.0-dev",
|
||||
"version": "3.2.0-dev",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mempool-unfurl",
|
||||
"version": "3.0.0",
|
||||
"version": "3.2.0-dev",
|
||||
"dependencies": {
|
||||
"@types/node": "^16.11.41",
|
||||
"ejs": "^3.1.10",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mempool-unfurl",
|
||||
"version": "3.1.0-dev",
|
||||
"version": "3.2.0-dev",
|
||||
"description": "Renderer for mempool open graph link preview images",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -32,4 +32,4 @@
|
|||
"eslint-config-prettier": "^8.5.0",
|
||||
"prettier": "^2.7.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue