import * as plugins from './bobcat.plugins'; import * as interfaces from './interfaces'; /** * maps to an individual bobcat miner */ export class Bobcat { // STATIC public static minerAuthObject = { headers: { Authorization: 'Basic ' + Buffer.from('bobcat:miner').toString('base64') } } public static async createFromNetworkAddress (networkAddressArg: string) { const newBobcat = new Bobcat(networkAddressArg); try { await plugins.smartpromise.timeoutAndContinue(newBobcat.checkMinerStatus()); await plugins.smartpromise.timeoutAndContinue(newBobcat.gatherMinerDetails()); } catch (err) { console.log('initial adding completed with errors'); } return newBobcat; } // INSTANCE public networkAddress: string; public latestStatus: interfaces.IMinerStatus; public latestMinerDetails: interfaces.IMinerDetailsResponse constructor(networkAddressArg: string) { console.log(`adding bobcat at ${networkAddressArg}`); this.networkAddress = networkAddressArg; } /** * checks the status of the miner */ public async checkMinerStatus () { const response = await plugins.smartrequest.getJson(`http://${this.networkAddress}/status.json`, { timeout: 60000 }); const body: interfaces.IMinerStatus = response.body; this.latestStatus = body; return this.latestStatus; } /** * gathers the miner details */ public async gatherMinerDetails () { const response = await plugins.smartrequest.getJson(`http://${this.networkAddress}/miner.json`, { timeout: 60000 }); const body: interfaces.IMinerDetailsResponse = response.body; this.latestMinerDetails = body; return this.latestMinerDetails; } /** * runs maintenance on the bobcat */ public async runMaintenance () { await plugins.smartpromise.timeoutAndContinue(this.checkMinerStatus()); await plugins.smartdelay.delayFor(10000); await plugins.smartpromise.timeoutAndContinue(this.gatherMinerDetails()); await plugins.smartdelay.delayFor(10000); await plugins.smartpromise.timeoutAndContinue(this.checkMinerStatus()); await plugins.smartdelay.delayFor(10000); await plugins.smartpromise.timeoutAndContinue(this.gatherMinerDetails()); if (this.latestStatus.status === 'Synced' && parseInt(this.latestStatus.gap) > -100 && parseInt(this.latestStatus.gap) < 50) { console.log(`Miner ${this.latestMinerDetails.animal} at ${this.networkAddress} is Synced. ok!`) return; } if (this.latestStatus.status === 'Syncing') { console.log( `Miner ${this.latestMinerDetails.animal} at ${this.networkAddress} is Syncing... ok!` ); return; } if (this.latestStatus.status !== 'Synced') { console.log(`Miner ${this.latestMinerDetails.animal} is not synced. Restarting now!`); try { await this.restart(); return; } catch (err) { } } if (this.latestStatus.status === 'Synced' && parseInt(this.latestStatus.gap) < -100) { console.log(`Miner ${this.latestMinerDetails.animal} is Synced, but strangely ahead of blockchain. Restarting!`); try { await this.restart(); return; } catch (err) { } } console.log(`Looks like miner ${this.latestMinerDetails.animal} is Synced, but does not fall under predefined statuses!`); } /** * triggers a fast resync */ public async triggerFastResync() { const response = await plugins.smartrequest.request(`http://${this.networkAddress}/admin/fastsync`, { method: 'POST', ...Bobcat.minerAuthObject }) } /** * restarts the miner */ public async restart () { console.log(`cooling down before restart`); await plugins.smartdelay.delayFor(10000); const response = await plugins.smartrequest.request(`http://${this.networkAddress}/admin/reboot`, { method: 'POST', timeout: 60000, ...Bobcat.minerAuthObject }); console.log(response.statusCode); } }