multiblock support >8 blocks
This commit is contained in:
parent
e63adbe28b
commit
5429d6f264
@ -5,7 +5,7 @@
|
|||||||
<app-block-overview-multi
|
<app-block-overview-multi
|
||||||
#blockGraph
|
#blockGraph
|
||||||
[isLoading]="false"
|
[isLoading]="false"
|
||||||
[numBlocks]="8"
|
[numBlocks]="numBlocks"
|
||||||
[blockWidth]="blockWidth"
|
[blockWidth]="blockWidth"
|
||||||
[resolution]="resolution"
|
[resolution]="resolution"
|
||||||
[blockLimit]="stateService.blockVSize"
|
[blockLimit]="stateService.blockVSize"
|
||||||
|
@ -10,6 +10,7 @@ import { detectWebGL } from '../../shared/graphs.utils';
|
|||||||
import { animate, style, transition, trigger } from '@angular/animations';
|
import { animate, style, transition, trigger } from '@angular/animations';
|
||||||
import { BytesPipe } from '../../shared/pipes/bytes-pipe/bytes.pipe';
|
import { BytesPipe } from '../../shared/pipes/bytes-pipe/bytes.pipe';
|
||||||
import { BlockOverviewMultiComponent } from '../block-overview-multi/block-overview-multi.component';
|
import { BlockOverviewMultiComponent } from '../block-overview-multi/block-overview-multi.component';
|
||||||
|
import { CacheService } from '../../services/cache.service';
|
||||||
|
|
||||||
function bestFitResolution(min, max, n): number {
|
function bestFitResolution(min, max, n): number {
|
||||||
const target = (min + max) / 2;
|
const target = (min + max) / 2;
|
||||||
@ -47,18 +48,20 @@ interface BlockInfo extends BlockExtended {
|
|||||||
})
|
})
|
||||||
export class EightBlocksComponent implements OnInit, OnDestroy {
|
export class EightBlocksComponent implements OnInit, OnDestroy {
|
||||||
network = '';
|
network = '';
|
||||||
latestBlocks: BlockExtended[] = [];
|
latestBlocks: (BlockExtended | null)[] = [];
|
||||||
|
pendingBlocks: Record<number, ((b: BlockExtended) => void)[]> = {};
|
||||||
isLoadingTransactions = true;
|
isLoadingTransactions = true;
|
||||||
strippedTransactions: { [height: number]: TransactionStripped[] } = {};
|
strippedTransactions: { [height: number]: TransactionStripped[] } = {};
|
||||||
webGlEnabled = true;
|
webGlEnabled = true;
|
||||||
hoverTx: string | null = null;
|
hoverTx: string | null = null;
|
||||||
|
|
||||||
blocksSubscription: Subscription;
|
tipSubscription: Subscription;
|
||||||
cacheBlocksSubscription: Subscription;
|
cacheBlocksSubscription: Subscription;
|
||||||
networkChangedSubscription: Subscription;
|
networkChangedSubscription: Subscription;
|
||||||
queryParamsSubscription: Subscription;
|
queryParamsSubscription: Subscription;
|
||||||
graphChangeSubscription: Subscription;
|
graphChangeSubscription: Subscription;
|
||||||
|
|
||||||
|
height: number = 0;
|
||||||
numBlocks: number = 8;
|
numBlocks: number = 8;
|
||||||
blockIndices: number[] = [...Array(8).keys()];
|
blockIndices: number[] = [...Array(8).keys()];
|
||||||
autofit: boolean = false;
|
autofit: boolean = false;
|
||||||
@ -92,6 +95,7 @@ export class EightBlocksComponent implements OnInit, OnDestroy {
|
|||||||
public stateService: StateService,
|
public stateService: StateService,
|
||||||
private websocketService: WebsocketService,
|
private websocketService: WebsocketService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
|
private cacheService: CacheService,
|
||||||
private bytesPipe: BytesPipe,
|
private bytesPipe: BytesPipe,
|
||||||
) {
|
) {
|
||||||
this.webGlEnabled = this.stateService.isBrowser && detectWebGL();
|
this.webGlEnabled = this.stateService.isBrowser && detectWebGL();
|
||||||
@ -125,18 +129,21 @@ export class EightBlocksComponent implements OnInit, OnDestroy {
|
|||||||
padding: (this.padding || 0) +'px 0px',
|
padding: (this.padding || 0) +'px 0px',
|
||||||
};
|
};
|
||||||
|
|
||||||
if (params.test === 'true') {
|
this.cacheBlocksSubscription = this.cacheService.loadedBlocks$.subscribe((block: BlockExtended) => {
|
||||||
if (this.blocksSubscription) {
|
if (this.pendingBlocks[block.height]) {
|
||||||
this.blocksSubscription.unsubscribe();
|
this.pendingBlocks[block.height].forEach(resolve => resolve(block));
|
||||||
|
delete this.pendingBlocks[block.height];
|
||||||
}
|
}
|
||||||
this.blocksSubscription = (new Subject<BlockExtended[]>()).subscribe((blocks) => {
|
});
|
||||||
this.handleNewBlock(blocks.slice(0, this.numBlocks));
|
|
||||||
});
|
this.tipSubscription?.unsubscribe();
|
||||||
|
if (params.test === 'true') {
|
||||||
this.shiftTestBlocks();
|
this.shiftTestBlocks();
|
||||||
} else if (!this.blocksSubscription) {
|
} else {
|
||||||
this.blocksSubscription = this.stateService.blocks$
|
this.tipSubscription = this.stateService.chainTip$
|
||||||
.subscribe((blocks) => {
|
.subscribe((height) => {
|
||||||
this.handleNewBlock(blocks.slice(0, this.numBlocks));
|
this.height = height;
|
||||||
|
this.handleNewBlock(height);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -153,8 +160,8 @@ export class EightBlocksComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
this.stateService.markBlock$.next({});
|
this.stateService.markBlock$.next({});
|
||||||
if (this.blocksSubscription) {
|
if (this.tipSubscription) {
|
||||||
this.blocksSubscription?.unsubscribe();
|
this.tipSubscription?.unsubscribe();
|
||||||
}
|
}
|
||||||
this.cacheBlocksSubscription?.unsubscribe();
|
this.cacheBlocksSubscription?.unsubscribe();
|
||||||
this.networkChangedSubscription?.unsubscribe();
|
this.networkChangedSubscription?.unsubscribe();
|
||||||
@ -164,32 +171,27 @@ export class EightBlocksComponent implements OnInit, OnDestroy {
|
|||||||
shiftTestBlocks(): void {
|
shiftTestBlocks(): void {
|
||||||
const sub = this.apiService.getBlocks$(this.testHeight).subscribe(result => {
|
const sub = this.apiService.getBlocks$(this.testHeight).subscribe(result => {
|
||||||
sub.unsubscribe();
|
sub.unsubscribe();
|
||||||
this.handleNewBlock(result.slice(0, this.numBlocks));
|
this.handleNewBlock(this.testHeight);
|
||||||
this.testHeight++;
|
this.testHeight++;
|
||||||
clearTimeout(this.testShiftTimeout);
|
clearTimeout(this.testShiftTimeout);
|
||||||
this.testShiftTimeout = window.setTimeout(() => { this.shiftTestBlocks(); }, 10000);
|
this.testShiftTimeout = window.setTimeout(() => { this.shiftTestBlocks(); }, 10000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleNewBlock(blocks: BlockExtended[]): Promise<void> {
|
async handleNewBlock(height: number): Promise<void> {
|
||||||
const readyPromises: Promise<TransactionStripped[]>[] = [];
|
const readyPromises: Promise<TransactionStripped[]>[] = [];
|
||||||
const previousBlocks = this.latestBlocks;
|
const previousBlocks = this.latestBlocks;
|
||||||
|
|
||||||
|
const blocks = await this.loadBlocks(height, this.numBlocks);
|
||||||
|
console.log('loaded ', blocks.length, ' blocks from height ', height);
|
||||||
|
console.log(blocks);
|
||||||
|
|
||||||
const newHeights = {};
|
const newHeights = {};
|
||||||
this.latestBlocks = blocks;
|
this.latestBlocks = blocks;
|
||||||
for (const block of blocks) {
|
for (const block of blocks) {
|
||||||
newHeights[block.height] = true;
|
newHeights[block.height] = true;
|
||||||
if (!this.strippedTransactions[block.height]) {
|
if (!this.strippedTransactions[block.height]) {
|
||||||
readyPromises.push(new Promise((resolve) => {
|
readyPromises.push(this.loadBlockTransactions(block));
|
||||||
const subscription = this.apiService.getStrippedBlockTransactions$(block.id).pipe(
|
|
||||||
catchError(() => {
|
|
||||||
return of([]);
|
|
||||||
}),
|
|
||||||
).subscribe((transactions) => {
|
|
||||||
this.strippedTransactions[block.height] = transactions;
|
|
||||||
subscription.unsubscribe();
|
|
||||||
resolve(transactions);
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Promise.allSettled(readyPromises);
|
await Promise.allSettled(readyPromises);
|
||||||
@ -203,6 +205,39 @@ export class EightBlocksComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async loadBlocks(height: number, numBlocks: number): Promise<BlockExtended[]> {
|
||||||
|
console.log('loading ', numBlocks, ' blocks from height ', height);
|
||||||
|
const promises: Promise<BlockExtended>[] = [];
|
||||||
|
for (let i = 0; i < numBlocks; i++) {
|
||||||
|
this.cacheService.loadBlock(height - i);
|
||||||
|
const cachedBlock = this.cacheService.getCachedBlock(height - i);
|
||||||
|
if (cachedBlock) {
|
||||||
|
promises.push(Promise.resolve(cachedBlock));
|
||||||
|
} else {
|
||||||
|
promises.push(new Promise((resolve) => {
|
||||||
|
if (!this.pendingBlocks[height - i]) {
|
||||||
|
this.pendingBlocks[height - i] = [];
|
||||||
|
}
|
||||||
|
this.pendingBlocks[height - i].push(resolve);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadBlockTransactions(block: BlockExtended): Promise<TransactionStripped[]> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
this.apiService.getStrippedBlockTransactions$(block.id).pipe(
|
||||||
|
catchError(() => {
|
||||||
|
return of([]);
|
||||||
|
}),
|
||||||
|
).subscribe((transactions) => {
|
||||||
|
this.strippedTransactions[block.height] = transactions;
|
||||||
|
resolve(transactions);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
updateBlockGraphs(blocks): void {
|
updateBlockGraphs(blocks): void {
|
||||||
const startTime = performance.now() + 1000 - (this.stagger < 0 ? this.stagger * 8 : 0);
|
const startTime = performance.now() + 1000 - (this.stagger < 0 ? this.stagger * 8 : 0);
|
||||||
if (this.blockGraph) {
|
if (this.blockGraph) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user