Merge branch 'master' into fee-visibility
This commit is contained in:
		
						commit
						50cd8e01bd
					
				| @ -84,19 +84,19 @@ class BitcoinApi implements AbstractBitcoinApi { | ||||
|   } | ||||
| 
 | ||||
|   $getAddressPrefix(prefix: string): string[] { | ||||
|     const found: string[] = []; | ||||
|     const found: { [address: string]: string } = {}; | ||||
|     const mp = mempool.getMempool(); | ||||
|     for (const tx in mp) { | ||||
|       for (const vout of mp[tx].vout) { | ||||
|         if (vout.scriptpubkey_address.indexOf(prefix) === 0) { | ||||
|           found.push(vout.scriptpubkey_address); | ||||
|           if (found.length >= 10) { | ||||
|             return found; | ||||
|           found[vout.scriptpubkey_address] = ''; | ||||
|           if (Object.keys(found).length >= 10) { | ||||
|             return Object.keys(found); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return found; | ||||
|     return Object.keys(found); | ||||
|   } | ||||
| 
 | ||||
|   $sendRawTransaction(rawTransaction: string): Promise<string> { | ||||
|  | ||||
| @ -218,7 +218,6 @@ class Blocks { | ||||
|           if (blockHeight < lastBlockToIndex) { | ||||
|             break; | ||||
|           } | ||||
|           try { | ||||
|           ++indexedThisRun; | ||||
|           if (++totaIndexed % 100 === 0 || blockHeight === lastBlockToIndex) { | ||||
|             const elapsedSeconds = Math.max(1, Math.round((new Date().getTime() / 1000) - startedAt)); | ||||
| @ -232,17 +231,15 @@ class Blocks { | ||||
|           const transactions = await this.$getTransactionsExtended(blockHash, block.height, true, true); | ||||
|           const blockExtended = await this.$getBlockExtended(block, transactions); | ||||
|           await blocksRepository.$saveBlockInDatabase(blockExtended); | ||||
|           } catch (e) { | ||||
|             logger.err(`Something went wrong while indexing blocks.` + e); | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         currentBlockHeight -= chunkSize; | ||||
|       } | ||||
|       logger.info('Block indexing completed'); | ||||
|     } catch (e) { | ||||
|       logger.err('An error occured in $generateBlockDatabase(). Skipping block indexing. ' + e); | ||||
|       console.log(e); | ||||
|       logger.err('An error occured in $generateBlockDatabase(). Trying again later. ' + e); | ||||
|       this.blockIndexingStarted = false; | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     this.blockIndexingCompleted = true; | ||||
|  | ||||
| @ -108,6 +108,8 @@ class Mining { | ||||
|     if (!blocks.blockIndexingCompleted || this.hashrateIndexingStarted) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     try { | ||||
|       this.hashrateIndexingStarted = true; | ||||
| 
 | ||||
|       logger.info(`Indexing hashrates`); | ||||
| @ -142,7 +144,7 @@ class Mining { | ||||
|         lastBlockHashrate = await bitcoinClient.getNetworkHashPs(blockStats.blockCount, | ||||
|           blockStats.lastBlockHeight); | ||||
| 
 | ||||
|       if (totalIndexed % 7 === 0 && !indexedTimestamp.includes(fromTimestamp + 1)) { // Save weekly pools hashrate
 | ||||
|         if (totalIndexed > 7 && totalIndexed % 7 === 0 && !indexedTimestamp.includes(fromTimestamp + 1)) { // Save weekly pools hashrate
 | ||||
|           logger.debug("Indexing weekly hashrates for mining pools"); | ||||
|           let pools = await PoolsRepository.$getPoolsInfoBetween(fromTimestamp - 604800, fromTimestamp); | ||||
|           const totalBlocks = pools.reduce((acc, pool) => acc + pool.blockCount, 0); | ||||
| @ -208,6 +210,10 @@ class Mining { | ||||
|       this.hashrateIndexingStarted = false; | ||||
| 
 | ||||
|       logger.info(`Hashrates indexing completed`); | ||||
|     } catch (e) { | ||||
|       this.hashrateIndexingStarted = false; | ||||
|       throw e; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -96,8 +96,8 @@ class Server { | ||||
|           await Common.sleep(5000); | ||||
|           await databaseMigration.$truncateIndexedData(tables); | ||||
|         } | ||||
|         await this.$resetHashratesIndexingState(); | ||||
|         await databaseMigration.$initializeOrMigrateDatabase(); | ||||
|         await this.$resetHashratesIndexingState(); | ||||
|         await poolsParser.migratePoolsJson(); | ||||
|       } catch (e) { | ||||
|         throw new Error(e instanceof Error ? e.message : 'Error'); | ||||
|  | ||||
| @ -22,6 +22,7 @@ class HashratesRepository { | ||||
|       await connection.query(query); | ||||
|     } catch (e: any) { | ||||
|       logger.err('$saveHashrateInDatabase() error' + (e instanceof Error ? e.message : e)); | ||||
|       throw e; | ||||
|     } | ||||
| 
 | ||||
|     connection.release(); | ||||
|  | ||||
| @ -74,6 +74,7 @@ import { HashrateChartComponent } from './components/hashrate-chart/hashrate-cha | ||||
| import { HashrateChartPoolsComponent } from './components/hashrates-chart-pools/hashrate-chart-pools.component'; | ||||
| import { MiningStartComponent } from './components/mining-start/mining-start.component'; | ||||
| import { AmountShortenerPipe } from './shared/pipes/amount-shortener.pipe'; | ||||
| import { ShortenStringPipe } from './shared/pipes/shorten-string-pipe/shorten-string.pipe'; | ||||
| 
 | ||||
| @NgModule({ | ||||
|   declarations: [ | ||||
| @ -154,6 +155,7 @@ import { AmountShortenerPipe } from './shared/pipes/amount-shortener.pipe'; | ||||
|     SeoService, | ||||
|     StorageService, | ||||
|     LanguageService, | ||||
|     ShortenStringPipe, | ||||
|     { provide: HTTP_INTERCEPTORS, useClass: HttpCacheInterceptor, multi: true } | ||||
|   ], | ||||
|   bootstrap: [AppComponent] | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| <form [formGroup]="searchForm" (submit)="searchForm.valid && search()" novalidate> | ||||
|   <div class="d-flex"> | ||||
|     <div class="search-box-container mr-2"> | ||||
|       <input #instance="ngbTypeahead" [ngbTypeahead]="typeaheadSearchFn" (selectItem)="itemSelected()" (focus)="focus$.next($any($event).target.value)" (click)="click$.next($any($event).target.value)" formControlName="searchText" type="text" class="form-control" i18n-placeholder="search-form.searchbar-placeholder" placeholder="TXID, block height, hash or address"> | ||||
|       <input #instance="ngbTypeahead" [ngbTypeahead]="typeaheadSearchFn" [resultFormatter]="formatterFn" (selectItem)="itemSelected()" (focus)="focus$.next($any($event).target.value)" (click)="click$.next($any($event).target.value)" formControlName="searchText" type="text" class="form-control" i18n-placeholder="search-form.searchbar-placeholder" placeholder="TXID, block height, hash or address"> | ||||
|     </div> | ||||
|     <div> | ||||
|       <button [disabled]="isSearching" type="submit" class="btn btn-block btn-primary"><fa-icon [icon]="['fas', 'search']" [fixedWidth]="true" i18n-title="search-form.search-title" title="Search"></fa-icon></button> | ||||
|  | ||||
| @ -1,8 +1,19 @@ | ||||
| :host ::ng-deep .dropdown-item { | ||||
| :host ::ng-deep { | ||||
|   .dropdown-item { | ||||
|     white-space: nowrap; | ||||
|   overflow: hidden; | ||||
|   width: 375px; | ||||
|   text-overflow: ellipsis; | ||||
|     width: calc(100% - 34px); | ||||
|   } | ||||
|   .dropdown-menu { | ||||
|     width: calc(100% - 34px); | ||||
|   } | ||||
|   @media (min-width: 768px) { | ||||
|     .dropdown-item { | ||||
|       width: 410px; | ||||
|     } | ||||
|     .dropdown-menu { | ||||
|       width: 410px; | ||||
|     } | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| form { | ||||
|  | ||||
| @ -8,6 +8,7 @@ import { debounceTime, distinctUntilChanged, switchMap, filter, catchError, map | ||||
| import { ElectrsApiService } from 'src/app/services/electrs-api.service'; | ||||
| import { NgbTypeahead } from '@ng-bootstrap/ng-bootstrap'; | ||||
| import { RelativeUrlPipe } from 'src/app/shared/pipes/relative-url/relative-url.pipe'; | ||||
| import { ShortenStringPipe } from 'src/app/shared/pipes/shorten-string-pipe/shorten-string.pipe'; | ||||
| 
 | ||||
| @Component({ | ||||
|   selector: 'app-search-form', | ||||
| @ -22,6 +23,7 @@ export class SearchFormComponent implements OnInit { | ||||
|   typeaheadSearchFn: ((text: Observable<string>) => Observable<readonly any[]>); | ||||
| 
 | ||||
|   searchForm: FormGroup; | ||||
|   isMobile = (window.innerWidth <= 767.98); | ||||
|   @Output() searchTriggered = new EventEmitter(); | ||||
| 
 | ||||
|   regexAddress = /^([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})$/; | ||||
| @ -33,6 +35,8 @@ export class SearchFormComponent implements OnInit { | ||||
|   focus$ = new Subject<string>(); | ||||
|   click$ = new Subject<string>(); | ||||
| 
 | ||||
|   formatterFn = (address: string) => this.shortenStringPipe.transform(address, this.isMobile ? 33 : 40); | ||||
| 
 | ||||
|   constructor( | ||||
|     private formBuilder: FormBuilder, | ||||
|     private router: Router, | ||||
| @ -40,6 +44,7 @@ export class SearchFormComponent implements OnInit { | ||||
|     private stateService: StateService, | ||||
|     private electrsApiService: ElectrsApiService, | ||||
|     private relativeUrlPipe: RelativeUrlPipe, | ||||
|     private shortenStringPipe: ShortenStringPipe, | ||||
|   ) { } | ||||
| 
 | ||||
|   ngOnInit() { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user