Merge branch 'master' into nymkappa/bugfix/handle-error-pool-hashrate
This commit is contained in:
		
						commit
						57276b7abd
					
				
							
								
								
									
										42
									
								
								backend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										42
									
								
								backend/package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -17,9 +17,9 @@ | ||||
|         "express": "^4.18.0", | ||||
|         "mysql2": "2.3.3", | ||||
|         "node-worker-threads-pool": "^1.5.1", | ||||
|         "socks-proxy-agent": "^6.2.0", | ||||
|         "typescript": "~4.7.2", | ||||
|         "ws": "~8.7.0" | ||||
|         "socks-proxy-agent": "~7.0.0", | ||||
|         "typescript": "~4.7.4", | ||||
|         "ws": "~8.8.0" | ||||
|       }, | ||||
|       "devDependencies": { | ||||
|         "@types/compression": "^1.7.2", | ||||
| @ -2734,9 +2734,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "node_modules/socks-proxy-agent": { | ||||
|       "version": "6.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz", | ||||
|       "integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==", | ||||
|       "version": "7.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", | ||||
|       "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", | ||||
|       "dependencies": { | ||||
|         "agent-base": "^6.0.2", | ||||
|         "debug": "^4.3.3", | ||||
| @ -2950,9 +2950,9 @@ | ||||
|       "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" | ||||
|     }, | ||||
|     "node_modules/typescript": { | ||||
|       "version": "4.7.2", | ||||
|       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", | ||||
|       "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==", | ||||
|       "version": "4.7.4", | ||||
|       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", | ||||
|       "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", | ||||
|       "bin": { | ||||
|         "tsc": "bin/tsc", | ||||
|         "tsserver": "bin/tsserver" | ||||
| @ -3052,9 +3052,9 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "node_modules/ws": { | ||||
|       "version": "8.7.0", | ||||
|       "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", | ||||
|       "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", | ||||
|       "version": "8.8.0", | ||||
|       "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", | ||||
|       "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", | ||||
|       "engines": { | ||||
|         "node": ">=10.0.0" | ||||
|       }, | ||||
| @ -5098,9 +5098,9 @@ | ||||
|       } | ||||
|     }, | ||||
|     "socks-proxy-agent": { | ||||
|       "version": "6.2.0", | ||||
|       "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.0.tgz", | ||||
|       "integrity": "sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==", | ||||
|       "version": "7.0.0", | ||||
|       "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", | ||||
|       "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", | ||||
|       "requires": { | ||||
|         "agent-base": "^6.0.2", | ||||
|         "debug": "^4.3.3", | ||||
| @ -5256,9 +5256,9 @@ | ||||
|       "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==" | ||||
|     }, | ||||
|     "typescript": { | ||||
|       "version": "4.7.2", | ||||
|       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.2.tgz", | ||||
|       "integrity": "sha512-Mamb1iX2FDUpcTRzltPxgWMKy3fhg0TN378ylbktPGPK/99KbDtMQ4W1hwgsbPAsG3a0xKa1vmw4VKZQbkvz5A==" | ||||
|       "version": "4.7.4", | ||||
|       "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz", | ||||
|       "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==" | ||||
|     }, | ||||
|     "unpipe": { | ||||
|       "version": "1.0.0", | ||||
| @ -5333,9 +5333,9 @@ | ||||
|       "dev": true | ||||
|     }, | ||||
|     "ws": { | ||||
|       "version": "8.7.0", | ||||
|       "resolved": "https://registry.npmjs.org/ws/-/ws-8.7.0.tgz", | ||||
|       "integrity": "sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg==", | ||||
|       "version": "8.8.0", | ||||
|       "resolved": "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz", | ||||
|       "integrity": "sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==", | ||||
|       "requires": {} | ||||
|     }, | ||||
|     "yallist": { | ||||
|  | ||||
| @ -37,9 +37,9 @@ | ||||
|     "express": "^4.18.0", | ||||
|     "mysql2": "2.3.3", | ||||
|     "node-worker-threads-pool": "^1.5.1", | ||||
|     "socks-proxy-agent": "^6.2.0", | ||||
|     "typescript": "~4.7.2", | ||||
|     "ws": "~8.7.0" | ||||
|     "socks-proxy-agent": "~7.0.0", | ||||
|     "typescript": "~4.7.4", | ||||
|     "ws": "~8.8.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/compression": "^1.7.2", | ||||
|  | ||||
| @ -295,7 +295,8 @@ class Blocks { | ||||
|       } | ||||
|       logger.notice(`Blocks summaries indexing completed: indexed ${newlyIndexed} blocks`); | ||||
|     } catch (e) { | ||||
|       logger.err(`Blocks summaries indexing failed. Reason: ${(e instanceof Error ? e.message : e)}`); | ||||
|       logger.err(`Blocks summaries indexing failed. Trying again in 10 seconds. Reason: ${(e instanceof Error ? e.message : e)}`); | ||||
|       throw e; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
| @ -367,18 +368,12 @@ class Blocks { | ||||
|       logger.notice(`Block indexing completed: indexed ${newlyIndexed} blocks`); | ||||
|       loadingIndicators.setProgress('block-indexing', 100); | ||||
|     } catch (e) { | ||||
|       logger.err('Block indexing failed. Trying again later. Reason: ' + (e instanceof Error ? e.message : e)); | ||||
|       logger.err('Block indexing failed. Trying again in 10 seconds. Reason: ' + (e instanceof Error ? e.message : e)); | ||||
|       loadingIndicators.setProgress('block-indexing', 100); | ||||
|       return false; | ||||
|       throw e; | ||||
|     } | ||||
| 
 | ||||
|     const chainValid = await BlocksRepository.$validateChain(); | ||||
|     if (!chainValid) { | ||||
|       indexer.reindex(); | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     return true; | ||||
|     return await BlocksRepository.$validateChain(); | ||||
|   } | ||||
| 
 | ||||
|   public async $updateBlocks() { | ||||
|  | ||||
| @ -7,7 +7,9 @@ import logger from '../logger'; | ||||
| import { Common } from './common'; | ||||
| import loadingIndicators from './loading-indicators'; | ||||
| import { escape } from 'mysql2'; | ||||
| import indexer from '../indexer'; | ||||
| import DifficultyAdjustmentsRepository from '../repositories/DifficultyAdjustmentsRepository'; | ||||
| import config from '../config'; | ||||
| 
 | ||||
| class Mining { | ||||
|   constructor() { | ||||
| @ -263,6 +265,7 @@ class Mining { | ||||
|       loadingIndicators.setProgress('weekly-hashrate-indexing', 100); | ||||
|     } catch (e) { | ||||
|       loadingIndicators.setProgress('weekly-hashrate-indexing', 100); | ||||
|       logger.err(`Weekly mining pools hashrates indexing failed. Trying again in 10 seconds. Reason: ${(e instanceof Error ? e.message : e)}`); | ||||
|       throw e; | ||||
|     } | ||||
|   } | ||||
| @ -302,7 +305,7 @@ class Mining { | ||||
|       while (toTimestamp > genesisTimestamp) { | ||||
|         const fromTimestamp = toTimestamp - 86400000; | ||||
| 
 | ||||
|         // Skip already indexed weeks
 | ||||
|         // Skip already indexed days
 | ||||
|         if (indexedTimestamp.includes(toTimestamp / 1000)) { | ||||
|           toTimestamp -= 86400000; | ||||
|           ++totalIndexed; | ||||
| @ -313,7 +316,7 @@ class Mining { | ||||
|         // we are currently indexing has complete data)
 | ||||
|         const blockStatsPreviousDay: any = await BlocksRepository.$blockCountBetweenTimestamp( | ||||
|           null, (fromTimestamp - 86400000) / 1000, (toTimestamp - 86400000) / 1000); | ||||
|         if (blockStatsPreviousDay.blockCount === 0) { // We are done indexing
 | ||||
|         if (blockStatsPreviousDay.blockCount === 0 && config.MEMPOOL.NETWORK === 'mainnet') { // We are done indexing
 | ||||
|           break; | ||||
|         } | ||||
| 
 | ||||
| @ -357,9 +360,10 @@ class Mining { | ||||
|       // Add genesis block manually
 | ||||
|       if (toTimestamp <= genesisTimestamp && !indexedTimestamp.includes(genesisTimestamp)) { | ||||
|         hashrates.push({ | ||||
|           hashrateTimestamp: genesisTimestamp, | ||||
|           hashrateTimestamp: genesisTimestamp / 1000, | ||||
|           avgHashrate: await bitcoinClient.getNetworkHashPs(1, 1), | ||||
|           poolId: null, | ||||
|           poolId: 0, | ||||
|           share: 1, | ||||
|           type: 'daily', | ||||
|         }); | ||||
|       } | ||||
| @ -374,6 +378,7 @@ class Mining { | ||||
|       loadingIndicators.setProgress('daily-hashrate-indexing', 100); | ||||
|     } catch (e) { | ||||
|       loadingIndicators.setProgress('daily-hashrate-indexing', 100); | ||||
|       logger.err(`Daily network hashrate indexing failed. Trying again in 10 seconds. Reason: ${(e instanceof Error ? e.message : e)}`); | ||||
|       throw e; | ||||
|     } | ||||
|   } | ||||
| @ -393,6 +398,15 @@ class Mining { | ||||
|     let currentDifficulty = 0; | ||||
|     let totalIndexed = 0; | ||||
| 
 | ||||
|     if (indexedHeights[0] === false) { | ||||
|       await DifficultyAdjustmentsRepository.$saveAdjustments({ | ||||
|         time: 1231006505, | ||||
|         height: 0, | ||||
|         difficulty: 1.0, | ||||
|         adjustment: 0.0, | ||||
|       }); | ||||
|     } | ||||
| 
 | ||||
|     for (const block of blocks) { | ||||
|       if (block.difficulty !== currentDifficulty) { | ||||
|         if (block.height === 0 || indexedHeights[block.height] === true) { // Already indexed
 | ||||
|  | ||||
| @ -285,6 +285,7 @@ class Server { | ||||
|         .get(config.MEMPOOL.API_URL_PREFIX + 'mining/pool/:slug', routes.$getPool) | ||||
|         .get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/pools/:interval', routes.$getPoolsHistoricalHashrate) | ||||
|         .get(config.MEMPOOL.API_URL_PREFIX + 'mining/hashrate/:interval', routes.$getHistoricalHashrate) | ||||
|         .get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty-adjustments', routes.$getDifficultyAdjustments) | ||||
|         .get(config.MEMPOOL.API_URL_PREFIX + 'mining/reward-stats/:blockCount', routes.$getRewardStats) | ||||
|         .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/fees/:interval', routes.$getHistoricalBlockFees) | ||||
|         .get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/rewards/:interval', routes.$getHistoricalBlockRewards) | ||||
|  | ||||
| @ -39,6 +39,8 @@ class Indexer { | ||||
|       const chainValid = await blocks.$generateBlockDatabase(); | ||||
|       if (chainValid === false) { | ||||
|         // Chain of block hash was invalid, so we need to reindex. Stop here and continue at the next iteration
 | ||||
|         logger.warn(`The chain of block hash is invalid, re-indexing invalid data in 10 seconds.`); | ||||
|         setTimeout(() => this.reindex(), 10000); | ||||
|         this.indexerRunning = false; | ||||
|         return; | ||||
|       } | ||||
| @ -49,8 +51,9 @@ class Indexer { | ||||
|       await mining.$generatePoolHashrateHistory(); | ||||
|       await blocks.$generateBlocksSummariesDatabase(); | ||||
|     } catch (e) { | ||||
|       this.reindex(); | ||||
|       logger.err(`Indexer failed, trying again later. Reason: ` + (e instanceof Error ? e.message : e)); | ||||
|       this.indexerRunning = false; | ||||
|       logger.err(`Indexer failed, trying again in 10 seconds. Reason: ` + (e instanceof Error ? e.message : e)); | ||||
|       setTimeout(() => this.reindex(), 10000); | ||||
|     } | ||||
| 
 | ||||
|     this.indexerRunning = false; | ||||
| @ -62,6 +65,7 @@ class Indexer { | ||||
|       await HashratesRepository.$setLatestRun('last_weekly_hashrates_indexing', 0); | ||||
|     } catch (e) { | ||||
|       logger.err(`Cannot reset hashrate indexing timestamps. Reason: ` + (e instanceof Error ? e.message : e)); | ||||
|       throw e; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -436,7 +436,7 @@ class BlocksRepository { | ||||
|         } | ||||
| 
 | ||||
|         if (blocks[idx].previous_block_hash !== blocks[idx - 1].hash) { | ||||
|           logger.warn(`Chain divergence detected at block ${blocks[idx - 1].height}, re-indexing newer blocks and hashrates`); | ||||
|           logger.warn(`Chain divergence detected at block ${blocks[idx - 1].height}`); | ||||
|           await this.$deleteBlocksFrom(blocks[idx - 1].height); | ||||
|           await BlocksSummariesRepository.$deleteBlocksFrom(blocks[idx - 1].height); | ||||
|           await HashratesRepository.$deleteHashratesFromTimestamp(blocks[idx - 1].timestamp - 604800); | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| import { Common } from '../api/common'; | ||||
| import config from '../config'; | ||||
| import DB from '../database'; | ||||
| import logger from '../logger'; | ||||
| import { IndexedDifficultyAdjustment } from '../mempool.interfaces'; | ||||
| @ -31,13 +32,19 @@ class DifficultyAdjustmentsRepository { | ||||
|   public async $getAdjustments(interval: string | null, descOrder: boolean = false): Promise<IndexedDifficultyAdjustment[]> { | ||||
|     interval = Common.getSqlInterval(interval); | ||||
| 
 | ||||
|     let query = `SELECT UNIX_TIMESTAMP(time) as time, height, difficulty, adjustment
 | ||||
|     let query = `SELECT 
 | ||||
|       CAST(AVG(UNIX_TIMESTAMP(time)) as INT) as time, | ||||
|       CAST(AVG(height) AS INT) as height, | ||||
|       CAST(AVG(difficulty) as DOUBLE) as difficulty, | ||||
|       CAST(AVG(adjustment) as DOUBLE) as adjustment | ||||
|       FROM difficulty_adjustments`;
 | ||||
| 
 | ||||
|     if (interval) { | ||||
|       query += ` WHERE time BETWEEN DATE_SUB(NOW(), INTERVAL ${interval}) AND NOW()`; | ||||
|     } | ||||
| 
 | ||||
|     query += ` GROUP BY UNIX_TIMESTAMP(time) DIV ${86400}`; | ||||
| 
 | ||||
|     if (descOrder === true) { | ||||
|       query += ` ORDER BY time DESC`; | ||||
|     } else { | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| import { escape } from 'mysql2'; | ||||
| import { Common } from '../api/common'; | ||||
| import config from '../config'; | ||||
| import DB from '../database'; | ||||
| import logger from '../logger'; | ||||
| import PoolsRepository from './PoolsRepository'; | ||||
| @ -32,7 +33,9 @@ class HashratesRepository { | ||||
|   public async $getNetworkDailyHashrate(interval: string | null): Promise<any[]> { | ||||
|     interval = Common.getSqlInterval(interval); | ||||
| 
 | ||||
|     let query = `SELECT UNIX_TIMESTAMP(hashrate_timestamp) as timestamp, avg_hashrate as avgHashrate
 | ||||
|     let query = `SELECT
 | ||||
|       CAST(AVG(UNIX_TIMESTAMP(hashrate_timestamp)) as INT) as timestamp, | ||||
|       CAST(AVG(avg_hashrate) as DOUBLE) as avgHashrate | ||||
|       FROM hashrates`;
 | ||||
| 
 | ||||
|     if (interval) { | ||||
| @ -42,6 +45,7 @@ class HashratesRepository { | ||||
|       query += ` WHERE hashrates.type = 'daily'`; | ||||
|     } | ||||
| 
 | ||||
|     query += ` GROUP BY UNIX_TIMESTAMP(hashrate_timestamp) DIV ${86400}`; | ||||
|     query += ` ORDER by hashrate_timestamp`; | ||||
| 
 | ||||
|     try { | ||||
|  | ||||
							
								
								
									
										1153
									
								
								frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1153
									
								
								frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -89,7 +89,7 @@ | ||||
|     "domino": "^2.1.6", | ||||
|     "echarts": "~5.3.2", | ||||
|     "express": "^4.17.1", | ||||
|     "lightweight-charts": "^3.3.0", | ||||
|     "lightweight-charts": "~3.8.0", | ||||
|     "ngx-bootrap-multiselect": "^2.0.0", | ||||
|     "ngx-echarts": "8.0.1", | ||||
|     "ngx-infinite-scroll": "^10.0.1", | ||||
| @ -112,24 +112,24 @@ | ||||
|     "@typescript-eslint/parser": "^5.30.5", | ||||
|     "codelyzer": "~6.0.2", | ||||
|     "eslint": "^8.19.0", | ||||
|     "http-proxy-middleware": "^1.0.5", | ||||
|     "http-proxy-middleware": "~2.0.6", | ||||
|     "jasmine-core": "~4.1.0", | ||||
|     "jasmine-spec-reporter": "~7.0.0", | ||||
|     "karma": "~6.3.19", | ||||
|     "karma-chrome-launcher": "~3.1.0", | ||||
|     "karma-coverage": "~2.0.3", | ||||
|     "karma-jasmine": "~5.0.0", | ||||
|     "karma-jasmine-html-reporter": "^1.5.0", | ||||
|     "ts-node": "~8.3.0", | ||||
|     "karma-coverage": "~2.2.0", | ||||
|     "karma-jasmine": "~5.1.0", | ||||
|     "karma-jasmine-html-reporter": "~2.0.0", | ||||
|     "ts-node": "~10.8.1", | ||||
|     "tslint": "~6.1.0", | ||||
|     "typescript": "~4.6.4" | ||||
|   }, | ||||
|   "optionalDependencies": { | ||||
|     "@cypress/schematic": "^1.3.0", | ||||
|     "@cypress/schematic": "~2.0.0", | ||||
|     "cypress": "^10.0.2", | ||||
|     "cypress-fail-on-console-error": "^2.1.3", | ||||
|     "cypress-fail-on-console-error": "~2.1.4", | ||||
|     "cypress-wait-until": "^1.7.1", | ||||
|     "mock-socket": "^9.0.3", | ||||
|     "start-server-and-test": "^1.12.6" | ||||
|     "mock-socket": "~9.1.4", | ||||
|     "start-server-and-test": "~1.14.0" | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -50,7 +50,7 @@ | ||||
|             <tbody> | ||||
|               <tr> | ||||
|                 <td class="td-width" i18n="block.hash">Hash</td> | ||||
|                 <td><a [routerLink]="['/block/' | relativeUrl, block.id]" title="{{ block.id }}">{{ block.id | shortenString : 13 }}</a> <app-clipboard class="d-none d-sm-inline-block" [text]="block.id"></app-clipboard></td> | ||||
|                 <td>‎<a [routerLink]="['/block/' | relativeUrl, block.id]" title="{{ block.id }}">{{ block.id | shortenString : 13 }}</a> <app-clipboard class="d-none d-sm-inline-block" [text]="block.id"></app-clipboard></td> | ||||
|               </tr> | ||||
|               <tr> | ||||
|                 <td i18n="block.timestamp">Timestamp</td> | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| <div *ngIf="stateService.env.MINING_DASHBOARD" class="mb-3 d-flex menu" style="padding: 0px 35px;"> | ||||
| <div *ngIf="stateService.env.MINING_DASHBOARD" class="mb-3 d-inline-flex menu" style="padding: 0px 35px;"> | ||||
|   <a routerLinkActive="active" class="btn btn-primary w-50 mr-1" | ||||
|     [routerLink]="['/graphs/mempool' | relativeUrl]">Mempool</a> | ||||
|   <div ngbDropdown class="w-50"> | ||||
|  | ||||
| @ -11,6 +11,7 @@ import { StorageService } from 'src/app/services/storage.service'; | ||||
| import { MiningService } from 'src/app/services/mining.service'; | ||||
| import { download } from 'src/app/shared/graphs.utils'; | ||||
| import { ActivatedRoute } from '@angular/router'; | ||||
| import { StateService } from 'src/app/services/state.service'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'app-hashrate-chart', | ||||
| @ -47,7 +48,7 @@ export class HashrateChartComponent implements OnInit { | ||||
|   formatNumber = formatNumber; | ||||
|   timespan = ''; | ||||
|   chartInstance: any = undefined; | ||||
|   maResolution: number =  30; | ||||
|   network = ''; | ||||
| 
 | ||||
|   constructor( | ||||
|     @Inject(LOCALE_ID) public locale: string, | ||||
| @ -57,10 +58,13 @@ export class HashrateChartComponent implements OnInit { | ||||
|     private storageService: StorageService, | ||||
|     private miningService: MiningService, | ||||
|     private route: ActivatedRoute, | ||||
|     private stateService: StateService | ||||
|   ) { | ||||
|   } | ||||
| 
 | ||||
|   ngOnInit(): void { | ||||
|     this.stateService.networkChanged$.subscribe((network) => this.network = network); | ||||
| 
 | ||||
|     let firstRun = true; | ||||
| 
 | ||||
|     if (this.widget) { | ||||
| @ -124,17 +128,14 @@ export class HashrateChartComponent implements OnInit { | ||||
|                   ++diffIndex; | ||||
|                 } | ||||
| 
 | ||||
|                 this.maResolution = 30; | ||||
|                 if (["3m", "6m"].includes(this.timespan)) { | ||||
|                   this.maResolution = 7; | ||||
|                 } | ||||
|                 let maResolution = 15; | ||||
|                 const hashrateMa = []; | ||||
|                 for (let i = this.maResolution - 1; i < data.hashrates.length; ++i) { | ||||
|                 for (let i = maResolution - 1; i < data.hashrates.length; ++i) { | ||||
|                   let avg = 0; | ||||
|                   for (let y = this.maResolution - 1; y >= 0; --y) { | ||||
|                   for (let y = maResolution - 1; y >= 0; --y) { | ||||
|                     avg += data.hashrates[i - y].avgHashrate; | ||||
|                   } | ||||
|                   avg /= this.maResolution; | ||||
|                   avg /= maResolution; | ||||
|                   hashrateMa.push([data.hashrates[i].timestamp * 1000, avg]); | ||||
|                 } | ||||
| 
 | ||||
| @ -276,17 +277,17 @@ export class HashrateChartComponent implements OnInit { | ||||
|             }, | ||||
|           }, | ||||
|           { | ||||
|             name: $localize`::Difficulty`, | ||||
|             name: $localize`:@@25148835d92465353fc5fe8897c27d5369978e5a:Difficulty`, | ||||
|             inactiveColor: 'rgb(110, 112, 121)', | ||||
|             textStyle: {   | ||||
|             textStyle: { | ||||
|               color: 'white', | ||||
|             }, | ||||
|             icon: 'roundRect', | ||||
|           }, | ||||
|           { | ||||
|             name: $localize`Hashrate` + ` (MA${this.maResolution})`, | ||||
|             name: $localize`Hashrate (MA)`, | ||||
|             inactiveColor: 'rgb(110, 112, 121)', | ||||
|             textStyle: {   | ||||
|             textStyle: { | ||||
|               color: 'white', | ||||
|             }, | ||||
|             icon: 'roundRect', | ||||
| @ -295,11 +296,18 @@ export class HashrateChartComponent implements OnInit { | ||||
|             }, | ||||
|           }, | ||||
|         ], | ||||
|         selected: JSON.parse(this.storageService.getValue('hashrate_difficulty_legend')) ?? { | ||||
|           '$localize`:@@79a9dc5b1caca3cbeb1733a19515edacc5fc7920:Hashrate`': true, | ||||
|           '$localize`::Difficulty`': this.network === '', | ||||
|           '$localize`Hashrate (MA)`': true, | ||||
|         }, | ||||
|       }, | ||||
|       yAxis: data.hashrates.length === 0 ? undefined : [ | ||||
|         { | ||||
|           min: (value) => { | ||||
|             return value.min * 0.9; | ||||
|             const selectedPowerOfTen: any = selectPowerOfTen(value.min); | ||||
|             const newMin = Math.floor(value.min / selectedPowerOfTen.divider / 10); | ||||
|             return newMin * selectedPowerOfTen.divider * 10; | ||||
|           }, | ||||
|           type: 'value', | ||||
|           axisLabel: { | ||||
| @ -363,7 +371,7 @@ export class HashrateChartComponent implements OnInit { | ||||
|         }, | ||||
|         { | ||||
|           zlevel: 2, | ||||
|           name: $localize`Hashrate` + ` (MA${this.maResolution})`, | ||||
|           name: $localize`Hashrate (MA)`, | ||||
|           showSymbol: false, | ||||
|           symbol: 'none', | ||||
|           data: data.hashrateMa, | ||||
| @ -404,6 +412,10 @@ export class HashrateChartComponent implements OnInit { | ||||
| 
 | ||||
|   onChartInit(ec) { | ||||
|     this.chartInstance = ec; | ||||
| 
 | ||||
|     this.chartInstance.on('legendselectchanged', (e) => { | ||||
|       this.storageService.setValue('hashrate_difficulty_legend', JSON.stringify(e.selected)); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   isMobile() { | ||||
|  | ||||
| @ -40,7 +40,7 @@ | ||||
|       <div class="card"> | ||||
|         <div class="card-body pl-lg-3 pr-lg-3 pl-2 pr-2"> | ||||
|           <app-hashrate-chart [widget]="true"></app-hashrate-chart> | ||||
|           <div class="mt-1"><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" i18n="dashboard.view-more">View more »</a></div> | ||||
|           <div class="mt-1"><a [routerLink]="['/graphs/mining/hashrate-difficulty' | relativeUrl]" fragment="1y" i18n="dashboard.view-more">View more »</a></div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| <div class="container-xl"> | ||||
|   <h1 i18n="shared.broadcast-transaction|Broadcast Transaction">Broadcast Transaction</h1> | ||||
|   <h1 class="text-left" i18n="shared.broadcast-transaction|Broadcast Transaction">Broadcast Transaction</h1> | ||||
| 
 | ||||
|   <form [formGroup]="pushTxForm" (submit)="pushTxForm.valid && postTx()" novalidate> | ||||
|     <div class="mb-3"> | ||||
|  | ||||
| @ -66,9 +66,9 @@ | ||||
|                         </ng-template> | ||||
|                       </ng-template> | ||||
|                       <ng-template #defaultAddress> | ||||
|                         <a *ngIf="vin.prevout.scriptpubkey_address; else vinScriptPubkeyType" [routerLink]="['/address/' | relativeUrl, vin.prevout.scriptpubkey_address]" title="{{ vin.prevout.scriptpubkey_address }}"> | ||||
|                         <a class="shortable-address" *ngIf="vin.prevout.scriptpubkey_address; else vinScriptPubkeyType" [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-flex justify-content-start"> | ||||
|                           <span class="d-none d-lg-inline-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> | ||||
| @ -164,9 +164,9 @@ | ||||
|                 'highlight': vout.scriptpubkey_address === this.address && this.address !== '' | ||||
|               }"> | ||||
|                 <td> | ||||
|                   <a *ngIf="vout.scriptpubkey_address; else scriptpubkey_type" [routerLink]="['/address/' | relativeUrl, vout.scriptpubkey_address]" title="{{ vout.scriptpubkey_address }}"> | ||||
|                   <a class="shortable-address" *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-flex justify-content-start"> | ||||
|                     <span class="d-none d-lg-inline-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> | ||||
|  | ||||
| @ -852,6 +852,40 @@ th { | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .fee-progress-bar { | ||||
|     @extend .fee-progress-bar; | ||||
|     &.priority { | ||||
|       @media (767px < width < 992px), (width < 576px) { | ||||
|         width: 100%; | ||||
|       } | ||||
|       width: 75%; | ||||
|       border-radius: 10px 0px 0px 10px !important; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .fees-wrapper-tooltip-chart { | ||||
|     @extend .fees-wrapper-tooltip-chart; | ||||
|     .title { | ||||
|       direction: rtl; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .btn-link { | ||||
|     padding: 0.1rem 0.5rem 0.25rem 0 !important; | ||||
|   } | ||||
| 
 | ||||
|   .shortable-address { | ||||
|     direction: ltr; | ||||
|   } | ||||
| 
 | ||||
|   .lastest-blocks-table { | ||||
|     @extend .lastest-blocks-table; | ||||
|     .table-cell-mined { | ||||
|       @extend .table-cell-mined; | ||||
|       text-align: right !important; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   .mempool-graph { | ||||
|     @extend .mempool-graph; | ||||
|     direction: ltr; | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| #!/usr/local/bin/zsh | ||||
| #!/usr/bin/env zsh | ||||
| cd "${HOME}/electrs" | ||||
| #source "${HOME}/.cargo/env" | ||||
| #export PATH="${HOME}/.cargo/bin:${PATH}" | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| #!/usr/local/bin/zsh | ||||
| #!/usr/bin/env zsh | ||||
| cd "${HOME}/electrs" | ||||
| #source "${HOME}/.cargo/env" | ||||
| #export PATH="${HOME}/.cargo/bin:${PATH}" | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| #!/usr/local/bin/zsh | ||||
| #!/usr/bin/env zsh | ||||
| cd "${HOME}/electrs" | ||||
| #source "${HOME}/.cargo/env" | ||||
| #export PATH="${HOME}/.cargo/bin:${PATH}" | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| #!/usr/local/bin/zsh | ||||
| #!/usr/bin/env zsh | ||||
| cd "${HOME}/electrs" | ||||
| #source $HOME/.cargo/env | ||||
| #export PATH=$HOME/.cargo/bin:$PATH | ||||
|  | ||||
| @ -6,11 +6,13 @@ case `uname -s` in | ||||
| 
 | ||||
|     FreeBSD) | ||||
|         OS=FreeBSD | ||||
|         NPROC=$(sysctl hw.ncpu | awk '{print $2}') | ||||
|     ;; | ||||
| 
 | ||||
|     Linux) | ||||
|         if [ "$(grep -Ei 'debian|buntu|mint' /etc/*release)" ]; then | ||||
|             OS=Debian | ||||
|             NPROC=$(nproc --all) | ||||
|         else | ||||
|             echo "Your distribution of Linux is not yet supported by this installation script" | ||||
|             exit 1 | ||||
| @ -39,6 +41,7 @@ ELEMENTS_INSTALL=ON | ||||
| 
 | ||||
| # configure 4 network instances | ||||
| BITCOIN_MAINNET_ENABLE=ON | ||||
| BITCOIN_MAINNET_MINFEE_ENABLE=ON | ||||
| BITCOIN_TESTNET_ENABLE=ON | ||||
| BITCOIN_SIGNET_ENABLE=ON | ||||
| BISQ_MAINNET_ENABLE=ON | ||||
| @ -682,6 +685,7 @@ $CUT >$input <<-EOF | ||||
| Tor:Enable Tor v3 HS Onion:ON | ||||
| Certbot:Enable HTTPS using Certbot:ON | ||||
| Mainnet:Enable Bitcoin Mainnet:ON | ||||
| Mainnet-Minfee:Enable Bitcoin Mainnet Minfee:ON | ||||
| Testnet:Enable Bitcoin Testnet:ON | ||||
| Liquid:Enable Elements Liquid:ON | ||||
| Bisq:Enable Bisq:ON | ||||
| @ -725,6 +729,12 @@ else | ||||
|     BITCOIN_MAINNET_ENABLE=OFF | ||||
| fi | ||||
| 
 | ||||
| if grep Mainnet-Minfee $tempfile >/dev/null 2>&1;then | ||||
|     BITCOIN_MAINNET_MINFEE_ENABLE=ON | ||||
| else | ||||
|     BITCOIN_MAINNET_MINFEE_ENABLE=OFF | ||||
| fi | ||||
| 
 | ||||
| if grep Testnet $tempfile >/dev/null 2>&1;then | ||||
|     BITCOIN_TESTNET_ENABLE=ON | ||||
| else | ||||
| @ -964,7 +974,7 @@ if [ "${BITCOIN_INSTALL}" = ON ];then | ||||
|     echo "[*] Building Bitcoin from source repo" | ||||
|     osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_REPO_NAME} && ./autogen.sh --quiet" | ||||
|     osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_REPO_NAME} && MAKE=gmake CC=cc CXX=c++ CPPFLAGS=-I/usr/local/include ./configure --with-gui=no --disable-wallet --disable-tests" | ||||
|     osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_REPO_NAME} && gmake -j48" | ||||
|     osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_REPO_NAME} && gmake -j${NPROC}" | ||||
| 
 | ||||
|     echo "[*] Installing Bitcoin binaries into OS" | ||||
|     osSudo "${ROOT_USER}" sh -c "cd ${BITCOIN_HOME}/${BITCOIN_REPO_NAME} && gmake install" | ||||
| @ -1009,7 +1019,7 @@ if [ "${ELEMENTS_INSTALL}" = ON ];then | ||||
|     echo "[*] Building Elements from source repo" | ||||
|     osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_REPO_NAME} && ./autogen.sh --quiet" | ||||
|     osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_REPO_NAME} && MAKE=gmake CC=cc CXX=c++ CPPFLAGS=-I/usr/local/include ./configure --with-gui=no --disable-wallet --disable-tests" | ||||
|     osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_REPO_NAME} && gmake -j48" | ||||
|     osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_REPO_NAME} && gmake -j${NPROC}" | ||||
| 
 | ||||
|     echo "[*] Installing Elements binaries into OS" | ||||
|     osSudo "${ROOT_USER}" sh -c "cd ${ELEMENTS_HOME}/${ELEMENTS_REPO_NAME} && gmake install" | ||||
| @ -1048,7 +1058,7 @@ case $OS in | ||||
|     ;; | ||||
|     Debian) | ||||
|        echo "[*] Installing Rust from rustup.rs" | ||||
|        osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_ELECTRS_HOME} && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" | ||||
|        osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_ELECTRS_HOME} && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y" | ||||
|     ;; | ||||
| esac | ||||
| 
 | ||||
| @ -1095,15 +1105,6 @@ echo "[*] Cloning Liquid Asset Registry testnet repo from ${LIQUIDTESTNET_ASSET_ | ||||
| osSudo "${ELEMENTS_USER}" git config --global advice.detachedHead false | ||||
| osSudo "${ELEMENTS_USER}" git clone "${LIQUIDTESTNET_ASSET_REGISTRY_DB_URL}" "${ELEMENTS_HOME}/${LIQUIDTESTNET_ASSET_REGISTRY_DB_NAME}" | ||||
| 
 | ||||
| case $OS in | ||||
|     FreeBSD) | ||||
|     ;; | ||||
|     Debian) | ||||
|        echo "[*] Installing Rust from rustup.rs" | ||||
|        osSudo "${BITCOIN_USER}" sh -c "cd ${BITCOIN_ELECTRS_HOME} && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh" | ||||
|     ;; | ||||
| esac | ||||
| 
 | ||||
| echo "[*] Building Liquid Electrs release binary" | ||||
| osSudo "${ELEMENTS_USER}" sh -c "cd ${ELEMENTS_ELECTRS_HOME} && cargo run --release --features liquid --bin electrs -- --network liquid --version" || true | ||||
| 
 | ||||
| @ -1214,6 +1215,24 @@ if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then | ||||
|     esac | ||||
| fi | ||||
| 
 | ||||
| ####################################### | ||||
| # Bitcoin instance for Mainnet Minfee # | ||||
| ####################################### | ||||
| 
 | ||||
| if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then | ||||
|     echo "[*] Installing Bitcoin Minfee service" | ||||
|     case $OS in | ||||
| 
 | ||||
|         FreeBSD) | ||||
|             echo "[*] FIXME: Bitcoin Minfee service must be installed manually on FreeBSD" | ||||
|         ;; | ||||
| 
 | ||||
|         Debian) | ||||
|             osSudo "${ROOT_USER}" install -c -o "${ROOT_USER}" -g "${ROOT_GROUP}" -m 644 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/linux/bitcoin-minfee.service" "${DEBIAN_SERVICE_HOME}" | ||||
|         ;; | ||||
|     esac | ||||
| fi | ||||
| 
 | ||||
| ################################ | ||||
| # Bitcoin instance for Testnet # | ||||
| ################################ | ||||
| @ -1277,9 +1296,16 @@ if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then | ||||
|     osSudo "${ROOT_USER}" install -c -o "${BITCOIN_USER}" -g "${BITCOIN_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-mainnet" "${BITCOIN_ELECTRS_HOME}" | ||||
| 
 | ||||
|     echo "[*] Installing Bitcoin crontab" | ||||
|     # FIXME: must only crontab enabled daemons | ||||
|     osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/bitcoin.crontab" | ||||
|     osSudo "${ROOT_USER}" crontab -u "${MINFEE_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/minfee.crontab" | ||||
|     case $OS in | ||||
|         FreeBSD) | ||||
|             echo [*] FIXME: must only crontab enabled daemons | ||||
|             osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/bitcoin.crontab" | ||||
|             osSudo "${ROOT_USER}" crontab -u "${MINFEE_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/minfee.crontab" | ||||
|         ;; | ||||
|         Debian) | ||||
|             (crontab -l ; echo "@reboot sleep 30 ; screen -dmS mainnet /bitcoin/electrs/electrs-start-mainnet") | osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" - | ||||
|         ;; | ||||
|     esac | ||||
| 
 | ||||
|     echo "[*] Configuring Bitcoin Mainnet RPC credentials in electrs start script" | ||||
|     osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_USER__/${BITCOIN_RPC_USER}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-mainnet" | ||||
| @ -1295,6 +1321,13 @@ if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then | ||||
|     echo "[*] Installing Bitcoin Testnet electrs start script" | ||||
|     osSudo "${ROOT_USER}" install -c -o "${BITCOIN_USER}" -g "${BITCOIN_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-testnet" "${BITCOIN_ELECTRS_HOME}" | ||||
| 
 | ||||
|     case $OS in | ||||
|         Debian) | ||||
|             echo "[*] Installing Bitcoin-testnet crontab" | ||||
|             (crontab -l ; echo "@reboot sleep 70 ; screen -dmS testnet /bitcoin/electrs/electrs-start-testnet") | osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" - | ||||
|         ;; | ||||
|     esac | ||||
| 
 | ||||
|     echo "[*] Configuring Bitcoin Testnet RPC credentials in electrs start script" | ||||
|     osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_USER__/${BITCOIN_RPC_USER}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-testnet" | ||||
|     osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_PASS__/${BITCOIN_RPC_PASS}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-testnet" | ||||
| @ -1309,6 +1342,13 @@ if [ "${BITCOIN_SIGNET_ENABLE}" = ON ];then | ||||
|     echo "[*] Installing Bitcoin Signet electrs start script" | ||||
|     osSudo "${ROOT_USER}" install -c -o "${BITCOIN_USER}" -g "${BITCOIN_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-signet" "${BITCOIN_ELECTRS_HOME}" | ||||
| 
 | ||||
|     case $OS in | ||||
|         Debian) | ||||
|             echo "[*] Installing Bitcoin-signet crontab" | ||||
|             (crontab -l ; echo "@reboot sleep 90 ; screen -dmS signet /bitcoin/electrs/electrs-start-signet") | osSudo "${ROOT_USER}" crontab -u "${BITCOIN_USER}" - | ||||
|         ;; | ||||
|     esac | ||||
| 
 | ||||
|     echo "[*] Configuring Bitcoin Signet RPC credentials in electrs start script" | ||||
|     osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_USER__/${BITCOIN_RPC_USER}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-signet" | ||||
|     osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_PASS__/${BITCOIN_RPC_PASS}/" "${BITCOIN_ELECTRS_HOME}/electrs-start-signet" | ||||
| @ -1324,8 +1364,15 @@ if [ "${ELEMENTS_LIQUID_ENABLE}" = ON ];then | ||||
|     osSudo "${ROOT_USER}" install -c -o "${ELEMENTS_USER}" -g "${ELEMENTS_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-liquid" "${ELEMENTS_ELECTRS_HOME}" | ||||
| 
 | ||||
|     echo "[*] Installing Elements crontab" | ||||
|     # FIXME: must only crontab enabled daemons | ||||
|     osSudo "${ROOT_USER}" crontab -u "${ELEMENTS_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/elements.crontab" | ||||
|     case $OS in | ||||
|         FreeBSD) | ||||
|             echo [*] FIXME: must only crontab enabled daemons | ||||
|             osSudo "${ROOT_USER}" crontab -u "${ELEMENTS_USER}" "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/elements.crontab" | ||||
|         ;; | ||||
|         Debian) | ||||
|             (crontab -l ; echo "6 * * * * cd $HOME/asset_registry_db && git pull origin master >/dev/null 2>&1") | osSudo "${ROOT_USER}" crontab -u "${ELEMENTS_USER}" - | ||||
|         ;; | ||||
|     esac | ||||
| 
 | ||||
|     echo "[*] Configuring Elements Liquid RPC credentials in electrs start script" | ||||
|     osSudo "${ROOT_USER}" sed -i.orig "s/__ELEMENTS_RPC_USER__/${ELEMENTS_RPC_USER}/" "${ELEMENTS_ELECTRS_HOME}/electrs-start-liquid" | ||||
| @ -1341,6 +1388,13 @@ if [ "${ELEMENTS_LIQUIDTESTNET_ENABLE}" = ON ];then | ||||
|     echo "[*] Installing Elements Liquid Testnet electrs start script" | ||||
|     osSudo "${ROOT_USER}" install -c -o "${ELEMENTS_USER}" -g "${ELEMENTS_GROUP}" -m 755 "${MEMPOOL_HOME}/${MEMPOOL_REPO_NAME}/production/electrs-start-liquidtestnet" "${ELEMENTS_ELECTRS_HOME}" | ||||
| 
 | ||||
|     case $OS in | ||||
|         Debian) | ||||
|             echo "[*] Installing Elements-testnet crontab" | ||||
|             (crontab -l ; echo "6 * * * * cd $HOME/asset_registry_testnet_db && git pull origin master >/dev/null 2>&1") | osSudo "${ROOT_USER}" crontab -u "${ELEMENTS_USER}" - | ||||
|         ;; | ||||
|     esac | ||||
| 
 | ||||
|     echo "[*] Installing Elements Liquid Testnet RPC credentials" | ||||
|     osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_USER__/${BITCOIN_RPC_USER}/" "${ELEMENTS_HOME}/elements.conf" | ||||
|     osSudo "${ROOT_USER}" sed -i.orig "s/__BITCOIN_RPC_PASS__/${BITCOIN_RPC_PASS}/" "${ELEMENTS_HOME}/elements.conf" | ||||
| @ -1480,23 +1534,21 @@ case $OS in | ||||
|         fi | ||||
|         if [ "${BITCOIN_MAINNET_ENABLE}" = ON ];then | ||||
|             osSudo "${ROOT_USER}" systemctl enable bitcoin.service | ||||
|             osSudo "${ROOT_USER}" systemctl enable mempool.service | ||||
|         fi | ||||
|         if [ "${BITCOIN_MAINNET_MINFEE_ENABLE}" = ON ];then | ||||
|             osSudo "${ROOT_USER}" systemctl enable bitcoin-minfee.service | ||||
|         fi | ||||
|         if [ "${BITCOIN_TESTNET_ENABLE}" = ON ];then | ||||
|             osSudo "${ROOT_USER}" systemctl enable bitcoin-testnet.service | ||||
|             osSudo "${ROOT_USER}" systemctl enable mempool-testnet.service | ||||
|         fi | ||||
|         if [ "${BITCOIN_SIGNET_ENABLE}" = ON ];then | ||||
|             osSudo "${ROOT_USER}" systemctl enable bitcoin-signet.service | ||||
|             osSudo "${ROOT_USER}" systemctl enable mempool-signet.service | ||||
|         fi | ||||
|         if [ "${BISQ_MAINNET_ENABLE}" = ON ];then | ||||
|             osSudo "${ROOT_USER}" systemctl enable bisq.service | ||||
|             osSudo "${ROOT_USER}" systemctl enable mempool-bisq.service | ||||
|         fi | ||||
|         if [ "${ELEMENTS_LIQUID_ENABLE}" = ON ];then | ||||
|             osSudo "${ROOT_USER}" systemctl enable liquid.service | ||||
|             osSudo "${ROOT_USER}" systemctl enable mempool-liquid.service | ||||
|         fi | ||||
|     ;; | ||||
| esac | ||||
|  | ||||
							
								
								
									
										22
									
								
								production/linux/bitcoin-minfee.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								production/linux/bitcoin-minfee.service
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| [Unit] | ||||
| Description=Bitcoind-minfee | ||||
| After=network.target | ||||
| 
 | ||||
| [Service] | ||||
| ExecStart=/usr/local/bin/bitcoind -daemon -printtoconsole -pid=/minfee/bitcoind-minfee.pid | ||||
| ExecStop=/usr/local/bin/bitcoin-cli stop | ||||
| 
 | ||||
| Type=forking | ||||
| PIDFile=/minfee/bitcoind.pid | ||||
| Restart=on-failure | ||||
| 
 | ||||
| User=minfee | ||||
| Group=minfee | ||||
| 
 | ||||
| PrivateTmp=true | ||||
| ProtectSystem=full | ||||
| NoNewPrivileges=true | ||||
| PrivateDevices=true | ||||
| 
 | ||||
| [Install] | ||||
| WantedBy=multi-user.target | ||||
| @ -1,4 +1,4 @@ | ||||
| #!/usr/local/bin/zsh | ||||
| #!/usr/bin/env zsh | ||||
| PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:$HOME/bin | ||||
| HOSTNAME=$(hostname) | ||||
| LOCATION=$(hostname|cut -d . -f2) | ||||
| @ -16,10 +16,13 @@ if [ -f "${LOCKFILE}" ];then | ||||
|     exit 1 | ||||
| fi | ||||
| 
 | ||||
| trap "rv=\$?; rm -rf "${LOCKFILE}"; exit \$rv" INT TERM EXIT | ||||
| # on exit, remove lockfile but preserve exit code | ||||
| trap "rv=\$?; rm -f "${LOCKFILE}"; exit \$rv" INT TERM EXIT | ||||
| 
 | ||||
| # create lockfile | ||||
| touch "${LOCKFILE}" | ||||
| 
 | ||||
| # notify logged in users | ||||
| echo "Upgrading mempool to ${REF}" | wall | ||||
| 
 | ||||
| update_repo() | ||||
| @ -84,25 +87,48 @@ ship_frontend() | ||||
|     rsync -av "./dist/mempool/browser/" "${HOME}/public_html/${site}/" || exit 1 | ||||
| } | ||||
| 
 | ||||
| # load nvm if necessary | ||||
| export NVM_DIR="${HOME}/.nvm" | ||||
| source "${NVM_DIR}/nvm.sh" | ||||
| 
 | ||||
| for target in mainnet testnet signet liquid liquidtestnet bisq;do | ||||
|     update_repo "${target}" | ||||
| # what to look for | ||||
| frontends=(mainnet liquid bisq) | ||||
| backends=(mainnet testnet signet liquid liquidtestnet bisq) | ||||
| frontend_repos=() | ||||
| backend_repos=() | ||||
| 
 | ||||
| # find which frontend repos we have | ||||
| for repo in $frontends;do | ||||
|     [ -d "${repo}" ] && frontend_repos+="${repo}" | ||||
| done | ||||
| 
 | ||||
| for target in mainnet testnet signet liquid liquidtestnet bisq;do | ||||
|     build_backend "${target}" | ||||
| # find which backend repos we have | ||||
| for repo in $backends;do | ||||
|     [ -d "${repo}" ] && backend_repos+="${repo}" | ||||
|     [ -d "${repo}-lightning" ] && backend_repos+="${repo}-lightning" | ||||
| done | ||||
| 
 | ||||
| for target in mainnet liquid bisq;do | ||||
|     build_frontend "${target}" | ||||
| # update all repos | ||||
| for repo in $backend_repos;do | ||||
|     update_repo "${repo}" | ||||
| done | ||||
| 
 | ||||
| # build backends | ||||
| for repo in $backend_repos;do | ||||
|     build_backend "${repo}" | ||||
| done | ||||
| 
 | ||||
| # build frontends | ||||
| for repo in $frontend_repos;do | ||||
|     build_frontend "${repo}" | ||||
| done | ||||
| 
 | ||||
| # ship frontend dist folders to public_html | ||||
| for target in mainnet liquid bisq;do | ||||
|     ship_frontend "${target}" | ||||
| done | ||||
| 
 | ||||
| # notify everyone | ||||
| echo "${HOSTNAME} updated to \`${REF}\` @ \`${HASH}\`" | /usr/local/bin/keybase chat send --nonblock --channel general mempool.dev | ||||
| echo "${HOSTNAME} updated to \`${REF}\` @ \`${HASH}\`" | /usr/local/bin/keybase chat send --nonblock --channel general "mempool.ops.${LOCATION}" | ||||
| 
 | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| #!/usr/local/bin/zsh | ||||
| #!/usr/bin/env zsh | ||||
| export NVM_DIR="$HOME/.nvm" | ||||
| source "$NVM_DIR/nvm.sh" | ||||
| for site in mainnet liquid testnet bisq signet liquidtestnet | ||||
| do | ||||
| 
 | ||||
| for site in mainnet mainnet-lightning testnet testnet-lightning signet signet-lightning bisq liquid liquidtestnet;do | ||||
|     cd "${HOME}/${site}/backend/" && \ | ||||
|     screen -dmS "${site}" sh -c 'while true;do npm run start-production;sleep 1;done' | ||||
| done | ||||
|  | ||||
| @ -4,8 +4,6 @@ tcp_nopush on; | ||||
| tcp_nodelay on; | ||||
| server_tokens off; | ||||
| server_name_in_redirect off; | ||||
| include /usr/local/etc/nginx/mime.types; | ||||
| default_type application/octet-stream; | ||||
| 
 | ||||
| # default logs | ||||
| access_log /var/log/nginx/access.log; | ||||
|  | ||||
							
								
								
									
										20
									
								
								production/nginx/location-api-v1-lightning.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								production/nginx/location-api-v1-lightning.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| # route lightning API endpoints to lightning backend | ||||
| location /api/v1/lightning { | ||||
| 	try_files /dev/null @mempool-api-v1-lightning; | ||||
| } | ||||
| location @mempool-api-v1-lightning { | ||||
| 	proxy_pass $mempoolMainnetLightning; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 10s; | ||||
| } | ||||
| @ -1,26 +1,51 @@ | ||||
| location /api/v1/statistics { | ||||
| 	try_files /dev/null @mempool-api-v1-warmcache; | ||||
| } | ||||
| location /api/v1/mining { | ||||
| 	try_files /dev/null @mempool-api-v1-warmcache; | ||||
| } | ||||
| location /api/v1/block/ { | ||||
| 	try_files /dev/null @mempool-api-v1-forevercache; | ||||
| } | ||||
| location /api/v1 { | ||||
| 	try_files /dev/null @mempool-api-v1-coldcache; | ||||
| } | ||||
| location /api/block/ { | ||||
| 	rewrite ^/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @electrs-api-forevercache; | ||||
| } | ||||
| location /api/ { | ||||
| 	rewrite ^/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @electrs-api-nocache; | ||||
| ########### | ||||
| # mempool # | ||||
| ########### | ||||
| 
 | ||||
| # websocket has special HTTP headers | ||||
| location /api/v1/ws { | ||||
| 	try_files /dev/null @mempool-api-v1-websocket; | ||||
| } | ||||
| 
 | ||||
| location @mempool-api-v1-forevercache { | ||||
| 	proxy_pass $mempoolBackend; | ||||
| # warm cache mining and mempool API responses | ||||
| location /api/v1/statistics { | ||||
| 	try_files /dev/null @mempool-api-v1-cache-warm; | ||||
| } | ||||
| location /api/v1/mining { | ||||
| 	try_files /dev/null @mempool-api-v1-cache-warm; | ||||
| } | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /api/v1/block/ { | ||||
| 	try_files /dev/null @mempool-api-v1-cache-forever; | ||||
| } | ||||
| 
 | ||||
| # everything else gets "normal" cache | ||||
| location /api/v1 { | ||||
| 	try_files /dev/null @mempool-api-v1-cache-normal; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # esplora # | ||||
| ########### | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /api/block/ { | ||||
| 	rewrite ^/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-api-cache-forever; | ||||
| } | ||||
| # other API responses cannot be cached | ||||
| location /api/ { | ||||
| 	rewrite ^/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-api-cache-disabled; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # routing # | ||||
| ########### | ||||
| 
 | ||||
| location @mempool-api-v1-websocket { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 	proxy_http_version 1.1; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| @ -29,8 +54,16 @@ location @mempool-api-v1-forevercache { | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| } | ||||
| 
 | ||||
| location @mempool-api-v1-cache-forever { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_bypass $http_upgrade; | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| @ -40,18 +73,14 @@ location @mempool-api-v1-forevercache { | ||||
| 	expires 30d; | ||||
| } | ||||
| 
 | ||||
| location @mempool-api-v1-warmcache { | ||||
| 	proxy_pass $mempoolBackend; | ||||
| 	proxy_http_version 1.1; | ||||
| location @mempool-api-v1-cache-warm { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_bypass $http_upgrade; | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| @ -59,18 +88,14 @@ location @mempool-api-v1-warmcache { | ||||
| 	proxy_redirect off; | ||||
| } | ||||
| 
 | ||||
| location @mempool-api-v1-coldcache { | ||||
| 	proxy_pass $mempoolBackend; | ||||
| 	proxy_http_version 1.1; | ||||
| location @mempool-api-v1-cache-normal { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_bypass $http_upgrade; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| @ -78,54 +103,42 @@ location @mempool-api-v1-coldcache { | ||||
| 	expires 10s; | ||||
| } | ||||
| 
 | ||||
| location @mempool-api-v1-nocache { | ||||
| 	proxy_pass $mempoolBackend; | ||||
| 	proxy_http_version 1.1; | ||||
| location @mempool-api-v1-cache-disabled { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_bypass $http_upgrade; | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @electrs-api-nocache { | ||||
| 	proxy_pass $electrsBackend; | ||||
| 	proxy_http_version 1.1; | ||||
| location @esplora-api-cache-disabled { | ||||
| 	proxy_pass $esploraMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_bypass $http_upgrade; | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @electrs-api-forevercache { | ||||
| 	proxy_pass $electrsBackend; | ||||
| 	proxy_http_version 1.1; | ||||
| location @esplora-api-cache-forever { | ||||
| 	proxy_pass $esploraMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_bypass $http_upgrade; | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
|  | ||||
| @ -1,12 +1,150 @@ | ||||
| ########### | ||||
| # mempool # | ||||
| ########### | ||||
| 
 | ||||
| # websocket has special HTTP headers | ||||
| location /liquid/api/v1/ws { | ||||
| 	proxy_pass http://mempool-liquid-mainnet/; | ||||
| 	proxy_http_version 1.1; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "Upgrade"; | ||||
| 	rewrite ^/liquid/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-liquid-api-v1-websocket; | ||||
| } | ||||
| 
 | ||||
| # warm cache mempool API responses | ||||
| location /liquid/api/v1/statistics { | ||||
| 	rewrite ^/liquid/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-liquid-api-v1-cache-warm; | ||||
| } | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /liquid/api/v1/block/ { | ||||
| 	rewrite ^/liquid/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-liquid-api-v1-cache-forever; | ||||
| } | ||||
| 
 | ||||
| # everything else gets "normal" cache | ||||
| location /liquid/api/v1 { | ||||
| 	proxy_pass http://mempool-liquid-mainnet/api/v1; | ||||
| 	rewrite ^/liquid/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-liquid-api-v1-cache-normal; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # esplora # | ||||
| ########### | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /liquid/api/block/ { | ||||
| 	rewrite ^/liquid/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-liquid-api-cache-forever; | ||||
| } | ||||
| # other API responses cannot be cached | ||||
| location /liquid/api/ { | ||||
| 	proxy_pass http://electrs-liquid-mainnet/; | ||||
| 	rewrite ^/liquid/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-liquid-api-cache-disabled; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # routing # | ||||
| ########### | ||||
| 
 | ||||
| location @mempool-liquid-api-v1-websocket { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 	proxy_http_version 1.1; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| } | ||||
| 
 | ||||
| location @mempool-liquid-api-v1-cache-forever { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 30d; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 30d; | ||||
| } | ||||
| 
 | ||||
| location @mempool-liquid-api-v1-cache-warm { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| } | ||||
| 
 | ||||
| location @mempool-liquid-api-v1-cache-normal { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 10s; | ||||
| } | ||||
| 
 | ||||
| location @mempool-liquid-api-v1-cache-disabled { | ||||
| 	proxy_pass $mempoolMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @esplora-liquid-api-cache-disabled { | ||||
| 	proxy_pass $esploraMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @esplora-liquid-api-cache-forever { | ||||
| 	proxy_pass $esploraMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 30d; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 30d; | ||||
| } | ||||
|  | ||||
| @ -1,12 +1,154 @@ | ||||
| ########### | ||||
| # mempool # | ||||
| ########### | ||||
| 
 | ||||
| # websocket has special HTTP headers | ||||
| location /liquidtestnet/api/v1/ws { | ||||
| 	proxy_pass http://mempool-liquid-testnet/; | ||||
| 	proxy_http_version 1.1; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "Upgrade"; | ||||
| 	rewrite ^/liquidtestnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-liquidtestnet-api-v1-websocket; | ||||
| } | ||||
| 
 | ||||
| # warm cache mining and mempool API responses | ||||
| location /liquidtestnet/api/v1/statistics { | ||||
| 	rewrite ^/liquidtestnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-liquidtestnet-api-v1-cache-warm; | ||||
| } | ||||
| location /liquidtestnet/api/v1/mining { | ||||
| 	rewrite ^/liquidtestnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-liquidtestnet-api-v1-cache-warm; | ||||
| } | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /liquidtestnet/api/v1/block/ { | ||||
| 	rewrite ^/liquidtestnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-liquidtestnet-api-v1-cache-forever; | ||||
| } | ||||
| 
 | ||||
| # everything else gets "normal" cache | ||||
| location /liquidtestnet/api/v1 { | ||||
| 	proxy_pass http://mempool-liquid-testnet/api/v1; | ||||
| 	rewrite ^/liquidtestnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-liquidtestnet-api-v1-cache-normal; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # esplora # | ||||
| ########### | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /liquidtestnet/api/block/ { | ||||
| 	rewrite ^/liquidtestnet/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-liquidtestnet-api-cache-forever; | ||||
| } | ||||
| # other API responses cannot be cached | ||||
| location /liquidtestnet/api/ { | ||||
| 	proxy_pass http://electrs-liquid-testnet/; | ||||
| 	rewrite ^/liquidtestnet/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-liquidtestnet-api-cache-disabled; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # routing # | ||||
| ########### | ||||
| 
 | ||||
| location @mempool-liquidtestnet-api-v1-websocket { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 	proxy_http_version 1.1; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| } | ||||
| 
 | ||||
| location @mempool-liquidtestnet-api-v1-cache-forever { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 30d; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 30d; | ||||
| } | ||||
| 
 | ||||
| location @mempool-liquidtestnet-api-v1-cache-warm { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| } | ||||
| 
 | ||||
| location @mempool-liquidtestnet-api-v1-cache-normal { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 10s; | ||||
| } | ||||
| 
 | ||||
| location @mempool-liquidtestnet-api-v1-cache-disabled { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @esplora-liquidtestnet-api-cache-disabled { | ||||
| 	proxy_pass $esploraTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @esplora-liquidtestnet-api-cache-forever { | ||||
| 	proxy_pass $esploraTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 30d; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 30d; | ||||
| } | ||||
|  | ||||
							
								
								
									
										21
									
								
								production/nginx/location-signet-api-v1-lightning.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								production/nginx/location-signet-api-v1-lightning.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| # route lightning API endpoints to lightning backend | ||||
| location /signet/api/v1/lightning { | ||||
| 	rewrite ^/signet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-signet-api-v1-lightning; | ||||
| } | ||||
| location @mempool-signet-api-v1-lightning { | ||||
| 	proxy_pass $mempoolSignetLightning; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 10s; | ||||
| } | ||||
| @ -1,12 +1,154 @@ | ||||
| ########### | ||||
| # mempool # | ||||
| ########### | ||||
| 
 | ||||
| # websocket has special HTTP headers | ||||
| location /signet/api/v1/ws { | ||||
| 	proxy_pass http://mempool-bitcoin-signet/; | ||||
| 	proxy_http_version 1.1; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "Upgrade"; | ||||
| 	rewrite ^/signet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-signet-api-v1-websocket; | ||||
| } | ||||
| 
 | ||||
| # warm cache mining and mempool API responses | ||||
| location /signet/api/v1/statistics { | ||||
| 	rewrite ^/signet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-signet-api-v1-cache-warm; | ||||
| } | ||||
| location /signet/api/v1/mining { | ||||
| 	rewrite ^/signet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-signet-api-v1-cache-warm; | ||||
| } | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /signet/api/v1/block/ { | ||||
| 	rewrite ^/signet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-signet-api-v1-cache-forever; | ||||
| } | ||||
| 
 | ||||
| # everything else gets "normal" cache | ||||
| location /signet/api/v1 { | ||||
| 	proxy_pass http://mempool-bitcoin-signet/api/v1; | ||||
| 	rewrite ^/signet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-signet-api-v1-cache-normal; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # esplora # | ||||
| ########### | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /signet/api/block/ { | ||||
| 	rewrite ^/signet/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-signet-api-cache-forever; | ||||
| } | ||||
| # other API responses cannot be cached | ||||
| location /signet/api/ { | ||||
| 	proxy_pass http://electrs-bitcoin-signet/; | ||||
| 	rewrite ^/signet/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-signet-api-cache-disabled; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # routing # | ||||
| ########### | ||||
| 
 | ||||
| location @mempool-signet-api-v1-websocket { | ||||
| 	proxy_pass $mempoolSignet; | ||||
| 	proxy_http_version 1.1; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| } | ||||
| 
 | ||||
| location @mempool-signet-api-v1-cache-forever { | ||||
| 	proxy_pass $mempoolSignet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 30d; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 30d; | ||||
| } | ||||
| 
 | ||||
| location @mempool-signet-api-v1-cache-warm { | ||||
| 	proxy_pass $mempoolSignet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| } | ||||
| 
 | ||||
| location @mempool-signet-api-v1-cache-normal { | ||||
| 	proxy_pass $mempoolSignet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 10s; | ||||
| } | ||||
| 
 | ||||
| location @mempool-signet-api-v1-cache-disabled { | ||||
| 	proxy_pass $mempoolSignet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @esplora-signet-api-cache-disabled { | ||||
| 	proxy_pass $esploraSignet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @esplora-signet-api-cache-forever { | ||||
| 	proxy_pass $esploraSignet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 30d; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 30d; | ||||
| } | ||||
|  | ||||
							
								
								
									
										21
									
								
								production/nginx/location-testnet-api-v1-lightning.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								production/nginx/location-testnet-api-v1-lightning.conf
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| # route lightning API endpoints to lightning backend | ||||
| location /testnet/api/v1/lightning { | ||||
| 	rewrite ^/testnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-testnet-api-v1-lightning; | ||||
| } | ||||
| location @mempool-testnet-api-v1-lightning { | ||||
| 	proxy_pass $mempoolSignetLightning; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 10s; | ||||
| } | ||||
| @ -1,12 +1,154 @@ | ||||
| ########### | ||||
| # mempool # | ||||
| ########### | ||||
| 
 | ||||
| # websocket has special HTTP headers | ||||
| location /testnet/api/v1/ws { | ||||
| 	proxy_pass http://mempool-bitcoin-testnet/; | ||||
| 	proxy_http_version 1.1; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "Upgrade"; | ||||
| 	rewrite ^/testnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-testnet-api-v1-websocket; | ||||
| } | ||||
| 
 | ||||
| # warm cache mining and mempool API responses | ||||
| location /testnet/api/v1/statistics { | ||||
| 	rewrite ^/testnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-testnet-api-v1-cache-warm; | ||||
| } | ||||
| location /testnet/api/v1/mining { | ||||
| 	rewrite ^/testnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-testnet-api-v1-cache-warm; | ||||
| } | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /testnet/api/v1/block/ { | ||||
| 	rewrite ^/testnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-testnet-api-v1-cache-forever; | ||||
| } | ||||
| 
 | ||||
| # everything else gets "normal" cache | ||||
| location /testnet/api/v1 { | ||||
| 	proxy_pass http://mempool-bitcoin-testnet/api/v1; | ||||
| 	rewrite ^/testnet/(.*) /$1 break; | ||||
| 	try_files /dev/null @mempool-testnet-api-v1-cache-normal; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # esplora # | ||||
| ########### | ||||
| 
 | ||||
| # it's ok to cache blockchain data "forever", so we do 30d | ||||
| location /testnet/api/block/ { | ||||
| 	rewrite ^/testnet/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-testnet-api-cache-forever; | ||||
| } | ||||
| # other API responses cannot be cached | ||||
| location /testnet/api/ { | ||||
| 	proxy_pass http://electrs-bitcoin-testnet/; | ||||
| 	rewrite ^/testnet/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-testnet-api-cache-disabled; | ||||
| } | ||||
| 
 | ||||
| ########### | ||||
| # routing # | ||||
| ########### | ||||
| 
 | ||||
| location @mempool-testnet-api-v1-websocket { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 	proxy_http_version 1.1; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| } | ||||
| 
 | ||||
| location @mempool-testnet-api-v1-cache-forever { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 30d; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 30d; | ||||
| } | ||||
| 
 | ||||
| location @mempool-testnet-api-v1-cache-warm { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| } | ||||
| 
 | ||||
| location @mempool-testnet-api-v1-cache-normal { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 10s; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 10s; | ||||
| } | ||||
| 
 | ||||
| location @mempool-testnet-api-v1-cache-disabled { | ||||
| 	proxy_pass $mempoolTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @esplora-testnet-api-cache-disabled { | ||||
| 	proxy_pass $esploraTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
| 
 | ||||
| location @esplora-testnet-api-cache-forever { | ||||
| 	proxy_pass $esploraTestnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_cache_background_update on; | ||||
| 	proxy_cache_use_stale updating; | ||||
| 	proxy_cache api; | ||||
| 	proxy_cache_valid 200 30d; | ||||
| 	proxy_redirect off; | ||||
| 
 | ||||
| 	expires 30d; | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,3 @@ | ||||
| # FreeBSD configuration | ||||
| user nobody; | ||||
| pid /var/run/nginx.pid; | ||||
| 
 | ||||
| @ -14,17 +13,21 @@ http { | ||||
| 	# DNS servers for on-demand recursive resolver | ||||
| 	resolver 8.8.8.8; | ||||
| 
 | ||||
| 	# include default mime types | ||||
| 	include /usr/local/etc/nginx/mime.types; | ||||
| 	default_type application/octet-stream; | ||||
| 
 | ||||
| 	# HTTP basic configuration | ||||
| 	include mempool/production/nginx/http-basic.conf; | ||||
| 	include mempool/production/nginx/http-proxy-cache.conf; | ||||
| 	include mempool/production/nginx/http-language.conf; | ||||
| 
 | ||||
| 	# mempool backend configuration | ||||
| 	# mempool configuration | ||||
| 	include mempool/production/nginx/upstream-mempool.conf; | ||||
| 
 | ||||
| 	# electrs backend configuration | ||||
| 	include mempool/production/nginx/upstream-electrs.conf; | ||||
| 	include mempool/production/nginx/server-electrs.conf; | ||||
| 	# esplora configuration | ||||
| 	include mempool/production/nginx/upstream-esplora.conf; | ||||
| 	include mempool/production/nginx/server-esplora.conf; | ||||
| 
 | ||||
| 	# MEMPOOL.NINJA | ||||
| 	server { | ||||
| @ -36,11 +39,18 @@ http { | ||||
| 		# for services from mempool.space like contributors on about page | ||||
| 		set $mempoolSpaceServices "https://mempool.space"; | ||||
| 
 | ||||
| 		# for mempool/backend daemon, see upstream-mempool.conf | ||||
| 		set $mempoolBackend "http://mempool-bitcoin-mainnet"; | ||||
| 		# for mempool daemons, see upstream-mempool.conf | ||||
| 		set $mempoolMainnet "http://mempool-bitcoin-mainnet"; | ||||
| 		set $mempoolMainnetLightning "http://mempool-bitcoin-mainnet-lightning"; | ||||
| 		set $mempoolTestnet "http://mempool-bitcoin-testnet"; | ||||
| 		set $mempoolTestnetLightning "http://mempool-bitcoin-testnet-lightning"; | ||||
| 		set $mempoolSignet "http://mempool-bitcoin-signet"; | ||||
| 		set $mempoolSignetLightning "http://mempool-bitcoin-signet-lightning"; | ||||
| 
 | ||||
| 		# for blockstream/electrs daemon, see upstream-electrs.conf | ||||
| 		set $electrsBackend "http://electrs-bitcoin-mainnet"; | ||||
| 		# for blockstream/esplora daemons, see upstream-esplora.conf | ||||
| 		set $esploraMainnet "http://esplora-bitcoin-mainnet"; | ||||
| 		set $esploraTestnet "http://esplora-bitcoin-testnet"; | ||||
| 		set $esploraSignet "http://esplora-bitcoin-signet"; | ||||
| 
 | ||||
| 		# tor v3 | ||||
| 		listen 127.0.0.1:81; | ||||
| @ -70,11 +80,11 @@ http { | ||||
| 		# for services from mempool.space like contributors on about page | ||||
| 		set $mempoolSpaceServices "https://mempool.space"; | ||||
| 
 | ||||
| 		# for mempool/backend daemon, see upstream-mempool.conf | ||||
| 		set $mempoolBackend "http://mempool-bisq-mainnet"; | ||||
| 		# for mempool daemons, see upstream-mempool.conf | ||||
| 		set $mempoolBisq "http://mempool-bitcoin-bisq"; | ||||
| 
 | ||||
| 		# for blockstream/electrs daemon, see upstream-electrs.conf | ||||
| 		set $electrsBackend "http://electrs-bitcoin-mainnet"; | ||||
| 		# for blockstream/esplora daemon, see upstream-esplora.conf | ||||
| 		set $esploraMainnet "http://esplora-bitcoin-mainnet"; | ||||
| 
 | ||||
| 		# tor v3 | ||||
| 		listen 127.0.0.1:82; | ||||
| @ -104,11 +114,13 @@ http { | ||||
| 		# for services from mempool.space like contributors on about page | ||||
| 		set $mempoolSpaceServices "https://mempool.space"; | ||||
| 
 | ||||
| 		# for mempool/backend daemon, see upstream-mempool.conf | ||||
| 		set $mempoolBackend "http://mempool-liquid-mainnet"; | ||||
| 		# for mempool daemons, see upstream-mempool.conf | ||||
| 		set $mempoolMainnet "http://mempool-liquid-mainnet"; | ||||
| 		set $mempoolTestnet "http://mempool-liquid-testnet"; | ||||
| 
 | ||||
| 		# for blockstream/electrs daemon, see upstream-electrs.conf | ||||
| 		set $electrsBackend "http://electrs-liquid-mainnet"; | ||||
| 		# for blockstream/esplora daemon, see upstream-esplora.conf | ||||
| 		set $esploraMainnet "http://esplora-liquid-mainnet"; | ||||
| 		set $esploraTestnet "http://esplora-liquid-testnet"; | ||||
| 
 | ||||
| 		# tor v3 | ||||
| 		listen 127.0.0.1:83; | ||||
|  | ||||
| @ -4,80 +4,98 @@ include mempool/production/nginx/location-api-v1-services.conf; | ||||
| proxy_cache markets; | ||||
| proxy_cache_valid 200 30s; | ||||
| 
 | ||||
| # route electrs APIs to electrs | ||||
| # route esplora APIs to esplora | ||||
| location /api/tx/ { | ||||
|         proxy_pass http://electrs-bitcoin-mainnet/tx/; | ||||
| 	rewrite ^/api/(.*) /$1 break; | ||||
| 	try_files /dev/null @esplora-api-cache-disabled; | ||||
| } | ||||
| 
 | ||||
| # rewrite APIs to match what backend expects | ||||
| location /api/currencies { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api/depth { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api/hloc { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api/offers { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api/ticker { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api/trades { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api/volumes { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api/markets { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/markets/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api/v1 { | ||||
| 	rewrite ^/api/v1/(.*) /api/v1/bisq/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /api/v1/ws { | ||||
| 	rewrite ^/api/(.*) /api/v1/bisq/$1 break; | ||||
| 	try_files /dev/null @mempool-bisq-websocket; | ||||
| } | ||||
| location /bisq/api/v1/ws { | ||||
| 	rewrite ^/bisq/api/v1/(.*) /api/v1/bisq/$1 break; | ||||
| 	try_files /dev/null @mempool-bisq-websocket; | ||||
| } | ||||
| location /bisq/api/v1 { | ||||
| 	rewrite ^/bisq/api/v1/(.*) /api/v1/bisq/$1 break; | ||||
| 	try_files $uri $uri/ @mempool-bisq; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| location /bisq/api { | ||||
|         rewrite ^/bisq/api/(.*) /api/v1/bisq/$1 break; | ||||
|         try_files $uri $uri/ @mempool-bisq; | ||||
| 	rewrite ^/bisq/api/(.*) /api/v1/bisq/$1 break; | ||||
| 	try_files /dev/null @mempool-bisq; | ||||
| } | ||||
| 
 | ||||
| # special handling for websocket | ||||
| location /api/v1/ws { | ||||
| 	proxy_pass http://mempool-bitcoin-bisq/; | ||||
| location @mempool-bisq-websocket { | ||||
| 	proxy_pass $mempoolBisq; | ||||
| 	proxy_http_version 1.1; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "Upgrade"; | ||||
| } | ||||
| 
 | ||||
| location @mempool-bisq { | ||||
| 	proxy_pass http://mempool-bitcoin-bisq; | ||||
| 	proxy_http_version 1.1; | ||||
| 	proxy_pass $mempoolBisq; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header Upgrade $http_upgrade; | ||||
| 	proxy_set_header Connection "upgrade"; | ||||
| 
 | ||||
| 	proxy_cache_bypass $http_upgrade; | ||||
| 	proxy_redirect off; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| } | ||||
| 
 | ||||
| location @esplora-api-cache-disabled { | ||||
| 	proxy_pass $esploraMainnet; | ||||
| 
 | ||||
| 	proxy_set_header Host $http_host; | ||||
| 	proxy_set_header X-Real-IP $remote_addr; | ||||
| 	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||||
| 	proxy_set_header X-Forwarded-Proto $scheme; | ||||
| 
 | ||||
| 	proxy_redirect off; | ||||
| 	proxy_buffering off; | ||||
| 
 | ||||
| 	expires -1; | ||||
| } | ||||
|  | ||||
| @ -2,34 +2,34 @@ server { | ||||
| 	listen 127.0.0.1:4000; | ||||
| 	access_log /dev/null; | ||||
| 	location / { | ||||
| 		proxy_pass http://electrs-bitcoin-mainnet; | ||||
| 		proxy_pass http://esplora-bitcoin-mainnet; | ||||
| 	} | ||||
| } | ||||
| server { | ||||
| 	listen 127.0.0.1:4001; | ||||
| 	access_log /dev/null; | ||||
| 	location / { | ||||
| 		proxy_pass http://electrs-liquid-mainnet; | ||||
| 		proxy_pass http://esplora-liquid-mainnet; | ||||
| 	} | ||||
| } | ||||
| server { | ||||
| 	listen 127.0.0.1:4002; | ||||
| 	access_log /dev/null; | ||||
| 	location / { | ||||
| 		proxy_pass http://electrs-bitcoin-testnet; | ||||
| 		proxy_pass http://esplora-bitcoin-testnet; | ||||
| 	} | ||||
| } | ||||
| server { | ||||
| 	listen 127.0.0.1:4003; | ||||
| 	access_log /dev/null; | ||||
| 	location / { | ||||
| 		proxy_pass http://electrs-bitcoin-signet; | ||||
| 		proxy_pass http://esplora-bitcoin-signet; | ||||
| 	} | ||||
| } | ||||
| server { | ||||
| 	listen 127.0.0.1:4004; | ||||
| 	access_log /dev/null; | ||||
| 	location / { | ||||
| 		proxy_pass http://electrs-liquid-testnet; | ||||
| 		proxy_pass http://esplora-liquid-testnet; | ||||
| 	} | ||||
| } | ||||
| @ -1,6 +1,9 @@ | ||||
| include mempool/production/nginx/server-common.conf; | ||||
| include mempool/production/nginx/location-redirects.conf; | ||||
| include mempool/production/nginx/location-api-v1-services.conf; | ||||
| include mempool/production/nginx/location-api-v1-lightning.conf; | ||||
| include mempool/production/nginx/location-api.conf; | ||||
| include mempool/production/nginx/location-testnet-api.conf; | ||||
| include mempool/production/nginx/location-testnet-api-v1-lightning.conf; | ||||
| include mempool/production/nginx/location-signet-api.conf; | ||||
| include mempool/production/nginx/location-signet-api-v1-lightning.conf; | ||||
|  | ||||
| @ -1,15 +1,15 @@ | ||||
| upstream electrs-bitcoin-mainnet { | ||||
| upstream esplora-bitcoin-mainnet { | ||||
| 	server [::1]:3000 fail_timeout=10s max_fails=10 weight=99999; | ||||
| } | ||||
| upstream electrs-liquid-mainnet { | ||||
| upstream esplora-liquid-mainnet { | ||||
| 	server [::1]:3001 fail_timeout=10s max_fails=10 weight=99999; | ||||
| } | ||||
| upstream electrs-bitcoin-testnet { | ||||
| upstream esplora-bitcoin-testnet { | ||||
| 	server [::1]:3002 fail_timeout=10s max_fails=10 weight=99999; | ||||
| } | ||||
| upstream electrs-bitcoin-signet { | ||||
| upstream esplora-bitcoin-signet { | ||||
| 	server [::1]:3003 fail_timeout=10s max_fails=10 weight=99999; | ||||
| } | ||||
| upstream electrs-liquid-testnet { | ||||
| upstream esplora-liquid-testnet { | ||||
| 	server [::1]:3004 fail_timeout=10s max_fails=10 weight=99999; | ||||
| } | ||||
| @ -16,3 +16,12 @@ upstream mempool-bitcoin-signet { | ||||
| upstream mempool-liquid-testnet { | ||||
| 	server 127.0.0.1:8994 fail_timeout=10s max_fails=10 weight=99999; | ||||
| } | ||||
| upstream mempool-bitcoin-mainnet-lightning { | ||||
| 	server 127.0.0.1:8993 fail_timeout=10s max_fails=10 weight=99999; | ||||
| } | ||||
| upstream mempool-bitcoin-testnet-lightning { | ||||
| 	server 127.0.0.1:8992 fail_timeout=10s max_fails=10 weight=99999; | ||||
| } | ||||
| upstream mempool-bitcoin-signet-lightning { | ||||
| 	server 127.0.0.1:8991 fail_timeout=10s max_fails=10 weight=99999; | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| #!/usr/local/bin/zsh | ||||
| #!/usr/bin/env zsh | ||||
| PROTO=https | ||||
| HOSTNAME=mempool.ninja | ||||
| URL_BASE=${PROTO}://${HOSTNAME} | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user