Merge branch 'master' into mononaut/acceleration-viz
This commit is contained in:
		
						commit
						f8faccd502
					
				@ -276,7 +276,7 @@ class Mempool {
 | 
			
		||||
      logger.warn(`Mempool clear protection triggered because transactions.length: ${transactions.length} and currentMempoolSize: ${currentMempoolSize}.`);
 | 
			
		||||
      setTimeout(() => {
 | 
			
		||||
        this.mempoolProtection = 2;
 | 
			
		||||
        logger.warn('Mempool clear protection resumed.');
 | 
			
		||||
        logger.warn('Mempool clear protection ended, normal operation resumed.');
 | 
			
		||||
      }, 1000 * 60 * config.MEMPOOL.CLEAR_PROTECTION_MINUTES);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -191,15 +191,22 @@ class WebsocketHandler {
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (parsedMessage && parsedMessage['track-address']) {
 | 
			
		||||
            if (/^([a-km-zA-HJ-NP-Z1-9]{26,35}|[a-km-zA-HJ-NP-Z1-9]{80}|[a-z]{2,5}1[ac-hj-np-z02-9]{8,100}|[A-Z]{2,5}1[AC-HJ-NP-Z02-9]{8,100})$/
 | 
			
		||||
            if (/^([a-km-zA-HJ-NP-Z1-9]{26,35}|[a-km-zA-HJ-NP-Z1-9]{80}|[a-z]{2,5}1[ac-hj-np-z02-9]{8,100}|[A-Z]{2,5}1[AC-HJ-NP-Z02-9]{8,100}|[0-9a-fA-F]{130})$/
 | 
			
		||||
              .test(parsedMessage['track-address'])) {
 | 
			
		||||
              let matchedAddress = parsedMessage['track-address'];
 | 
			
		||||
              if (/^[A-Z]{2,5}1[AC-HJ-NP-Z02-9]{8,100}$/.test(parsedMessage['track-address'])) {
 | 
			
		||||
                matchedAddress = matchedAddress.toLowerCase();
 | 
			
		||||
              }
 | 
			
		||||
              client['track-address'] = matchedAddress;
 | 
			
		||||
              if (/^[0-9a-fA-F]{130}$/.test(parsedMessage['track-address'])) {
 | 
			
		||||
                client['track-address'] = null;
 | 
			
		||||
                client['track-scriptpubkey'] = '41' + matchedAddress + 'ac';
 | 
			
		||||
              } else {
 | 
			
		||||
                client['track-address'] = matchedAddress;
 | 
			
		||||
                client['track-scriptpubkey'] = null;
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              client['track-address'] = null;
 | 
			
		||||
              client['track-scriptpubkey'] = null;
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
@ -554,6 +561,44 @@ class WebsocketHandler {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['track-scriptpubkey']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
        for (const tx of newTransactions) {
 | 
			
		||||
          const someVin = tx.vin.some((vin) => !!vin.prevout && vin.prevout.scriptpubkey_type === 'p2pk' && vin.prevout.scriptpubkey === client['track-scriptpubkey']);
 | 
			
		||||
          if (someVin) {
 | 
			
		||||
            if (config.MEMPOOL.BACKEND !== 'esplora') {
 | 
			
		||||
              try {
 | 
			
		||||
                const fullTx = await transactionUtils.$getMempoolTransactionExtended(tx.txid, true);
 | 
			
		||||
                foundTransactions.push(fullTx);
 | 
			
		||||
              } catch (e) {
 | 
			
		||||
                logger.debug('Error finding transaction in mempool: ' + (e instanceof Error ? e.message : e));
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              foundTransactions.push(tx);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          const someVout = tx.vout.some((vout) => vout.scriptpubkey_type === 'p2pk' && vout.scriptpubkey === client['track-scriptpubkey']);
 | 
			
		||||
          if (someVout) {
 | 
			
		||||
            if (config.MEMPOOL.BACKEND !== 'esplora') {
 | 
			
		||||
              try {
 | 
			
		||||
                const fullTx = await transactionUtils.$getMempoolTransactionExtended(tx.txid, true);
 | 
			
		||||
                foundTransactions.push(fullTx);
 | 
			
		||||
              } catch (e) {
 | 
			
		||||
                logger.debug('Error finding transaction in mempool: ' + (e instanceof Error ? e.message : e));
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              foundTransactions.push(tx);
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (foundTransactions.length) {
 | 
			
		||||
          response['address-transactions'] = JSON.stringify(foundTransactions);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['track-asset']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
@ -845,6 +890,33 @@ class WebsocketHandler {
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['track-scriptpubkey']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
        transactions.forEach((tx) => {
 | 
			
		||||
          if (tx.vin && tx.vin.some((vin) => !!vin.prevout && vin.prevout.scriptpubkey_type === 'p2pk' && vin.prevout.scriptpubkey === client['track-scriptpubkey'])) {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
          if (tx.vout && tx.vout.some((vout) => vout.scriptpubkey_type === 'p2pk' && vout.scriptpubkey === client['track-scriptpubkey'])) {
 | 
			
		||||
            foundTransactions.push(tx);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        if (foundTransactions.length) {
 | 
			
		||||
          foundTransactions.forEach((tx) => {
 | 
			
		||||
            tx.status = {
 | 
			
		||||
              confirmed: true,
 | 
			
		||||
              block_height: block.height,
 | 
			
		||||
              block_hash: block.id,
 | 
			
		||||
              block_time: block.timestamp,
 | 
			
		||||
            };
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          response['block-transactions'] = JSON.stringify(foundTransactions);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (client['track-asset']) {
 | 
			
		||||
        const foundTransactions: TransactionExtended[] = [];
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -166,31 +166,8 @@ export class AddressComponent implements OnInit, OnDestroy {
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    this.stateService.mempoolTransactions$
 | 
			
		||||
      .subscribe((transaction) => {
 | 
			
		||||
        if (this.transactions.some((t) => t.txid === transaction.txid)) {
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.transactions.unshift(transaction);
 | 
			
		||||
        this.transactions = this.transactions.slice();
 | 
			
		||||
        this.txCount++;
 | 
			
		||||
 | 
			
		||||
        if (transaction.vout.some((vout) => vout.scriptpubkey_address === this.address.address)) {
 | 
			
		||||
          this.audioService.playSound('cha-ching');
 | 
			
		||||
        } else {
 | 
			
		||||
          this.audioService.playSound('chime');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        transaction.vin.forEach((vin) => {
 | 
			
		||||
          if (vin.prevout.scriptpubkey_address === this.address.address) {
 | 
			
		||||
            this.sent += vin.prevout.value;
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
        transaction.vout.forEach((vout) => {
 | 
			
		||||
          if (vout.scriptpubkey_address === this.address.address) {
 | 
			
		||||
            this.received += vout.value;
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      .subscribe(tx => {
 | 
			
		||||
        this.addTransaction(tx);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    this.stateService.blockTransactions$
 | 
			
		||||
@ -200,12 +177,47 @@ export class AddressComponent implements OnInit, OnDestroy {
 | 
			
		||||
          tx.status = transaction.status;
 | 
			
		||||
          this.transactions = this.transactions.slice();
 | 
			
		||||
          this.audioService.playSound('magic');
 | 
			
		||||
        } else {
 | 
			
		||||
          if (this.addTransaction(transaction, false)) {
 | 
			
		||||
            this.audioService.playSound('magic');
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        this.totalConfirmedTxCount++;
 | 
			
		||||
        this.loadedConfirmedTxCount++;
 | 
			
		||||
      });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  addTransaction(transaction: Transaction, playSound: boolean = true): boolean {
 | 
			
		||||
    if (this.transactions.some((t) => t.txid === transaction.txid)) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.transactions.unshift(transaction);
 | 
			
		||||
    this.transactions = this.transactions.slice();
 | 
			
		||||
    this.txCount++;
 | 
			
		||||
 | 
			
		||||
    if (playSound) {
 | 
			
		||||
      if (transaction.vout.some((vout) => vout?.scriptpubkey_address === this.address.address)) {
 | 
			
		||||
        this.audioService.playSound('cha-ching');
 | 
			
		||||
      } else {
 | 
			
		||||
        this.audioService.playSound('chime');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    transaction.vin.forEach((vin) => {
 | 
			
		||||
      if (vin?.prevout?.scriptpubkey_address === this.address.address) {
 | 
			
		||||
        this.sent += vin.prevout.value;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    transaction.vout.forEach((vout) => {
 | 
			
		||||
      if (vout?.scriptpubkey_address === this.address.address) {
 | 
			
		||||
        this.received += vout.value;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  loadMore() {
 | 
			
		||||
    if (this.isLoadingTransactions || !this.totalConfirmedTxCount || this.loadedConfirmedTxCount >= this.totalConfirmedTxCount) {
 | 
			
		||||
      return;
 | 
			
		||||
 | 
			
		||||
@ -51,6 +51,8 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
  blockSubscription: Subscription;
 | 
			
		||||
  networkSubscription: Subscription;
 | 
			
		||||
  chainTipSubscription: Subscription;
 | 
			
		||||
  keySubscription: Subscription;
 | 
			
		||||
  isTabHiddenSubscription: Subscription;
 | 
			
		||||
  network = '';
 | 
			
		||||
  now = new Date().getTime();
 | 
			
		||||
  timeOffset = 0;
 | 
			
		||||
@ -117,7 +119,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
      this.calculateTransactionPosition();
 | 
			
		||||
    });
 | 
			
		||||
    this.reduceMempoolBlocksToFitScreen(this.mempoolBlocks);
 | 
			
		||||
    this.stateService.isTabHidden$.subscribe((tabHidden) => this.tabHidden = tabHidden);
 | 
			
		||||
    this.isTabHiddenSubscription = this.stateService.isTabHidden$.subscribe((tabHidden) => this.tabHidden = tabHidden);
 | 
			
		||||
    this.loadingBlocks$ = combineLatest([
 | 
			
		||||
      this.stateService.isLoadingWebSocket$,
 | 
			
		||||
      this.stateService.isLoadingMempool$
 | 
			
		||||
@ -225,7 +227,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
    this.networkSubscription = this.stateService.networkChanged$
 | 
			
		||||
      .subscribe((network) => this.network = network);
 | 
			
		||||
 | 
			
		||||
    this.stateService.keyNavigation$.subscribe((event) => {
 | 
			
		||||
    this.keySubscription = this.stateService.keyNavigation$.subscribe((event) => {
 | 
			
		||||
      if (this.markIndex === undefined) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
@ -236,13 +238,12 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
        if (this.mempoolBlocks[this.markIndex - 1]) {
 | 
			
		||||
          this.router.navigate([this.relativeUrlPipe.transform('mempool-block/'), this.markIndex - 1]);
 | 
			
		||||
        } else {
 | 
			
		||||
          this.stateService.blocks$
 | 
			
		||||
            .pipe(map((blocks) => blocks[0]))
 | 
			
		||||
            .subscribe((block) => {
 | 
			
		||||
              if (this.stateService.latestBlockHeight === block.height) {
 | 
			
		||||
                this.router.navigate([this.relativeUrlPipe.transform('/block/'), block.id], { state: { data: { block } }});
 | 
			
		||||
              }
 | 
			
		||||
            });
 | 
			
		||||
          const blocks = this.stateService.blocksSubject$.getValue();
 | 
			
		||||
          for (const block of (blocks || [])) {
 | 
			
		||||
            if (this.stateService.latestBlockHeight === block.height) {
 | 
			
		||||
              this.router.navigate([this.relativeUrlPipe.transform('/block/'), block.id], { state: { data: { block } }});
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      } else if (event.key === nextKey) {
 | 
			
		||||
        if (this.mempoolBlocks[this.markIndex + 1]) {
 | 
			
		||||
@ -266,6 +267,8 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
    this.networkSubscription.unsubscribe();
 | 
			
		||||
    this.timeLtrSubscription.unsubscribe();
 | 
			
		||||
    this.chainTipSubscription.unsubscribe();
 | 
			
		||||
    this.keySubscription.unsubscribe();
 | 
			
		||||
    this.isTabHiddenSubscription.unsubscribe();
 | 
			
		||||
    clearTimeout(this.resetTransitionTimeout);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user