Merge pull request #5361 from mempool/mononaut/fosscelerator
On-demand acceleration polling
This commit is contained in:
		
						commit
						dc09e75783
					
				@ -396,10 +396,6 @@ class Mempool {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public $updateAccelerations(newAccelerations: Acceleration[]): string[] {
 | 
					  public $updateAccelerations(newAccelerations: Acceleration[]): string[] {
 | 
				
			||||||
    if (!config.MEMPOOL_SERVICES.ACCELERATIONS) {
 | 
					 | 
				
			||||||
      return [];
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      const changed: string[] = [];
 | 
					      const changed: string[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ import bitcoinClient from '../bitcoin/bitcoin-client';
 | 
				
			|||||||
import mining from "./mining";
 | 
					import mining from "./mining";
 | 
				
			||||||
import PricesRepository from '../../repositories/PricesRepository';
 | 
					import PricesRepository from '../../repositories/PricesRepository';
 | 
				
			||||||
import AccelerationRepository from '../../repositories/AccelerationRepository';
 | 
					import AccelerationRepository from '../../repositories/AccelerationRepository';
 | 
				
			||||||
 | 
					import accelerationApi from '../services/acceleration';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MiningRoutes {
 | 
					class MiningRoutes {
 | 
				
			||||||
  public initRoutes(app: Application) {
 | 
					  public initRoutes(app: Application) {
 | 
				
			||||||
@ -41,6 +42,8 @@ class MiningRoutes {
 | 
				
			|||||||
      .get(config.MEMPOOL.API_URL_PREFIX + 'accelerations/block/:height', this.$getAccelerationsByHeight)
 | 
					      .get(config.MEMPOOL.API_URL_PREFIX + 'accelerations/block/:height', this.$getAccelerationsByHeight)
 | 
				
			||||||
      .get(config.MEMPOOL.API_URL_PREFIX + 'accelerations/recent/:interval', this.$getRecentAccelerations)
 | 
					      .get(config.MEMPOOL.API_URL_PREFIX + 'accelerations/recent/:interval', this.$getRecentAccelerations)
 | 
				
			||||||
      .get(config.MEMPOOL.API_URL_PREFIX + 'accelerations/total', this.$getAccelerationTotals)
 | 
					      .get(config.MEMPOOL.API_URL_PREFIX + 'accelerations/total', this.$getAccelerationTotals)
 | 
				
			||||||
 | 
					      .get(config.MEMPOOL.API_URL_PREFIX + 'accelerations', this.$getActiveAccelerations)
 | 
				
			||||||
 | 
					      .post(config.MEMPOOL.API_URL_PREFIX + 'acceleration/request/:txid', this.$requestAcceleration)
 | 
				
			||||||
    ;
 | 
					    ;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -445,6 +448,37 @@ class MiningRoutes {
 | 
				
			|||||||
      res.status(500).send(e instanceof Error ? e.message : e);
 | 
					      res.status(500).send(e instanceof Error ? e.message : e);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async $getActiveAccelerations(req: Request, res: Response): Promise<void> {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      res.header('Pragma', 'public');
 | 
				
			||||||
 | 
					      res.header('Cache-control', 'public');
 | 
				
			||||||
 | 
					      res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString());
 | 
				
			||||||
 | 
					      if (!config.MEMPOOL_SERVICES.ACCELERATIONS || ['testnet', 'signet', 'liquidtestnet', 'liquid'].includes(config.MEMPOOL.NETWORK)) {
 | 
				
			||||||
 | 
					        res.status(400).send('Acceleration data is not available.');
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      res.status(200).send(accelerationApi.accelerations || []);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      res.status(500).send(e instanceof Error ? e.message : e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async $requestAcceleration(req: Request, res: Response): Promise<void> {
 | 
				
			||||||
 | 
					    if (config.MEMPOOL_SERVICES.ACCELERATIONS || config.MEMPOOL.OFFICIAL) {
 | 
				
			||||||
 | 
					      res.status(405).send('not available.');
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res.setHeader('Pragma', 'no-cache');
 | 
				
			||||||
 | 
					    res.setHeader('Cache-control', 'private, no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0');
 | 
				
			||||||
 | 
					    res.setHeader('expires', -1);
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      accelerationApi.accelerationRequested(req.params.txid);
 | 
				
			||||||
 | 
					      res.status(200).send('ok');
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      res.status(500).send(e instanceof Error ? e.message : e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default new MiningRoutes();
 | 
					export default new MiningRoutes();
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,10 @@
 | 
				
			|||||||
import config from '../../config';
 | 
					import config from '../../config';
 | 
				
			||||||
import logger from '../../logger';
 | 
					import logger from '../../logger';
 | 
				
			||||||
import { BlockExtended, PoolTag } from '../../mempool.interfaces';
 | 
					import { BlockExtended } from '../../mempool.interfaces';
 | 
				
			||||||
import axios from 'axios';
 | 
					import axios from 'axios';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type MyAccelerationStatus = 'requested' | 'accelerating' | 'done';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Acceleration {
 | 
					export interface Acceleration {
 | 
				
			||||||
  txid: string,
 | 
					  txid: string,
 | 
				
			||||||
  added: number,
 | 
					  added: number,
 | 
				
			||||||
@ -35,18 +37,88 @@ export interface AccelerationHistory {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AccelerationApi {
 | 
					class AccelerationApi {
 | 
				
			||||||
  public async $fetchAccelerations(): Promise<Acceleration[] | null> {
 | 
					  private apiPath = config.MEMPOOL.OFFICIAL ? (config.MEMPOOL_SERVICES.API + '/accelerator/accelerations') : (config.EXTERNAL_DATA_SERVER.MEMPOOL_API + '/accelerations');
 | 
				
			||||||
 | 
					  private _accelerations: Acceleration[] | null = null;
 | 
				
			||||||
 | 
					  private lastPoll = 0;
 | 
				
			||||||
 | 
					  private forcePoll = false;
 | 
				
			||||||
 | 
					  private myAccelerations: Record<string, { status: MyAccelerationStatus, added: number, acceleration?: Acceleration }> = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public get accelerations(): Acceleration[] | null {
 | 
				
			||||||
 | 
					    return this._accelerations;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public countMyAccelerationsWithStatus(filter: MyAccelerationStatus): number {
 | 
				
			||||||
 | 
					    return Object.values(this.myAccelerations).reduce((count, {status}) => { return count + (status === filter ? 1 : 0); }, 0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public accelerationRequested(txid: string): void {
 | 
				
			||||||
 | 
					    this.myAccelerations[txid] = { status: 'requested', added: Date.now() };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public accelerationConfirmed(): void {
 | 
				
			||||||
 | 
					    this.forcePoll = true;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async $fetchAccelerations(): Promise<Acceleration[] | null> {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const response = await axios.get(this.apiPath, { responseType: 'json', timeout: 10000 });
 | 
				
			||||||
 | 
					      return response?.data || [];
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      logger.warn('Failed to fetch current accelerations from the mempool services backend: ' + (e instanceof Error ? e.message : e));
 | 
				
			||||||
 | 
					      return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public async $updateAccelerations(): Promise<Acceleration[] | null> {
 | 
				
			||||||
    if (config.MEMPOOL_SERVICES.ACCELERATIONS) {
 | 
					    if (config.MEMPOOL_SERVICES.ACCELERATIONS) {
 | 
				
			||||||
      try {
 | 
					      const accelerations = await this.$fetchAccelerations();
 | 
				
			||||||
        const response = await axios.get(`${config.MEMPOOL_SERVICES.API}/accelerator/accelerations`, { responseType: 'json', timeout: 10000 });
 | 
					      if (accelerations) {
 | 
				
			||||||
        return response.data as Acceleration[];
 | 
					        this._accelerations = accelerations;
 | 
				
			||||||
      } catch (e) {
 | 
					        return this._accelerations;
 | 
				
			||||||
        logger.warn('Failed to fetch current accelerations from the mempool services backend: ' + (e instanceof Error ? e.message : e));
 | 
					 | 
				
			||||||
        return null;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return [];
 | 
					      return this.$updateAccelerationsOnDemand();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async $updateAccelerationsOnDemand(): Promise<Acceleration[] | null> {
 | 
				
			||||||
 | 
					    const shouldUpdate = this.forcePoll
 | 
				
			||||||
 | 
					      || this.countMyAccelerationsWithStatus('requested') > 0
 | 
				
			||||||
 | 
					      || (this.countMyAccelerationsWithStatus('accelerating') > 0 && this.lastPoll < (Date.now() - (10 * 60 * 1000)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // update accelerations if necessary
 | 
				
			||||||
 | 
					    if (shouldUpdate) {
 | 
				
			||||||
 | 
					      const accelerations = await this.$fetchAccelerations();
 | 
				
			||||||
 | 
					      this.lastPoll = Date.now();
 | 
				
			||||||
 | 
					      this.forcePoll = false;
 | 
				
			||||||
 | 
					      if (accelerations) {
 | 
				
			||||||
 | 
					        const latestAccelerations: Record<string, Acceleration> = {};
 | 
				
			||||||
 | 
					        // set relevant accelerations to 'accelerating'
 | 
				
			||||||
 | 
					        for (const acc of accelerations) {
 | 
				
			||||||
 | 
					          if (this.myAccelerations[acc.txid]) {
 | 
				
			||||||
 | 
					            latestAccelerations[acc.txid] = acc;
 | 
				
			||||||
 | 
					            this.myAccelerations[acc.txid] = { status: 'accelerating', added: Date.now(), acceleration: acc };
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // txs that are no longer accelerating are either confirmed or canceled, so mark for expiry
 | 
				
			||||||
 | 
					        for (const [txid, { status, acceleration }] of Object.entries(this.myAccelerations)) {
 | 
				
			||||||
 | 
					          if (status === 'accelerating' && !latestAccelerations[txid]) {
 | 
				
			||||||
 | 
					            this.myAccelerations[txid] = { status: 'done', added: Date.now(), acceleration };
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // clear expired accelerations (confirmed / failed / not accepted) after 10 minutes
 | 
				
			||||||
 | 
					    for (const [txid, { status, added }] of Object.entries(this.myAccelerations)) {
 | 
				
			||||||
 | 
					      if (['requested', 'done'].includes(status) && added < (Date.now() - (1000 * 60 * 10))) {
 | 
				
			||||||
 | 
					        delete this.myAccelerations[txid];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this._accelerations = Object.values(this.myAccelerations).map(({ acceleration }) => acceleration).filter(acc => acc) as Acceleration[];
 | 
				
			||||||
 | 
					    return this._accelerations;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public async $fetchAccelerationHistory(page?: number, status?: string): Promise<AccelerationHistory[] | null> {
 | 
					  public async $fetchAccelerationHistory(page?: number, status?: string): Promise<AccelerationHistory[] | null> {
 | 
				
			||||||
 | 
				
			|||||||
@ -538,9 +538,9 @@ class WebsocketHandler {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (config.MEMPOOL.RUST_GBT) {
 | 
					    if (config.MEMPOOL.RUST_GBT) {
 | 
				
			||||||
      await mempoolBlocks.$rustUpdateBlockTemplates(transactionIds, newMempool, added, removed, candidates, config.MEMPOOL_SERVICES.ACCELERATIONS);
 | 
					      await mempoolBlocks.$rustUpdateBlockTemplates(transactionIds, newMempool, added, removed, candidates, true);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      await mempoolBlocks.$updateBlockTemplates(transactionIds, newMempool, added, removed, candidates, accelerationDelta, true, config.MEMPOOL_SERVICES.ACCELERATIONS);
 | 
					      await mempoolBlocks.$updateBlockTemplates(transactionIds, newMempool, added, removed, candidates, accelerationDelta, true, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const mBlocks = mempoolBlocks.getMempoolBlocks();
 | 
					    const mBlocks = mempoolBlocks.getMempoolBlocks();
 | 
				
			||||||
@ -949,18 +949,14 @@ class WebsocketHandler {
 | 
				
			|||||||
    if (config.MEMPOOL.AUDIT && memPool.isInSync()) {
 | 
					    if (config.MEMPOOL.AUDIT && memPool.isInSync()) {
 | 
				
			||||||
      let projectedBlocks;
 | 
					      let projectedBlocks;
 | 
				
			||||||
      const auditMempool = _memPool;
 | 
					      const auditMempool = _memPool;
 | 
				
			||||||
      const isAccelerated = config.MEMPOOL_SERVICES.ACCELERATIONS && accelerationApi.isAcceleratedBlock(block, Object.values(mempool.getAccelerations()));
 | 
					      const isAccelerated = accelerationApi.isAcceleratedBlock(block, Object.values(mempool.getAccelerations()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if ((config.MEMPOOL_SERVICES.ACCELERATIONS)) {
 | 
					      if (config.MEMPOOL.RUST_GBT) {
 | 
				
			||||||
        if (config.MEMPOOL.RUST_GBT) {
 | 
					        const added = memPool.limitGBT ? (candidates?.added || []) : [];
 | 
				
			||||||
          const added = memPool.limitGBT ? (candidates?.added || []) : [];
 | 
					        const removed = memPool.limitGBT ? (candidates?.removed || []) : [];
 | 
				
			||||||
          const removed = memPool.limitGBT ? (candidates?.removed || []) : [];
 | 
					        projectedBlocks = await mempoolBlocks.$rustUpdateBlockTemplates(transactionIds, auditMempool, added, removed, candidates, isAccelerated, block.extras.pool.id);
 | 
				
			||||||
          projectedBlocks = await mempoolBlocks.$rustUpdateBlockTemplates(transactionIds, auditMempool, added, removed, candidates, isAccelerated, block.extras.pool.id);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          projectedBlocks = await mempoolBlocks.$makeBlockTemplates(transactionIds, auditMempool, candidates, false, isAccelerated, block.extras.pool.id);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        projectedBlocks = mempoolBlocks.getMempoolBlocksWithTransactions();
 | 
					        projectedBlocks = await mempoolBlocks.$makeBlockTemplates(transactionIds, auditMempool, candidates, false, isAccelerated, block.extras.pool.id);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if (Common.indexingEnabled()) {
 | 
					      if (Common.indexingEnabled()) {
 | 
				
			||||||
@ -1040,7 +1036,7 @@ class WebsocketHandler {
 | 
				
			|||||||
      const removed = memPool.limitGBT ? (candidates?.removed || []) : transactions;
 | 
					      const removed = memPool.limitGBT ? (candidates?.removed || []) : transactions;
 | 
				
			||||||
      await mempoolBlocks.$rustUpdateBlockTemplates(transactionIds, _memPool, added, removed, candidates, true);
 | 
					      await mempoolBlocks.$rustUpdateBlockTemplates(transactionIds, _memPool, added, removed, candidates, true);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      await mempoolBlocks.$makeBlockTemplates(transactionIds, _memPool, candidates, true, config.MEMPOOL_SERVICES.ACCELERATIONS);
 | 
					      await mempoolBlocks.$makeBlockTemplates(transactionIds, _memPool, candidates, true, true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    const mBlocks = mempoolBlocks.getMempoolBlocks();
 | 
					    const mBlocks = mempoolBlocks.getMempoolBlocks();
 | 
				
			||||||
    const mBlockDeltas = mempoolBlocks.getMempoolBlockDeltas();
 | 
					    const mBlockDeltas = mempoolBlocks.getMempoolBlockDeltas();
 | 
				
			||||||
 | 
				
			|||||||
@ -229,7 +229,7 @@ class Server {
 | 
				
			|||||||
      const newMempool = await bitcoinApi.$getRawMempool();
 | 
					      const newMempool = await bitcoinApi.$getRawMempool();
 | 
				
			||||||
      const minFeeMempool = memPool.limitGBT ? await bitcoinSecondClient.getRawMemPool() : null;
 | 
					      const minFeeMempool = memPool.limitGBT ? await bitcoinSecondClient.getRawMemPool() : null;
 | 
				
			||||||
      const minFeeTip = memPool.limitGBT ? await bitcoinSecondClient.getBlockCount() : -1;
 | 
					      const minFeeTip = memPool.limitGBT ? await bitcoinSecondClient.getBlockCount() : -1;
 | 
				
			||||||
      const newAccelerations = await accelerationApi.$fetchAccelerations();
 | 
					      const newAccelerations = await accelerationApi.$updateAccelerations();
 | 
				
			||||||
      const numHandledBlocks = await blocks.$updateBlocks();
 | 
					      const numHandledBlocks = await blocks.$updateBlocks();
 | 
				
			||||||
      const pollRate = config.MEMPOOL.POLL_RATE_MS * (indexer.indexerIsRunning() ? 10 : 1);
 | 
					      const pollRate = config.MEMPOOL.POLL_RATE_MS * (indexer.indexerIsRunning() ? 10 : 1);
 | 
				
			||||||
      if (numHandledBlocks === 0) {
 | 
					      if (numHandledBlocks === 0) {
 | 
				
			||||||
 | 
				
			|||||||
@ -213,6 +213,15 @@ class AccelerationRepository {
 | 
				
			|||||||
        this.$saveAcceleration(accelerationInfo, block, block.extras.pool.id, successfulAccelerations);
 | 
					        this.$saveAcceleration(accelerationInfo, block, block.extras.pool.id, successfulAccelerations);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    let anyConfirmed = false;
 | 
				
			||||||
 | 
					    for (const acc of accelerations) {
 | 
				
			||||||
 | 
					      if (blockTxs[acc.txid]) {
 | 
				
			||||||
 | 
					        anyConfirmed = true;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (anyConfirmed) {
 | 
				
			||||||
 | 
					      accelerationApi.accelerationConfirmed();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    const lastSyncedHeight = await this.$getLastSyncedHeight();
 | 
					    const lastSyncedHeight = await this.$getLastSyncedHeight();
 | 
				
			||||||
    // if we've missed any blocks, let the indexer catch up from the last synced height on the next run
 | 
					    // if we've missed any blocks, let the indexer catch up from the last synced height on the next run
 | 
				
			||||||
    if (block.height === lastSyncedHeight + 1) {
 | 
					    if (block.height === lastSyncedHeight + 1) {
 | 
				
			||||||
 | 
				
			|||||||
@ -40,6 +40,7 @@ __MAINNET_BLOCK_AUDIT_START_HEIGHT__=${MAINNET_BLOCK_AUDIT_START_HEIGHT:=0}
 | 
				
			|||||||
__TESTNET_BLOCK_AUDIT_START_HEIGHT__=${TESTNET_BLOCK_AUDIT_START_HEIGHT:=0}
 | 
					__TESTNET_BLOCK_AUDIT_START_HEIGHT__=${TESTNET_BLOCK_AUDIT_START_HEIGHT:=0}
 | 
				
			||||||
__SIGNET_BLOCK_AUDIT_START_HEIGHT__=${SIGNET_BLOCK_AUDIT_START_HEIGHT:=0}
 | 
					__SIGNET_BLOCK_AUDIT_START_HEIGHT__=${SIGNET_BLOCK_AUDIT_START_HEIGHT:=0}
 | 
				
			||||||
__ACCELERATOR__=${ACCELERATOR:=false}
 | 
					__ACCELERATOR__=${ACCELERATOR:=false}
 | 
				
			||||||
 | 
					__ACCELERATOR_BUTTON__=${ACCELERATOR_BUTTON:=true}
 | 
				
			||||||
__SERVICES_API__=${SERVICES_API:=false}
 | 
					__SERVICES_API__=${SERVICES_API:=false}
 | 
				
			||||||
__PUBLIC_ACCELERATIONS__=${PUBLIC_ACCELERATIONS:=false}
 | 
					__PUBLIC_ACCELERATIONS__=${PUBLIC_ACCELERATIONS:=false}
 | 
				
			||||||
__HISTORICAL_PRICE__=${HISTORICAL_PRICE:=true}
 | 
					__HISTORICAL_PRICE__=${HISTORICAL_PRICE:=true}
 | 
				
			||||||
@ -70,6 +71,7 @@ export __MAINNET_BLOCK_AUDIT_START_HEIGHT__
 | 
				
			|||||||
export __TESTNET_BLOCK_AUDIT_START_HEIGHT__
 | 
					export __TESTNET_BLOCK_AUDIT_START_HEIGHT__
 | 
				
			||||||
export __SIGNET_BLOCK_AUDIT_START_HEIGHT__
 | 
					export __SIGNET_BLOCK_AUDIT_START_HEIGHT__
 | 
				
			||||||
export __ACCELERATOR__
 | 
					export __ACCELERATOR__
 | 
				
			||||||
 | 
					export __ACCELERATOR_BUTTON__
 | 
				
			||||||
export __SERVICES_API__
 | 
					export __SERVICES_API__
 | 
				
			||||||
export __PUBLIC_ACCELERATIONS__
 | 
					export __PUBLIC_ACCELERATIONS__
 | 
				
			||||||
export __HISTORICAL_PRICE__
 | 
					export __HISTORICAL_PRICE__
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ import { Transaction } from '../../interfaces/electrs.interface';
 | 
				
			|||||||
import { MiningStats } from '../../services/mining.service';
 | 
					import { MiningStats } from '../../services/mining.service';
 | 
				
			||||||
import { IAuth, AuthServiceMempool } from '../../services/auth.service';
 | 
					import { IAuth, AuthServiceMempool } from '../../services/auth.service';
 | 
				
			||||||
import { EnterpriseService } from '../../services/enterprise.service';
 | 
					import { EnterpriseService } from '../../services/enterprise.service';
 | 
				
			||||||
 | 
					import { ApiService } from '../../services/api.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type PaymentMethod = 'balance' | 'bitcoin' | 'cashapp';
 | 
					export type PaymentMethod = 'balance' | 'bitcoin' | 'cashapp';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -123,6 +124,7 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  constructor(
 | 
					  constructor(
 | 
				
			||||||
    public stateService: StateService,
 | 
					    public stateService: StateService,
 | 
				
			||||||
 | 
					    private apiService: ApiService,
 | 
				
			||||||
    private servicesApiService: ServicesApiServices,
 | 
					    private servicesApiService: ServicesApiServices,
 | 
				
			||||||
    private etaService: EtaService,
 | 
					    private etaService: EtaService,
 | 
				
			||||||
    private audioService: AudioService,
 | 
					    private audioService: AudioService,
 | 
				
			||||||
@ -370,10 +372,11 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
 | 
				
			|||||||
      this.accelerationUUID
 | 
					      this.accelerationUUID
 | 
				
			||||||
    ).subscribe({
 | 
					    ).subscribe({
 | 
				
			||||||
      next: () => {
 | 
					      next: () => {
 | 
				
			||||||
 | 
					        this.apiService.logAccelerationRequest$(this.tx.txid).subscribe();
 | 
				
			||||||
        this.audioService.playSound('ascend-chime-cartoon');
 | 
					        this.audioService.playSound('ascend-chime-cartoon');
 | 
				
			||||||
        this.showSuccess = true;
 | 
					        this.showSuccess = true;
 | 
				
			||||||
        this.estimateSubscription.unsubscribe();
 | 
					        this.estimateSubscription.unsubscribe();
 | 
				
			||||||
        this.moveToStep('paid')
 | 
					        this.moveToStep('paid');
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      error: (response) => {
 | 
					      error: (response) => {
 | 
				
			||||||
        this.accelerateError = response.error;
 | 
					        this.accelerateError = response.error;
 | 
				
			||||||
@ -481,6 +484,7 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
 | 
				
			|||||||
              that.accelerationUUID
 | 
					              that.accelerationUUID
 | 
				
			||||||
            ).subscribe({
 | 
					            ).subscribe({
 | 
				
			||||||
              next: () => {
 | 
					              next: () => {
 | 
				
			||||||
 | 
					                this.apiService.logAccelerationRequest$(this.tx.txid).subscribe();
 | 
				
			||||||
                that.audioService.playSound('ascend-chime-cartoon');
 | 
					                that.audioService.playSound('ascend-chime-cartoon');
 | 
				
			||||||
                if (that.cashAppPay) {
 | 
					                if (that.cashAppPay) {
 | 
				
			||||||
                  that.cashAppPay.destroy();
 | 
					                  that.cashAppPay.destroy();
 | 
				
			||||||
@ -530,9 +534,10 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bitcoinPaymentCompleted(): void {
 | 
					  bitcoinPaymentCompleted(): void {
 | 
				
			||||||
 | 
					    this.apiService.logAccelerationRequest$(this.tx.txid).subscribe();
 | 
				
			||||||
    this.audioService.playSound('ascend-chime-cartoon');
 | 
					    this.audioService.playSound('ascend-chime-cartoon');
 | 
				
			||||||
    this.estimateSubscription.unsubscribe();
 | 
					    this.estimateSubscription.unsubscribe();
 | 
				
			||||||
    this.moveToStep('paid')
 | 
					    this.moveToStep('paid');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  isLoggedIn(): boolean {
 | 
					  isLoggedIn(): boolean {
 | 
				
			||||||
 | 
				
			|||||||
@ -142,7 +142,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
 | 
				
			|||||||
  taprootEnabled: boolean;
 | 
					  taprootEnabled: boolean;
 | 
				
			||||||
  hasEffectiveFeeRate: boolean;
 | 
					  hasEffectiveFeeRate: boolean;
 | 
				
			||||||
  accelerateCtaType: 'alert' | 'button' = 'button';
 | 
					  accelerateCtaType: 'alert' | 'button' = 'button';
 | 
				
			||||||
  acceleratorAvailable: boolean = this.stateService.env.ACCELERATOR && this.stateService.network === '';
 | 
					  acceleratorAvailable: boolean = this.stateService.env.ACCELERATOR_BUTTON && this.stateService.network === '';
 | 
				
			||||||
  eligibleForAcceleration: boolean = false;
 | 
					  eligibleForAcceleration: boolean = false;
 | 
				
			||||||
  forceAccelerationSummary = false;
 | 
					  forceAccelerationSummary = false;
 | 
				
			||||||
  hideAccelerationSummary = false;
 | 
					  hideAccelerationSummary = false;
 | 
				
			||||||
@ -196,7 +196,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
 | 
				
			|||||||
    this.stateService.networkChanged$.subscribe(
 | 
					    this.stateService.networkChanged$.subscribe(
 | 
				
			||||||
      (network) => {
 | 
					      (network) => {
 | 
				
			||||||
        this.network = network;
 | 
					        this.network = network;
 | 
				
			||||||
        this.acceleratorAvailable = this.stateService.env.ACCELERATOR && this.stateService.network === '';
 | 
					        this.acceleratorAvailable = this.stateService.env.ACCELERATOR_BUTTON && this.stateService.network === '';
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -536,6 +536,10 @@ export class ApiService {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  logAccelerationRequest$(txid: string): Observable<any> {
 | 
				
			||||||
 | 
					    return this.httpClient.post(this.apiBaseUrl + this.apiBasePath + '/api/v1/acceleration/request/' + txid, '');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Cache methods
 | 
					  // Cache methods
 | 
				
			||||||
  async setBlockAuditLoaded(hash: string) {
 | 
					  async setBlockAuditLoaded(hash: string) {
 | 
				
			||||||
    this.blockAuditLoaded[hash] = true;
 | 
					    this.blockAuditLoaded[hash] = true;
 | 
				
			||||||
 | 
				
			|||||||
@ -30,6 +30,7 @@ export class EnterpriseService {
 | 
				
			|||||||
      this.fetchSubdomainInfo();
 | 
					      this.fetchSubdomainInfo();
 | 
				
			||||||
      this.disableSubnetworks();
 | 
					      this.disableSubnetworks();
 | 
				
			||||||
      this.stateService.env.ACCELERATOR = false;
 | 
					      this.stateService.env.ACCELERATOR = false;
 | 
				
			||||||
 | 
					      this.stateService.env.ACCELERATOR_BUTTON = false;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      this.insertMatomo();
 | 
					      this.insertMatomo();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -71,6 +71,7 @@ export interface Env {
 | 
				
			|||||||
  SIGNET_BLOCK_AUDIT_START_HEIGHT: number;
 | 
					  SIGNET_BLOCK_AUDIT_START_HEIGHT: number;
 | 
				
			||||||
  HISTORICAL_PRICE: boolean;
 | 
					  HISTORICAL_PRICE: boolean;
 | 
				
			||||||
  ACCELERATOR: boolean;
 | 
					  ACCELERATOR: boolean;
 | 
				
			||||||
 | 
					  ACCELERATOR_BUTTON: boolean;
 | 
				
			||||||
  PUBLIC_ACCELERATIONS: boolean;
 | 
					  PUBLIC_ACCELERATIONS: boolean;
 | 
				
			||||||
  ADDITIONAL_CURRENCIES: boolean;
 | 
					  ADDITIONAL_CURRENCIES: boolean;
 | 
				
			||||||
  GIT_COMMIT_HASH_MEMPOOL_SPACE?: string;
 | 
					  GIT_COMMIT_HASH_MEMPOOL_SPACE?: string;
 | 
				
			||||||
@ -108,6 +109,7 @@ const defaultEnv: Env = {
 | 
				
			|||||||
  'SIGNET_BLOCK_AUDIT_START_HEIGHT': 0,
 | 
					  'SIGNET_BLOCK_AUDIT_START_HEIGHT': 0,
 | 
				
			||||||
  'HISTORICAL_PRICE': true,
 | 
					  'HISTORICAL_PRICE': true,
 | 
				
			||||||
  'ACCELERATOR': false,
 | 
					  'ACCELERATOR': false,
 | 
				
			||||||
 | 
					  'ACCELERATOR_BUTTON': true,
 | 
				
			||||||
  'PUBLIC_ACCELERATIONS': false,
 | 
					  'PUBLIC_ACCELERATIONS': false,
 | 
				
			||||||
  'ADDITIONAL_CURRENCIES': false,
 | 
					  'ADDITIONAL_CURRENCIES': false,
 | 
				
			||||||
  'SERVICES_API': 'https://mempool.space/api/v1/services',
 | 
					  'SERVICES_API': 'https://mempool.space/api/v1/services',
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,7 @@
 | 
				
			|||||||
  "ITEMS_PER_PAGE": 25,
 | 
					  "ITEMS_PER_PAGE": 25,
 | 
				
			||||||
  "LIGHTNING": true,
 | 
					  "LIGHTNING": true,
 | 
				
			||||||
  "ACCELERATOR": true,
 | 
					  "ACCELERATOR": true,
 | 
				
			||||||
 | 
					  "ACCELERATOR_BUTTON": true,
 | 
				
			||||||
  "PUBLIC_ACCELERATIONS": true,
 | 
					  "PUBLIC_ACCELERATIONS": true,
 | 
				
			||||||
  "AUDIT": true
 | 
					  "AUDIT": true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ heat()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
heatURLs=(
 | 
					heatURLs=(
 | 
				
			||||||
       '/api/v1/fees/recommended'
 | 
					       '/api/v1/fees/recommended'
 | 
				
			||||||
 | 
					       '/api/v1/accelerations'
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
while true
 | 
					while true
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,9 @@
 | 
				
			|||||||
# routing #
 | 
					# routing #
 | 
				
			||||||
###########
 | 
					###########
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					location /api/v1/accelerations {
 | 
				
			||||||
 | 
						try_files /dev/null @mempool-api-v1-services-cache-short;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
location /api/v1/assets {
 | 
					location /api/v1/assets {
 | 
				
			||||||
	try_files /dev/null @mempool-api-v1-services-cache-short;
 | 
						try_files /dev/null @mempool-api-v1-services-cache-short;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user