Batch esplora outspends requests
This commit is contained in:
		
							parent
							
								
									823f06451c
								
							
						
					
					
						commit
						8aa51c4e80
					
				@ -112,6 +112,7 @@ class BitcoinRoutes {
 | 
				
			|||||||
          .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/hex', this.getRawTransaction)
 | 
					          .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/hex', this.getRawTransaction)
 | 
				
			||||||
          .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/status', this.getTransactionStatus)
 | 
					          .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/status', this.getTransactionStatus)
 | 
				
			||||||
          .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/outspends', this.getTransactionOutspends)
 | 
					          .get(config.MEMPOOL.API_URL_PREFIX + 'tx/:txId/outspends', this.getTransactionOutspends)
 | 
				
			||||||
 | 
					          .get(config.MEMPOOL.API_URL_PREFIX + 'txs/outspends', this.$getOutspends)
 | 
				
			||||||
          .get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/header', this.getBlockHeader)
 | 
					          .get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/header', this.getBlockHeader)
 | 
				
			||||||
          .get(config.MEMPOOL.API_URL_PREFIX + 'blocks/tip/hash', this.getBlockTipHash)
 | 
					          .get(config.MEMPOOL.API_URL_PREFIX + 'blocks/tip/hash', this.getBlockTipHash)
 | 
				
			||||||
          .get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/raw', this.getRawBlock)
 | 
					          .get(config.MEMPOOL.API_URL_PREFIX + 'block/:hash/raw', this.getRawBlock)
 | 
				
			||||||
@ -198,6 +199,26 @@ class BitcoinRoutes {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private async $getOutspends(req: Request, res: Response) {
 | 
				
			||||||
 | 
					    const txids_csv = req.query.txids;
 | 
				
			||||||
 | 
					    if (!txids_csv || typeof txids_csv !== 'string') {
 | 
				
			||||||
 | 
					      res.status(500).send('Invalid txids format');
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const txids = txids_csv.split(',');
 | 
				
			||||||
 | 
					    if (txids.length > 50) {
 | 
				
			||||||
 | 
					      res.status(400).send('Too many txids requested');
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const batchedOutspends = await bitcoinApi.$getBatchedOutspends(txids);
 | 
				
			||||||
 | 
					      res.json(batchedOutspends);
 | 
				
			||||||
 | 
					    } catch (e) {
 | 
				
			||||||
 | 
					      res.status(500).send(e instanceof Error ? e.message : e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private async $getCpfpInfo(req: Request, res: Response) {
 | 
					  private async $getCpfpInfo(req: Request, res: Response) {
 | 
				
			||||||
    if (!/^[a-fA-F0-9]{64}$/.test(req.params.txId)) {
 | 
					    if (!/^[a-fA-F0-9]{64}$/.test(req.params.txId)) {
 | 
				
			||||||
      res.status(501).send(`Invalid transaction ID.`);
 | 
					      res.status(501).send(`Invalid transaction ID.`);
 | 
				
			||||||
 | 
				
			|||||||
@ -174,6 +174,9 @@ class FailoverRouter {
 | 
				
			|||||||
      axiosConfig = { timeout: config.ESPLORA.REQUEST_TIMEOUT, responseType };
 | 
					      axiosConfig = { timeout: config.ESPLORA.REQUEST_TIMEOUT, responseType };
 | 
				
			||||||
      url = host.host + path;
 | 
					      url = host.host + path;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (data?.params) {
 | 
				
			||||||
 | 
					      axiosConfig.params = data.params;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return (method === 'post'
 | 
					    return (method === 'post'
 | 
				
			||||||
        ? this.requestConnection.post<T>(url, data, axiosConfig)
 | 
					        ? this.requestConnection.post<T>(url, data, axiosConfig)
 | 
				
			||||||
        : this.requestConnection.get<T>(url, axiosConfig)
 | 
					        : this.requestConnection.get<T>(url, axiosConfig)
 | 
				
			||||||
@ -193,8 +196,8 @@ class FailoverRouter {
 | 
				
			|||||||
      });
 | 
					      });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public async $get<T>(path, responseType = 'json'): Promise<T> {
 | 
					  public async $get<T>(path, responseType = 'json', params: any = null): Promise<T> {
 | 
				
			||||||
    return this.$query<T>('get', path, null, responseType);
 | 
					    return this.$query<T>('get', path, params ? { params } : null, responseType);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public async $post<T>(path, data: any, responseType = 'json'): Promise<T> {
 | 
					  public async $post<T>(path, data: any, responseType = 'json'): Promise<T> {
 | 
				
			||||||
@ -294,13 +297,8 @@ class ElectrsApi implements AbstractBitcoinApi {
 | 
				
			|||||||
    return this.failoverRouter.$get<IEsploraApi.Outspend[]>('/tx/' + txId + '/outspends');
 | 
					    return this.failoverRouter.$get<IEsploraApi.Outspend[]>('/tx/' + txId + '/outspends');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  async $getBatchedOutspends(txId: string[]): Promise<IEsploraApi.Outspend[][]> {
 | 
					  async $getBatchedOutspends(txids: string[]): Promise<IEsploraApi.Outspend[][]> {
 | 
				
			||||||
    const outspends: IEsploraApi.Outspend[][] = [];
 | 
					    return this.failoverRouter.$get<IEsploraApi.Outspend[][]>('/txs/outspends', 'json', { txids: txids.join(',') });
 | 
				
			||||||
    for (const tx of txId) {
 | 
					 | 
				
			||||||
      const outspend = await this.$getOutspends(tx);
 | 
					 | 
				
			||||||
      outspends.push(outspend);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return outspends;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public startHealthChecks(): void {
 | 
					  public startHealthChecks(): void {
 | 
				
			||||||
 | 
				
			|||||||
@ -75,7 +75,7 @@ export class TransactionsListComponent implements OnInit, OnChanges {
 | 
				
			|||||||
              for (let i = 0; i < txIds.length; i += 50) {
 | 
					              for (let i = 0; i < txIds.length; i += 50) {
 | 
				
			||||||
                batches.push(txIds.slice(i, i + 50));
 | 
					                batches.push(txIds.slice(i, i + 50));
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
              return forkJoin(batches.map(batch => { return this.apiService.cachedRequest(this.apiService.getOutspendsBatched$, 250, batch); }));
 | 
					              return forkJoin(batches.map(batch => this.electrsApiService.getOutspendsBatched$(batch)));
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
              return of([]);
 | 
					              return of([]);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,7 @@ import { ApiService } from '../../services/api.service';
 | 
				
			|||||||
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
 | 
					import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
 | 
				
			||||||
import { AssetsService } from '../../services/assets.service';
 | 
					import { AssetsService } from '../../services/assets.service';
 | 
				
			||||||
import { environment } from '../../../environments/environment';
 | 
					import { environment } from '../../../environments/environment';
 | 
				
			||||||
 | 
					import { ElectrsApiService } from '../../services/electrs-api.service';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface SvgLine {
 | 
					interface SvgLine {
 | 
				
			||||||
  path: string;
 | 
					  path: string;
 | 
				
			||||||
@ -100,7 +101,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
 | 
				
			|||||||
    private router: Router,
 | 
					    private router: Router,
 | 
				
			||||||
    private relativeUrlPipe: RelativeUrlPipe,
 | 
					    private relativeUrlPipe: RelativeUrlPipe,
 | 
				
			||||||
    private stateService: StateService,
 | 
					    private stateService: StateService,
 | 
				
			||||||
    private apiService: ApiService,
 | 
					    private electrsApiService: ElectrsApiService,
 | 
				
			||||||
    private assetsService: AssetsService,
 | 
					    private assetsService: AssetsService,
 | 
				
			||||||
    @Inject(LOCALE_ID) private locale: string,
 | 
					    @Inject(LOCALE_ID) private locale: string,
 | 
				
			||||||
  ) {
 | 
					  ) {
 | 
				
			||||||
@ -123,7 +124,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
 | 
				
			|||||||
        .pipe(
 | 
					        .pipe(
 | 
				
			||||||
          switchMap((txid) => {
 | 
					          switchMap((txid) => {
 | 
				
			||||||
            if (!this.cached) {
 | 
					            if (!this.cached) {
 | 
				
			||||||
              return this.apiService.cachedRequest(this.apiService.getOutspendsBatched$, 250, [txid]);
 | 
					              return this.electrsApiService.getOutspendsBatched$([txid]);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
              return of(null);
 | 
					              return of(null);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -138,14 +138,6 @@ export class ApiService {
 | 
				
			|||||||
    return this.httpClient.get<number[]>(this.apiBaseUrl + this.apiBasePath + '/api/v1/transaction-times', { params });
 | 
					    return this.httpClient.get<number[]>(this.apiBaseUrl + this.apiBasePath + '/api/v1/transaction-times', { params });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getOutspendsBatched$(txIds: string[]): Observable<Outspend[][]> {
 | 
					 | 
				
			||||||
    let params = new HttpParams();
 | 
					 | 
				
			||||||
    txIds.forEach((txId: string) => {
 | 
					 | 
				
			||||||
      params = params.append('txId[]', txId);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    return this.httpClient.get<Outspend[][]>(this.apiBaseUrl + this.apiBasePath + '/api/v1/outspends', { params });
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  getAboutPageProfiles$(): Observable<any[]> {
 | 
					  getAboutPageProfiles$(): Observable<any[]> {
 | 
				
			||||||
    return this.httpClient.get<any[]>(this.apiBaseUrl + '/api/v1/services/sponsors');
 | 
					    return this.httpClient.get<any[]>(this.apiBaseUrl + '/api/v1/services/sponsors');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
@ -54,6 +54,12 @@ export class ElectrsApiService {
 | 
				
			|||||||
    return this.httpClient.get<Outspend[]>(this.apiBaseUrl + this.apiBasePath + '/api/tx/' + hash + '/outspends');
 | 
					    return this.httpClient.get<Outspend[]>(this.apiBaseUrl + this.apiBasePath + '/api/tx/' + hash + '/outspends');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getOutspendsBatched$(txids: string[]): Observable<Outspend[][]> {
 | 
				
			||||||
 | 
					    let params = new HttpParams();
 | 
				
			||||||
 | 
					    params = params.append('txids', txids.join(','));
 | 
				
			||||||
 | 
					    return this.httpClient.get<Outspend[][]>(this.apiBaseUrl + this.apiBasePath + '/api/txs/outspends', { params });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  getBlockTransactions$(hash: string, index: number = 0): Observable<Transaction[]> {
 | 
					  getBlockTransactions$(hash: string, index: number = 0): Observable<Transaction[]> {
 | 
				
			||||||
    return this.httpClient.get<Transaction[]>(this.apiBaseUrl + this.apiBasePath + '/api/block/' + hash + '/txs/' + index);
 | 
					    return this.httpClient.get<Transaction[]>(this.apiBaseUrl + this.apiBasePath + '/api/block/' + hash + '/txs/' + index);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user