Set bootstrap daemon

This commit is contained in:
everoddandeven 2024-10-31 17:49:21 +01:00
parent d0d374f86c
commit b2d4ff9230
4 changed files with 160 additions and 5 deletions

View file

@ -189,7 +189,6 @@ export class DaemonService {
this.disablingSync = false; this.disablingSync = false;
} }
public async enableSync(): Promise<void> { public async enableSync(): Promise<void> {
this.enablingSync = true; this.enablingSync = true;
@ -217,7 +216,6 @@ export class DaemonService {
this.enablingSync = false; this.enablingSync = false;
} }
private onClose(): void { private onClose(): void {
this.daemonRunning = false; this.daemonRunning = false;
this.stopping = false; this.stopping = false;

View file

@ -73,6 +73,7 @@
</div> </div>
</div> </div>
<div class="tab-pane fade" id="pills-peers" role="tabpanel" aria-labelledby="pills-peers-tab" tabindex="0"> <div class="tab-pane fade" id="pills-peers" role="tabpanel" aria-labelledby="pills-peers-tab" tabindex="0">
<div class="m-3"> <div class="m-3">
<table <table
@ -97,6 +98,7 @@
</table> </table>
</div> </div>
</div> </div>
<div class="tab-pane fade" id="pills-spans" role="tabpanel" aria-labelledby="pills-spans-tab" tabindex="0"> <div class="tab-pane fade" id="pills-spans" role="tabpanel" aria-labelledby="pills-spans-tab" tabindex="0">
<div class="m-3"> <div class="m-3">
<table <table
@ -122,5 +124,89 @@
</table> </table>
</div> </div>
</div> </div>
<div class="tab-pane fade" id="pills-disabled" role="tabpanel" aria-labelledby="pills-disabled-tab" tabindex="0">...</div>
<div class="tab-pane fade" id="pills-bootstrap" role="tabpanel" aria-labelledby="pills-bootstrap-tab" tabindex="0">
<div *ngIf="setBootstrapDaemonError !== ''" class="alert alert-danger d-flex align-items-center justify-content-center text-center" role="alert">
<h4><i class="bi bi-exclamation-triangle m-2"></i></h4>&nbsp;&nbsp;
<div>
{{setBootstrapDaemonError}}
</div>
</div>
<div *ngIf="setBootstrapDaemonSuccess" class="alert alert-success d-flex align-items-center justify-content-center text-center" role="alert">
<h4><i class="bi bi-check-circle m-2"></i></h4>&nbsp;&nbsp;
<div>
Successfully set bootstrap daemon
</div>
</div>
<div class="row d-flex justify-content-center">
@for(card of boostrapCards; track card.header) {
@if(card.loading && !stoppingDaemon) {
<div class="card text-bg-dark m-3 text-center" style="max-width: 18rem;" aria-hidden="true">
<div class="card-header"><strong>{{card.header}}</strong></div>
<div class="card-body">
<p class="card-text placeholder-glow">
<span class="placeholder col-7"></span>
<span class="placeholder col-4"></span>
<span class="placeholder col-4"></span>
<span class="placeholder col-6"></span>
<span class="placeholder col-8"></span>
</p>
</div>
</div>
}
@else if (!stoppingDaemon) {
<div class="card text-bg-dark m-3 text-center" style="max-width: 18rem;">
<div class="card-header"><strong>{{card.header}}</strong></div>
<div class="card-body">
<h5 class="card-title">{{card.content}}</h5>
</div>
</div>
}
}
</div>
<hr class="my-4">
<div class="row g-3">
<h4 class="mb-3">Bootstrap Daemon</h4>
<div class="col-12">
<label for="address" class="form-label">Address</label>
<input type="text" class="form-control" id="address" placeholder="Use 'auto' to enable automatic discovering and switching" [(ngModel)]="bootstrapDaemonAddress" [ngModelOptions]="{standalone: true}">
<small class="text-body-secondary">URL of a bootstrap remote daemon that the connected wallets can use while this daemon is still not fully synced.</small>
</div>
<div class="col-sm-6">
<label for="firstName" class="form-label">Username</label>
<input type="text" class="form-control" id="firstName" placeholder="">
<small class="text-body-secondary">Specify username for the bootstrap daemon login</small>
</div>
<div class="col-sm-6">
<label for="lastName" class="form-label">Password</label>
<input type="password" class="form-control" id="lastName" placeholder="" value="">
<small class="text-body-secondary">Specify password for the bootstrap daemon login</small>
</div>
<div class="col-12">
<label for="bootstrap-daemon-proxy" class="form-label">Proxy</label>
<input type="text" class="form-control" id="bootstrap-daemon-proxy" placeholder="ip:port" [(ngModel)]="bootstrapDaemonProxy" [ngModelOptions]="{standalone: true}">
<small class="text-body-secondary">Socks proxy to use for bootstrap daemon connection</small>
</div>
</div>
<hr class="my-4">
<button *ngIf="!settingBootstrapDaemon" class="w-100 btn btn-primary btn-lg" type="submit" [disabled]="!canSetBootstrapDaemon" (click)="setBootstrapDaemon()">Set Bootstrap Daemon</button>
<button *ngIf="settingBootstrapDaemon" class="w-100 btn btn-primary btn-lg" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Setting Bootstrap Daemon
</button>
</div>
</div> </div>

View file

@ -70,6 +70,7 @@ export class DetailComponent extends BasePageComponent implements AfterViewInit
public get syncDisabledTo(): string { public get syncDisabledTo(): string {
return this.daemonService.settings.syncPeriodTo; return this.daemonService.settings.syncPeriodTo;
} }
//#region Sync Info //#region Sync Info
private get height(): number { private get height(): number {
@ -146,6 +147,39 @@ export class DetailComponent extends BasePageComponent implements AfterViewInit
return `${(height*100/targetHeight).toFixed(2)} %`; return `${(height*100/targetHeight).toFixed(2)} %`;
} }
private get wasBootstrapEverUsed(): boolean {
return this.daemonData.info ? this.daemonData.info.wasBoostrapEverUsed : false;
}
private get _bootstrapDaemonAddress(): string {
return this.daemonData.info ? this.daemonData.info.bootstrapDaemonAddress : 'Not set';
}
private get heightWithoutBootstrap(): number {
return this.daemonData.info ? this.daemonData.info.heightWithoutBootstrap : 0;
}
//#endregion
//#region Bootstrap Daemon
public boostrapCards: SimpleBootstrapCard[] = [];
public settingBootstrapDaemon: boolean = false;
public bootstrapDaemonAddress: string = '';
public bootstrapDaemonUsername: string = '';
public bootstrapDaemonPassword: string = '';
public bootstrapDaemonProxy: string = '';
public setBootstrapDaemonSuccess: boolean = false;
public setBootstrapDaemonError: string = '';
public get canSetBootstrapDaemon(): boolean {
if (this.settingBootstrapDaemon) {
return false;
}
return this.bootstrapDaemonAddress != '';
}
//#endregion //#endregion
public cards: SimpleBootstrapCard[]; public cards: SimpleBootstrapCard[];
@ -161,10 +195,12 @@ export class DetailComponent extends BasePageComponent implements AfterViewInit
this.setLinks([ this.setLinks([
new NavbarLink('pills-home-tab', '#pills-home', 'pills-home', false, 'Overview', true), new NavbarLink('pills-home-tab', '#pills-home', 'pills-home', false, 'Overview', true),
new NavbarLink('pills-peers-tab', '#pills-peers', 'pills-peers', false, 'Peers', true), new NavbarLink('pills-peers-tab', '#pills-peers', 'pills-peers', false, 'Peers', true),
new NavbarLink('pills-spans-tab', '#pills-spans', 'pills-spans', false, 'Spans', true) new NavbarLink('pills-spans-tab', '#pills-spans', 'pills-spans', false, 'Spans', true),
new NavbarLink('pills-bootstrap-tab', '#pills-bootstrap', 'pills-bootstrap', false, 'Bootstrap')
]); ]);
this.cards = this.createCards(); this.cards = this.createCards();
this.boostrapCards = this.createBootstrapCards();
} }
private registerEventListeners(): void { private registerEventListeners(): void {
@ -175,6 +211,7 @@ export class DetailComponent extends BasePageComponent implements AfterViewInit
this.ngZone.run(() => { this.ngZone.run(() => {
this.cards = this.createCards(); this.cards = this.createCards();
this.boostrapCards = this.createBootstrapCards();
this.loadTables(true); this.loadTables(true);
}); });
}); });
@ -187,6 +224,7 @@ export class DetailComponent extends BasePageComponent implements AfterViewInit
const syncInfoRefreshEndSub: Subscription = this.daemonData.syncInfoRefreshEnd.subscribe(() => { const syncInfoRefreshEndSub: Subscription = this.daemonData.syncInfoRefreshEnd.subscribe(() => {
this.cards = this.createCards(); this.cards = this.createCards();
this.boostrapCards = this.createBootstrapCards();
this.loadTables(); this.loadTables();
}); });
@ -252,6 +290,23 @@ export class DetailComponent extends BasePageComponent implements AfterViewInit
return cards; return cards;
} }
private createBootstrapCards(): SimpleBootstrapCard[] {
if (!this.daemonRunning && !this.daemonService.starting) {
return [];
}
const loading = this.daemonData.initializing || this.daemonService.starting || this.daemonData.info === undefined || this.daemonData.syncInfo === undefined;
const cards: SimpleBootstrapCard[] = [];
cards.push(
new SimpleBootstrapCard('Was Bootstrap Ever Used', `${this.wasBootstrapEverUsed}`, loading),
new SimpleBootstrapCard('Boostrap Daemon Address', this._bootstrapDaemonAddress, loading),
new SimpleBootstrapCard('Height Without Bootstrap', `${this.heightWithoutBootstrap}`, loading)
);
return cards;
}
private getPeers(): Connection[] { private getPeers(): Connection[] {
if (!this.daemonData.syncInfo) return []; if (!this.daemonData.syncInfo) return [];
const infos: Connection[] = []; const infos: Connection[] = [];
@ -268,4 +323,20 @@ export class DetailComponent extends BasePageComponent implements AfterViewInit
return this.daemonData.syncInfo.spans; return this.daemonData.syncInfo.spans;
} }
public async setBootstrapDaemon(): Promise<void> {
this.settingBootstrapDaemon = true;
try {
await this.daemonService.setBootstrapDaemon(this.bootstrapDaemonAddress, this.bootstrapDaemonUsername, this.bootstrapDaemonPassword, this.bootstrapDaemonProxy);
this.setBootstrapDaemonError = '';
this.setBootstrapDaemonSuccess = true;
}
catch(error: any) {
this.setBootstrapDaemonSuccess = false;
this.setBootstrapDaemonError = `${error}`;
}
this.settingBootstrapDaemon = false;
}
} }

View file

@ -184,7 +184,7 @@ export class DaemonInfo {
const untrusted: boolean = info.untrusted; const untrusted: boolean = info.untrusted;
const updateAvailable: boolean = info.update_available; const updateAvailable: boolean = info.update_available;
const version: string = info.version; const version: string = info.version;
const wasBoostrapEverUsed: boolean = info.was_boostrap_ever_used; const wasBoostrapEverUsed: boolean = info.was_boostrap_ever_used === true ? true : false;
const whitePeerlistSize: number = info.white_peerlist_size; const whitePeerlistSize: number = info.white_peerlist_size;
const wideCumulativeDifficulty: string = info.wide_cumulative_difficulty; const wideCumulativeDifficulty: string = info.wide_cumulative_difficulty;
const wideDifficulty: string = info.wide_difficulty; const wideDifficulty: string = info.wide_difficulty;