src/utils.js
'use strict';
import { read, write } from 'crypto-io-fs';
import { configPath, olivia, network } from './params';
import { encode } from 'bs58';
import CryptoWallet from './lib/wallet';
import chalk from 'chalk';
import { homedir } from 'os';
import { join } from 'path';
if (process.platform === 'win32') {
const readLine = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
readLine.on('SIGINT', () => {
process.emit('SIGINT');
});
};
const APPDATAPATH = (() => {
switch (process.platform) {
case 'win32':
return join(homedir(), 'AppData', 'Roaming', 'Leofcoin', olivia ? 'olivia' : '')
break;
case 'linux':
return join(homedir(), '.leofcoin', olivia ? 'olivia' : '')
break;
case 'darwin':
// TODO: implement darwin path
break;
case 'android':
// TODO: implement android path
// experimental
break;
}
})();
// hardcode debug param for now
process.env.DEBUG = true;
export const debug = (text) => {
if (process.env.DEBUG) {
const stack = new Error().stack;
const caller = stack.split('\n')[2].trim();
console.groupCollapsed(chalk.blue(text));
console.log(caller)
console.groupEnd();
};
};
export const log = text => {
console.log(chalk.cyan(text));
}
export const succes = text => {
console.log(chalk.green(text));
}
export const fail = text => {
console.log(chalk.red(text));
}
export const groupCollapsed = (text, cb) => {
console.groupCollapsed(chalk.gray.bold(text));
cb();
console.groupEnd();
}
/**
* Get hash difficulty
*
* @param hash
* @return {Number}
*/
export const getDifficulty = hash => {
return parseInt(hash.substring(0, 8), 16);
};
export const textlog = async text => {
let content = '';
try {
// content = await read('log');
} catch (e) {
console.log('creating new log file');
}
content += '\n';
content += text;
return
// await write('log', content);
};
export const timeout = (ms = 1000, cb) => {
setTimeout(() => {
cb();
}, ms);
};
export const interval = (cb, ms = 1000) => {
setInterval(() => {
cb();
}, ms);
};
export const hashes = nonce => {
const hashrates = [10, 100, 1000, 10000, 100000, 1000000, 1000000000, 1000000000000, 1000000000000000];
for (let i = hashrates.length; i-- > 0;) {
if (nonce % hashrates[i - 1] === 0) return hashrates[i - 1];
}
return hashrates.filter(hashrate => {
if (nonce % hashrate === 0) return hashrate;
});
};
export const median = array => {
array.sort( function(a,b) {return a - b;} );
var half = Math.floor(array.length/2);
if(array.length % 2)
return array[half];
else
return (array[half-1] + array[half]) / 2.0;
}
let previousDate = Date.now();
let previousMinuteDate = Date.now();
let hashCount = 0;
let timeoutRunning = false;
let rates = []
export const hashLog = nonce => {
if (typeof(hashes(nonce)) === 'number') {
hashCount = hashCount + hashes(nonce);
}
const now = Date.now()
// if (now - previousMinuteDate >= 60000) {
// previousMinuteDate = now;
// const middle = median(rates);
if (now - previousDate >= 1000) {
previousDate = now;
rates[hashCount]
hashCount = 0;
return rates;
}
};
export const config = {
server: {
port: 3030,
host: 'localhost',
},
p2p: {
port: 6001,
peers: [],
},
reward: 150,
peers: []
};
export const newWallet = ( name= 'main') => new Promise(async (resolve, reject) => {
try {
const wallet = new CryptoWallet(network);
wallet.new();
const addresses = JSON.stringify([[name, wallet.public]]);
await write(join(APPDATAPATH, 'wallet.dat'), JSON.stringify([
[name, {private: wallet.private, public: wallet.public}]
]));
await write(join(APPDATAPATH, 'addresses.dat'), addresses);
resolve(wallet.public);
} catch (e) {
console.log(e);
} finally {
}
})
/**
*
*/
export const createNewAddress = (name = Math.random().toString(36).slice(-8)) => new Promise(async (resolve, reject) => {
// create new address
const wallet = new CryptoWallet(network);
wallet.new()
// get local addresses
try {
const walletAddresses = await read(join(APPDATAPATH, 'wallet.dat'), 'json');
const addresses = await read(join(APPDATAPATH, 'addresses.dat'), 'json');
const address = [name, wallet.public];
addresses.push(address);
walletAddresses.push([name, {private: wallet.private, public: wallet.public}])
await write(join(APPDATAPATH, 'wallet.dat'), JSON.stringify(walletAddresses));
await write(join(APPDATAPATH, 'addresses.dat'), JSON.stringify(addresses));
resolve(wallet.public);
} catch (error) {
if (error.code === 'ENOENT') {
const n = await newWallet(name)
resolve(n)
}
else {reject(error)};
}
});
export const networkAddress = async net => {
let address;
console.log(net);
if (net === 'olivia') address = await createNewAddress('main');
else address = await createNewAddress('main');
return address;
};
export const net = () => {
const testnet = 'olivia';
const main = 'leofcoin';
if (process.argv[2] === testnet || process.argv[3] === testnet) {
return testnet;
}
return main;
};
const defaultConfig = async () => {
const address = await networkAddress(network)
console.log(address, 'address');
return {
miner: {
address,
intensity: 1
}
}
};
export const hexFromMultihash = multihash => {
return multihash.toString('hex').substring(4);
}
export const multihashFromHex = hex => {
return encode(new Buffer(`1220${hex}`, 'hex'));
}
// TODO: also check for configfile in the directory where core is run from @AndrewVanardennen
// search for the config file & create new one when needed
export const getUserConfig = new Promise(resolve => {
read(configPath, 'json')
.then(config => resolve(config))
.catch(async error => {
if (error.code !== 'ENOENT') {
console.error(error);
}
resolve(await defaultConfig());
debug('new config file created');
});
});
/**
* allow retry upto "amount" times
* @param {number} amount
*/
export const allowFailureUntillEnough = (func, amount = 5) => new Promise(async (resolve, reject) => {
if (typeof func !== 'function') reject('function undefined');
if (typeof amount !== 'number') reject(`Expected amount to be a typeof Number`);
let count = 0;
for (var i = 0; i < amount; i++) {
try {
await func();
resolve();
} catch (error) {
if (amount === count) reject(error);
}
}
});