Browse Source

Merge pull request #220 from SuperNETorg/v0.24

V0.24
pkg_automation_electrum
pbca26 7 years ago
committed by GitHub
parent
commit
7aaae18dab
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      main.js
  2. 1
      package.json
  3. 16
      routes/appConfig.js
  4. 51
      routes/shepherd/daemonControl.js
  5. 1
      routes/shepherd/dashboardUpdate.js
  6. 4
      routes/shepherd/electrum/auth.js
  7. 15
      routes/shepherd/electrum/keys.js
  8. 183
      routes/shepherd/quitDaemon.js
  9. 2
      routes/shepherd/rpc.js
  10. 2
      version

3
main.js

@ -476,7 +476,8 @@ function createWindow(status) {
let _appClosingInterval; let _appClosingInterval;
if (!Object.keys(shepherd.coindInstanceRegistry).length) { if (!Object.keys(shepherd.coindInstanceRegistry).length ||
!appConfig.stopNativeDaemonsOnQuit) {
closeApp(); closeApp();
} else { } else {
createAppCloseWindow(); createAppCloseWindow();

1
package.json

@ -38,6 +38,7 @@
"fix-path": "^2.1.0", "fix-path": "^2.1.0",
"fs-extra": "^1.0.0", "fs-extra": "^1.0.0",
"graceful-fs": "^4.1.11", "graceful-fs": "^4.1.11",
"js-sha256": "^0.7.1",
"nodejs-aes256": "^1.0.1", "nodejs-aes256": "^1.0.1",
"portscanner": "^2.1.1", "portscanner": "^2.1.1",
"ps-node": "^0.1.5", "ps-node": "^0.1.5",

16
routes/appConfig.js

@ -15,6 +15,9 @@ const appConfig = {
walletUnlockTimeout: 3600, walletUnlockTimeout: 3600,
}, },
cliStopTimeout: 1000, cliStopTimeout: 1000,
disableKomododDownModal: false,
failedRPCAttemptsThreshold: 10,
stopNativeDaemonsOnQuit: true,
}, },
schema: { schema: {
host: { host: {
@ -95,6 +98,19 @@ const appConfig = {
cliStopTimeout: { cliStopTimeout: {
display: true, display: true,
displayName: 'CLI stop timeout', displayName: 'CLI stop timeout',
info: 'Timeout between consequent CLI stop commands',
type: 'number',
},
stopNativeDaemonsOnQuit: {
display: true,
displayName: 'Stop native daemons on app quit',
info: 'If set to false agama will run in detached coin daemon mode',
type: 'boolean',
},
failedRPCAttemptsThreshold: {
display: true,
displayName: 'Failed RPC connect attempts threshold',
info: 'Number of allowed consequent RPC connect failures before the app marks native coin daemon as not running properly',
type: 'number', type: 'number',
}, },
}, },

51
routes/shepherd/daemonControl.js

@ -1,3 +1,5 @@
const spawn = require('child_process').spawn;
module.exports = (shepherd) => { module.exports = (shepherd) => {
const getConf = (flock, coind) => { const getConf = (flock, coind) => {
let DaemonConfPath = ''; let DaemonConfPath = '';
@ -135,7 +137,8 @@ module.exports = (shepherd) => {
// check if komodod instance is already running // check if komodod instance is already running
shepherd.portscanner.checkPortStatus(_port, '127.0.0.1', (error, status) => { shepherd.portscanner.checkPortStatus(_port, '127.0.0.1', (error, status) => {
// Status is 'open' if currently in use or 'closed' if available // Status is 'open' if currently in use or 'closed' if available
if (status === 'closed') { if (status === 'closed' ||
!shepherd.appConfig.stopNativeDaemonsOnQuit) {
// start komodod via exec // start komodod via exec
const _customParamDict = { const _customParamDict = {
silent: '&', silent: '&',
@ -169,25 +172,33 @@ module.exports = (shepherd) => {
if (!shepherd.kmdMainPassiveMode) { if (!shepherd.kmdMainPassiveMode) {
let _arg = `${coindACParam}${data.ac_options.join(' ')}${_customParam}`; let _arg = `${coindACParam}${data.ac_options.join(' ')}${_customParam}`;
_arg = _arg.trim().split(' '); _arg = _arg.trim().split(' ');
shepherd.execFile(`${shepherd.komododBin}`, _arg, {
maxBuffer: 1024 * 1000000 // 1000 mb
}, (error, stdout, stderr) => {
shepherd.writeLog(`stdout: ${stdout}`);
shepherd.writeLog(`stderr: ${stderr}`);
if (error !== null) { if (!shepherd.appConfig.stopNativeDaemonsOnQuit) {
shepherd.log(`exec error: ${error}`); spawn(shepherd.komododBin, _arg, {
shepherd.writeLog(`exec error: ${error}`); stdio: 'ignore', // piping all stdio to /dev/null
detached: true,
if (error.toString().indexOf('using -reindex') > -1) { }).unref();
shepherd.io.emit('service', { } else {
komodod: { shepherd.execFile(`${shepherd.komododBin}`, _arg, {
error: 'run -reindex', maxBuffer: 1024 * 1000000 // 1000 mb
}, }, (error, stdout, stderr) => {
}); shepherd.writeLog(`stdout: ${stdout}`);
shepherd.writeLog(`stderr: ${stderr}`);
if (error !== null) {
shepherd.log(`exec error: ${error}`);
shepherd.writeLog(`exec error: ${error}`);
if (error.toString().indexOf('using -reindex') > -1) {
shepherd.io.emit('service', {
komodod: {
error: 'run -reindex',
},
});
}
} }
} });
}); }
} }
} else { } else {
if (shepherd.kmdMainPassiveMode) { if (shepherd.kmdMainPassiveMode) {
@ -715,6 +726,7 @@ module.exports = (shepherd) => {
.then(RemoveLines) .then(RemoveLines)
.then(CheckConf); .then(CheckConf);
} }
/* /*
* type: POST * type: POST
* params: herd * params: herd
@ -731,7 +743,8 @@ module.exports = (shepherd) => {
shepherd.portscanner.checkPortStatus(_port, '127.0.0.1', (error, status) => { shepherd.portscanner.checkPortStatus(_port, '127.0.0.1', (error, status) => {
// Status is 'open' if currently in use or 'closed' if available // Status is 'open' if currently in use or 'closed' if available
if (status === 'open') { if (status === 'open' &&
shepherd.appConfig.stopNativeDaemonsOnQuit) {
if (!skipError) { if (!skipError) {
shepherd.log(`komodod service start error at port ${_port}, reason: port is closed`); shepherd.log(`komodod service start error at port ${_port}, reason: port is closed`);
shepherd.writeLog(`komodod service start error at port ${_port}, reason: port is closed`); shepherd.writeLog(`komodod service start error at port ${_port}, reason: port is closed`);

1
routes/shepherd/dashboardUpdate.js

@ -269,6 +269,7 @@ module.exports = (shepherd) => {
0 0
]; ];
} }
return new shepherd.Promise((resolve, reject) => { return new shepherd.Promise((resolve, reject) => {
_bitcoinRPC( _bitcoinRPC(
_coin, _coin,

4
routes/shepherd/electrum/auth.js

@ -5,7 +5,7 @@ module.exports = (shepherd) => {
let keys; let keys;
if (req.body.seed.length === 52 && if (req.body.seed.length === 52 &&
req.body.seed[0] === 'U' && req.body.seed.indexOf(' ') === -1 &&
req.body.seed.match(/^[a-zA-Z0-9]*$/)) { req.body.seed.match(/^[a-zA-Z0-9]*$/)) {
let key = shepherd.bitcoinJS.ECPair.fromWIF(req.body.seed, shepherd.electrumJSNetworks.komodo); let key = shepherd.bitcoinJS.ECPair.fromWIF(req.body.seed, shepherd.electrumJSNetworks.komodo);
keys = { keys = {
@ -13,7 +13,7 @@ module.exports = (shepherd) => {
pub: key.getAddress(), pub: key.getAddress(),
}; };
} else { } else {
keys = shepherd.seedToWif(req.body.seed, shepherd.findNetworkObj(_abbr), req.body.iguana); keys = shepherd.seedToWif(req.body.seed, shepherd.findNetworkObj(_abbr), req.body.iguana, req.body.old);
} }
shepherd.electrumKeys[_abbr] = { shepherd.electrumKeys[_abbr] = {

15
routes/shepherd/electrum/keys.js

@ -1,6 +1,15 @@
const sha256 = require('js-sha256');
module.exports = (shepherd) => { module.exports = (shepherd) => {
shepherd.seedToWif = (seed, network, iguana) => { shepherd.seedToWif = (seed, network, iguana, old) => {
const bytes = shepherd.sha256(seed, { asBytes: true }); let bytes;
if (old) {
bytes = shepherd.sha256(seed, { asBytes: true });
} else {
const hash = sha256.create().update(seed);
bytes = hash.array();
}
if (iguana) { if (iguana) {
bytes[0] &= 248; bytes[0] &= 248;
@ -23,6 +32,8 @@ module.exports = (shepherd) => {
key.compressed = true; key.compressed = true;
// shepherd.log(`seed: ${seed}`, true);
// shepherd.log(`network ${network}`, true);
// shepherd.log(`seedtowif priv key ${key.privateWif}`, true); // shepherd.log(`seedtowif priv key ${key.privateWif}`, true);
// shepherd.log(`seedtowif pub key ${key.publicAddress}`, true); // shepherd.log(`seedtowif pub key ${key.publicAddress}`, true);

183
routes/shepherd/quitDaemon.js

@ -6,72 +6,145 @@ module.exports = (shepherd) => {
shepherd.lockDownAddCoin = true; shepherd.lockDownAddCoin = true;
for (let key in shepherd.coindInstanceRegistry) { for (let key in shepherd.coindInstanceRegistry) {
const chain = key !== 'komodod' ? key : null; if (shepherd.appConfig.stopNativeDaemonsOnQuit) {
let _coindQuitCmd = shepherd.komodocliBin; const chain = key !== 'komodod' ? key : null;
let _coindQuitCmd = shepherd.komodocliBin;
// any coind // any coind
if (shepherd.nativeCoindList[key.toLowerCase()]) { if (shepherd.nativeCoindList[key.toLowerCase()]) {
_coindQuitCmd = `${shepherd.coindRootDir}/${key.toLowerCase()}/${shepherd.nativeCoindList[key.toLowerCase()].bin.toLowerCase()}-cli`; _coindQuitCmd = `${shepherd.coindRootDir}/${key.toLowerCase()}/${shepherd.nativeCoindList[key.toLowerCase()].bin.toLowerCase()}-cli`;
} }
if (key === 'CHIPS') { if (key === 'CHIPS') {
_coindQuitCmd = shepherd.chipscliBin; _coindQuitCmd = shepherd.chipscliBin;
} }
const execCliStop = () => { const execCliStop = () => {
let _arg = []; let _arg = [];
if (chain && if (chain &&
!shepherd.nativeCoindList[key.toLowerCase()] && key !== 'CHIPS') { !shepherd.nativeCoindList[key.toLowerCase()] && key !== 'CHIPS') {
_arg.push(`-ac_name=${chain}`); _arg.push(`-ac_name=${chain}`);
if (shepherd.appConfig.dataDir.length) { if (shepherd.appConfig.dataDir.length) {
_arg.push(`-datadir=${shepherd.appConfig.dataDir + (key !== 'komodod' ? '/' + key : '')}`); _arg.push(`-datadir=${shepherd.appConfig.dataDir + (key !== 'komodod' ? '/' + key : '')}`);
}
} else if (key === 'komodod' && shepherd.appConfig.dataDir.length) {
_arg.push(`-datadir=${shepherd.appConfig.dataDir}`);
} }
} else if (key === 'komodod' && shepherd.appConfig.dataDir.length) {
_arg.push(`-datadir=${shepherd.appConfig.dataDir}`);
}
_arg.push('stop'); _arg.push('stop');
shepherd.execFile(`${_coindQuitCmd}`, _arg, (error, stdout, stderr) => { shepherd.execFile(`${_coindQuitCmd}`, _arg, (error, stdout, stderr) => {
shepherd.log(`stdout: ${stdout}`); shepherd.log(`stdout: ${stdout}`);
shepherd.log(`stderr: ${stderr}`); shepherd.log(`stderr: ${stderr}`);
if (stdout.indexOf('EOF reached') > -1 ||
stderr.indexOf('EOF reached') > -1 ||
(error && error.toString().indexOf('Command failed') > -1 && !stderr) || // win "special snowflake" case
stdout.indexOf('connect to server: unknown (code -1)') > -1 ||
stderr.indexOf('connect to server: unknown (code -1)') > -1) {
delete shepherd.coindInstanceRegistry[key];
clearInterval(coindExitInterval[key]);
}
// workaround for AGT-65 if (stdout.indexOf('EOF reached') > -1 ||
const _port = shepherd.assetChainPorts[key]; stderr.indexOf('EOF reached') > -1 ||
setTimeout(() => { (error && error.toString().indexOf('Command failed') > -1 && !stderr) || // win "special snowflake" case
shepherd.portscanner.checkPortStatus(_port, '127.0.0.1', (error, status) => { stdout.indexOf('connect to server: unknown (code -1)') > -1 ||
// Status is 'open' if currently in use or 'closed' if available stderr.indexOf('connect to server: unknown (code -1)') > -1) {
if (status === 'closed') { delete shepherd.coindInstanceRegistry[key];
delete shepherd.coindInstanceRegistry[key]; clearInterval(coindExitInterval[key]);
clearInterval(coindExitInterval[key]); }
}
});
}, 100);
if (error !== null) {
shepherd.log(`exec error: ${error}`);
}
setTimeout(() => { // workaround for AGT-65
shepherd.killRogueProcess(key === 'CHIPS' ? 'chips-cli' : 'komodo-cli'); const _port = shepherd.assetChainPorts[key];
}, 100); setTimeout(() => {
}); shepherd.portscanner.checkPortStatus(_port, '127.0.0.1', (error, status) => {
} // Status is 'open' if currently in use or 'closed' if available
if (status === 'closed') {
delete shepherd.coindInstanceRegistry[key];
clearInterval(coindExitInterval[key]);
}
});
}, 100);
if (error !== null) {
shepherd.log(`exec error: ${error}`);
}
setTimeout(() => {
shepherd.killRogueProcess(key === 'CHIPS' ? 'chips-cli' : 'komodo-cli');
}, 100);
});
}
execCliStop();
coindExitInterval[key] = setInterval(() => {
execCliStop(); execCliStop();
}, timeout); coindExitInterval[key] = setInterval(() => {
execCliStop();
}, timeout);
} else {
delete shepherd.coindInstanceRegistry[key];
}
} }
} }
shepherd.post('/coind/stop', (req, res) => {
const _chain = req.body.chain;
let _coindQuitCmd = shepherd.komodocliBin;
let _arg = [];
if (_chain) {
_arg.push(`-ac_name=${_chain}`);
if (shepherd.appConfig.dataDir.length) {
_arg.push(`-datadir=${shepherd.appConfig.dataDir + (_chain ? '/' + _chain : '')}`);
}
} else if (!_chain && shepherd.appConfig.dataDir.length) {
_arg.push(`-datadir=${shepherd.appConfig.dataDir}`);
}
console.log(JSON.stringify(shepherd.coindInstanceRegistry, null, '\t'));
_arg.push('stop');
shepherd.execFile(`${_coindQuitCmd}`, _arg, (error, stdout, stderr) => {
shepherd.log(`stdout: ${stdout}`);
shepherd.log(`stderr: ${stderr}`);
if (stdout.indexOf('EOF reached') > -1 ||
stderr.indexOf('EOF reached') > -1 ||
(error && error.toString().indexOf('Command failed') > -1 && !stderr) || // win "special snowflake" case
stdout.indexOf('connect to server: unknown (code -1)') > -1 ||
stderr.indexOf('connect to server: unknown (code -1)') > -1) {
delete shepherd.coindInstanceRegistry[_chain ? _chain : 'komodo'];
const obj = {
msg: 'success',
result: 'result',
};
res.end(JSON.stringify(obj));
} else {
if (stdout.indexOf('Komodo server stopping') > -1) {
delete shepherd.coindInstanceRegistry[_chain ? _chain : 'komodo'];
const obj = {
msg: 'success',
result: 'result',
};
res.end(JSON.stringify(obj));
} else {
const obj = {
msg: 'error',
result: 'result',
};
res.end(JSON.stringify(obj));
}
}
});
});
shepherd.post('/coins/remove', (req, res) => {
const _chain = req.body.chain;
delete shepherd.coindInstanceRegistry[_chain ? _chain : 'komodo'];
const obj = {
msg: 'success',
result: 'result',
};
res.end(JSON.stringify(obj));
});
return shepherd; return shepherd;
}; };

2
routes/shepherd/rpc.js

@ -74,8 +74,8 @@ module.exports = (shepherd) => {
} else { } else {
const _mode = req.body.payload.mode === 'passthru' ? 'passthru' : 'default'; const _mode = req.body.payload.mode === 'passthru' ? 'passthru' : 'default';
const _chain = req.body.payload.chain === 'KMD' ? null : req.body.payload.chain; const _chain = req.body.payload.chain === 'KMD' ? null : req.body.payload.chain;
let _cmd = req.body.payload.cmd;
const _params = req.body.payload.params ? ` ${req.body.payload.params}` : ''; const _params = req.body.payload.params ? ` ${req.body.payload.params}` : '';
let _cmd = req.body.payload.cmd;
if (!shepherd.rpcConf[_chain]) { if (!shepherd.rpcConf[_chain]) {
shepherd.getConf(req.body.payload.chain === 'KMD' || !req.body.payload.chain && shepherd.kmdMainPassiveMode ? 'komodod' : req.body.payload.chain); shepherd.getConf(req.body.payload.chain === 'KMD' || !req.body.payload.chain && shepherd.kmdMainPassiveMode ? 'komodod' : req.body.payload.chain);

2
version

@ -1,3 +1,3 @@
version=0.2.0.23a version=0.2.0.24a
type=e-beta type=e-beta
minversion=0.2.0.2 minversion=0.2.0.2
Loading…
Cancel
Save