[accelerator] check for input replaceability
This commit is contained in:
		
							parent
							
								
									c71a0afe1f
								
							
						
					
					
						commit
						e35ac6e1a2
					
				| @ -122,7 +122,7 @@ | |||||||
|         <span class="explainer"> </span> |         <span class="explainer"> </span> | ||||||
|       } @else if (showAccelerationSummary) { |       } @else if (showAccelerationSummary) { | ||||||
|         <ng-container *ngIf="(ETA$ | async) as eta;"> |         <ng-container *ngIf="(ETA$ | async) as eta;"> | ||||||
|           <app-accelerate-checkout *ngIf="(da$ | async) as da;" [cashappEnabled]="accelerationEligible" [advancedEnabled]="false" [forceMobile]="true" [tx]="tx" [miningStats]="miningStats" [eta]="eta" [scrollEvent]="scrollIntoAccelPreview" class="h-100 w-100"></app-accelerate-checkout> |           <app-accelerate-checkout *ngIf="(da$ | async) as da;" [cashappEnabled]="cashappEligible" [advancedEnabled]="false" [forceMobile]="true" [tx]="tx" [miningStats]="miningStats" [eta]="eta" [scrollEvent]="scrollIntoAccelPreview" class="h-100 w-100"></app-accelerate-checkout> | ||||||
|         </ng-container> |         </ng-container> | ||||||
|       } @else { |       } @else { | ||||||
|         @if (tx?.acceleration && !tx.status?.confirmed) { |         @if (tx?.acceleration && !tx.status?.confirmed) { | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ import { AudioService } from '../../services/audio.service'; | |||||||
| import { ApiService } from '../../services/api.service'; | import { ApiService } from '../../services/api.service'; | ||||||
| import { SeoService } from '../../services/seo.service'; | import { SeoService } from '../../services/seo.service'; | ||||||
| import { seoDescriptionNetwork } from '../../shared/common.utils'; | import { seoDescriptionNetwork } from '../../shared/common.utils'; | ||||||
| import { Filter } from '../../shared/filters.utils'; | import { Filter, TransactionFlags } from '../../shared/filters.utils'; | ||||||
| import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment, Acceleration, AccelerationPosition } from '../../interfaces/node-api.interface'; | import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment, Acceleration, AccelerationPosition } from '../../interfaces/node-api.interface'; | ||||||
| import { PriceService } from '../../services/price.service'; | import { PriceService } from '../../services/price.service'; | ||||||
| import { ServicesApiServices } from '../../services/services-api.service'; | import { ServicesApiServices } from '../../services/services-api.service'; | ||||||
| @ -30,7 +30,7 @@ import { ZONE_SERVICE } from '../../injection-tokens'; | |||||||
| import { TrackerStage } from './tracker-bar.component'; | import { TrackerStage } from './tracker-bar.component'; | ||||||
| import { MiningService, MiningStats } from '../../services/mining.service'; | import { MiningService, MiningStats } from '../../services/mining.service'; | ||||||
| import { ETA, EtaService } from '../../services/eta.service'; | import { ETA, EtaService } from '../../services/eta.service'; | ||||||
| import { getUnacceleratedFeeRate } from '../../shared/transaction.utils'; | import { getTransactionFlags, getUnacceleratedFeeRate } from '../../shared/transaction.utils'; | ||||||
| 
 | 
 | ||||||
| interface Pool { | interface Pool { | ||||||
|   id: number; |   id: number; | ||||||
| @ -117,8 +117,7 @@ export class TrackerComponent implements OnInit, OnDestroy { | |||||||
|   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 && this.stateService.network === ''; | ||||||
|   accelerationEligible: boolean = false; |   eligibleForAcceleration: boolean = false; | ||||||
|   showAccelerationSummary = false; |  | ||||||
|   accelerationFlowCompleted = false; |   accelerationFlowCompleted = false; | ||||||
|   scrollIntoAccelPreview = false; |   scrollIntoAccelPreview = false; | ||||||
|   auditEnabled: boolean = this.stateService.env.AUDIT && this.stateService.env.BASE_MODULE === 'mempool' && this.stateService.env.MINING_DASHBOARD === true; |   auditEnabled: boolean = this.stateService.env.AUDIT && this.stateService.env.BASE_MODULE === 'mempool' && this.stateService.env.MINING_DASHBOARD === true; | ||||||
| @ -155,11 +154,6 @@ export class TrackerComponent implements OnInit, OnDestroy { | |||||||
|       this.miningStats = stats; |       this.miningStats = stats; | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     const urlParams = new URLSearchParams(window.location.search); |  | ||||||
|     if (urlParams.get('cash_request_id')) { |  | ||||||
|       this.showAccelerationSummary = true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     this.enterpriseService.page(); |     this.enterpriseService.page(); | ||||||
| 
 | 
 | ||||||
|     this.enterpriseInfo$ = this.enterpriseService.info$.subscribe(info => { |     this.enterpriseInfo$ = this.enterpriseService.info$.subscribe(info => { | ||||||
| @ -267,6 +261,7 @@ export class TrackerComponent implements OnInit, OnDestroy { | |||||||
| 
 | 
 | ||||||
|       if (!this.tx) { |       if (!this.tx) { | ||||||
|         this.tx = tx; |         this.tx = tx; | ||||||
|  |         this.checkAccelerationEligibility(); | ||||||
|         this.isCached = true; |         this.isCached = true; | ||||||
|         if (tx.fee === undefined) { |         if (tx.fee === undefined) { | ||||||
|           this.tx.fee = 0; |           this.tx.fee = 0; | ||||||
| @ -385,20 +380,9 @@ export class TrackerComponent implements OnInit, OnDestroy { | |||||||
|             this.trackerStage = 'replaced'; |             this.trackerStage = 'replaced'; | ||||||
|           } |           } | ||||||
| 
 | 
 | ||||||
|           if (!this.mempoolPosition.accelerated) { |           if (this.mempoolPosition.accelerated && this.showAccelerationSummary) { | ||||||
|             if (!this.accelerationFlowCompleted && !this.showAccelerationSummary && this.mempoolPosition.block > 0) { |  | ||||||
|               this.showAccelerationSummary = true; |  | ||||||
|               this.miningService.getMiningStats('1w').subscribe(stats => { |  | ||||||
|                 this.miningStats = stats; |  | ||||||
|               }); |  | ||||||
|             } |  | ||||||
|             if (txPosition.position?.block > 0) { |  | ||||||
|               this.accelerationEligible = true; |  | ||||||
|             } |  | ||||||
|           } else if (this.showAccelerationSummary) { |  | ||||||
|             setTimeout(() => { |             setTimeout(() => { | ||||||
|               this.accelerationFlowCompleted = true; |               this.accelerationFlowCompleted = true; | ||||||
|               this.showAccelerationSummary = false; |  | ||||||
|             }, 2000); |             }, 2000); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
| @ -462,6 +446,7 @@ export class TrackerComponent implements OnInit, OnDestroy { | |||||||
|           this.seoService.clearSoft404(); |           this.seoService.clearSoft404(); | ||||||
| 
 | 
 | ||||||
|           this.tx = tx; |           this.tx = tx; | ||||||
|  |           this.checkAccelerationEligibility(); | ||||||
|           this.isCached = false; |           this.isCached = false; | ||||||
|           if (tx.fee === undefined) { |           if (tx.fee === undefined) { | ||||||
|             this.tx.fee = 0; |             this.tx.fee = 0; | ||||||
| @ -744,8 +729,9 @@ export class TrackerComponent implements OnInit, OnDestroy { | |||||||
|     } |     } | ||||||
|     this.enterpriseService.goal(8); |     this.enterpriseService.goal(8); | ||||||
|     this.accelerationFlowCompleted = false; |     this.accelerationFlowCompleted = false; | ||||||
|     this.showAccelerationSummary = true && this.acceleratorAvailable; |     if (this.showAccelerationSummary) { | ||||||
|     this.scrollIntoAccelPreview = true; |       this.scrollIntoAccelPreview = true; | ||||||
|  |     } | ||||||
|     return false; |     return false; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -753,6 +739,30 @@ export class TrackerComponent implements OnInit, OnDestroy { | |||||||
|     return this.isLoadingTx || this.loadingCachedTx || this.loadingPosition; |     return this.isLoadingTx || this.loadingCachedTx || this.loadingPosition; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   checkAccelerationEligibility() { | ||||||
|  |     if (this.tx) { | ||||||
|  |       this.tx.flags = getTransactionFlags(this.tx); | ||||||
|  |       const replaceableInputs = (this.tx.flags & (TransactionFlags.sighash_none | TransactionFlags.sighash_acp)) > 0n; | ||||||
|  |       this.eligibleForAcceleration = !replaceableInputs; | ||||||
|  |     } else { | ||||||
|  |       this.eligibleForAcceleration = false; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   get cashappEligible(): boolean { | ||||||
|  |     return this.mempoolPosition?.block > 0; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   get showAccelerationSummary(): boolean { | ||||||
|  |     return ( | ||||||
|  |       this.tx | ||||||
|  |       && !this.tx.acceleration | ||||||
|  |       && this.acceleratorAvailable | ||||||
|  |       && this.eligibleForAcceleration | ||||||
|  |       && !this.accelerationFlowCompleted | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   resetTransaction() { |   resetTransaction() { | ||||||
|     this.error = undefined; |     this.error = undefined; | ||||||
|     this.tx = null; |     this.tx = null; | ||||||
| @ -778,7 +788,7 @@ export class TrackerComponent implements OnInit, OnDestroy { | |||||||
|     this.pool = null; |     this.pool = null; | ||||||
|     this.auditStatus = null; |     this.auditStatus = null; | ||||||
|     this.accelerationPositions = null; |     this.accelerationPositions = null; | ||||||
|     this.accelerationEligible = false; |     this.eligibleForAcceleration = false; | ||||||
|     this.trackerStage = 'waiting'; |     this.trackerStage = 'waiting'; | ||||||
|     document.body.scrollTo(0, 0); |     document.body.scrollTo(0, 0); | ||||||
|     this.leaveTransaction(); |     this.leaveTransaction(); | ||||||
|  | |||||||
| @ -147,7 +147,7 @@ | |||||||
|       <ng-container *ngIf="(ETA$ | async) as eta;"> |       <ng-container *ngIf="(ETA$ | async) as eta;"> | ||||||
|         <app-accelerate-checkout |         <app-accelerate-checkout | ||||||
|           *ngIf="(da$ | async) as da;" |           *ngIf="(da$ | async) as da;" | ||||||
|           [cashappEnabled]="accelerationEligible" |           [cashappEnabled]="cashappEligible" | ||||||
|           [advancedEnabled]="true" |           [advancedEnabled]="true" | ||||||
|           [tx]="tx" |           [tx]="tx" | ||||||
|           [eta]="eta" |           [eta]="eta" | ||||||
|  | |||||||
| @ -24,8 +24,8 @@ import { SeoService } from '../../services/seo.service'; | |||||||
| import { StorageService } from '../../services/storage.service'; | import { StorageService } from '../../services/storage.service'; | ||||||
| import { seoDescriptionNetwork } from '../../shared/common.utils'; | import { seoDescriptionNetwork } from '../../shared/common.utils'; | ||||||
| import { getTransactionFlags, getUnacceleratedFeeRate } from '../../shared/transaction.utils'; | import { getTransactionFlags, getUnacceleratedFeeRate } from '../../shared/transaction.utils'; | ||||||
| import { Filter, toFilters } from '../../shared/filters.utils'; | import { Filter, TransactionFlags, toFilters } from '../../shared/filters.utils'; | ||||||
| import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment, Acceleration, AccelerationPosition, SinglePoolStats } from '../../interfaces/node-api.interface'; | import { BlockExtended, CpfpInfo, RbfTree, MempoolPosition, DifficultyAdjustment, Acceleration, AccelerationPosition } from '../../interfaces/node-api.interface'; | ||||||
| import { LiquidUnblinding } from './liquid-ublinding'; | import { LiquidUnblinding } from './liquid-ublinding'; | ||||||
| import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe'; | import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe'; | ||||||
| import { PriceService } from '../../services/price.service'; | import { PriceService } from '../../services/price.service'; | ||||||
| @ -137,13 +137,14 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | |||||||
|   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 && this.stateService.network === ''; | ||||||
|  |   eligibleForAcceleration: boolean = false; | ||||||
|   forceAccelerationSummary = false; |   forceAccelerationSummary = false; | ||||||
|   hideAccelerationSummary = false; |   hideAccelerationSummary = false; | ||||||
|   accelerationFlowCompleted = false; |   accelerationFlowCompleted = false; | ||||||
|   showAccelerationDetails = false; |   showAccelerationDetails = false; | ||||||
|   hasAccelerationDetails = false; |   hasAccelerationDetails = false; | ||||||
|   scrollIntoAccelPreview = false; |   scrollIntoAccelPreview = false; | ||||||
|   accelerationEligible = false; |   cashappEligible = false; | ||||||
|   auditEnabled: boolean = this.stateService.env.AUDIT && this.stateService.env.BASE_MODULE === 'mempool' && this.stateService.env.MINING_DASHBOARD === true; |   auditEnabled: boolean = this.stateService.env.AUDIT && this.stateService.env.BASE_MODULE === 'mempool' && this.stateService.env.MINING_DASHBOARD === true; | ||||||
| 
 | 
 | ||||||
|   @ViewChild('graphContainer') |   @ViewChild('graphContainer') | ||||||
| @ -421,7 +422,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | |||||||
|                 }); |                 }); | ||||||
|               } |               } | ||||||
|               if (txPosition.position?.block > 0 && this.tx.weight < 4000) { |               if (txPosition.position?.block > 0 && this.tx.weight < 4000) { | ||||||
|                 this.accelerationEligible = true; |                 this.cashappEligible = true; | ||||||
|               } |               } | ||||||
|             } else if (this.showAccelerationSummary) { |             } else if (this.showAccelerationSummary) { | ||||||
|               setTimeout(() => { |               setTimeout(() => { | ||||||
| @ -819,6 +820,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | |||||||
|       this.rbfEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'rbf'); |       this.rbfEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'rbf'); | ||||||
|       this.tx.flags = getTransactionFlags(this.tx); |       this.tx.flags = getTransactionFlags(this.tx); | ||||||
|       this.filters = this.tx.flags ? toFilters(this.tx.flags).filter(f => f.txPage) : []; |       this.filters = this.tx.flags ? toFilters(this.tx.flags).filter(f => f.txPage) : []; | ||||||
|  |       this.checkAccelerationEligibility(); | ||||||
|     } else { |     } else { | ||||||
|       this.segwitEnabled = false; |       this.segwitEnabled = false; | ||||||
|       this.taprootEnabled = false; |       this.taprootEnabled = false; | ||||||
| @ -827,6 +829,15 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | |||||||
|     this.featuresEnabled = this.segwitEnabled || this.taprootEnabled || this.rbfEnabled; |     this.featuresEnabled = this.segwitEnabled || this.taprootEnabled || this.rbfEnabled; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   checkAccelerationEligibility() { | ||||||
|  |     if (this.tx && this.tx.flags) { | ||||||
|  |       const replaceableInputs = (this.tx.flags & (TransactionFlags.sighash_none | TransactionFlags.sighash_acp)) > 0n; | ||||||
|  |       this.eligibleForAcceleration = !replaceableInputs; | ||||||
|  |     } else { | ||||||
|  |       this.eligibleForAcceleration = false; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   isAuditAvailable(blockHeight: number): boolean { |   isAuditAvailable(blockHeight: number): boolean { | ||||||
|     if (!this.auditEnabled) { |     if (!this.auditEnabled) { | ||||||
|       return false; |       return false; | ||||||
| @ -871,7 +882,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | |||||||
|     this.showCpfpDetails = false; |     this.showCpfpDetails = false; | ||||||
|     this.showAccelerationDetails = false; |     this.showAccelerationDetails = false; | ||||||
|     this.accelerationInfo = null; |     this.accelerationInfo = null; | ||||||
|     this.accelerationEligible = false; |     this.cashappEligible = false; | ||||||
|     this.txInBlockIndex = null; |     this.txInBlockIndex = null; | ||||||
|     this.mempoolPosition = null; |     this.mempoolPosition = null; | ||||||
|     this.pool = null; |     this.pool = null; | ||||||
| @ -880,6 +891,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | |||||||
|     document.body.scrollTo(0, 0); |     document.body.scrollTo(0, 0); | ||||||
|     this.isAcceleration = false; |     this.isAcceleration = false; | ||||||
|     this.isAccelerated$.next(this.isAcceleration); |     this.isAccelerated$.next(this.isAcceleration); | ||||||
|  |     this.eligibleForAcceleration = false; | ||||||
|     this.leaveTransaction(); |     this.leaveTransaction(); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -974,6 +986,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy { | |||||||
|       this.tx |       this.tx | ||||||
|       && !this.tx.acceleration |       && !this.tx.acceleration | ||||||
|       && this.acceleratorAvailable |       && this.acceleratorAvailable | ||||||
|  |       && this.eligibleForAcceleration | ||||||
|       && ( |       && ( | ||||||
|         (!this.hideAccelerationSummary && !this.accelerationFlowCompleted) |         (!this.hideAccelerationSummary && !this.accelerationFlowCompleted) | ||||||
|         || this.forceAccelerationSummary |         || this.forceAccelerationSummary | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user