2018-05-28 16:54:06 +00:00
const child _process = require ( 'child_process' ) ;
2018-07-27 21:33:50 +00:00
const ProcessWrapper = require ( '../../core/processes/processWrapper' ) ;
2018-05-28 15:50:01 +00:00
const constants = require ( '../../constants' ) ;
2018-05-28 19:37:25 +00:00
const fs = require ( '../../core/fs' ) ;
2018-05-28 15:50:01 +00:00
let swarmProcess ;
class SwarmProcess extends ProcessWrapper {
constructor ( options ) {
super ( ) ;
this . storageConfig = options . storageConfig ;
2018-09-13 12:37:44 +00:00
this . blockchainConfig = options . blockchainConfig ;
2018-05-31 10:18:25 +00:00
this . cors = options . cors ;
2018-07-20 14:54:02 +00:00
this . command = this . storageConfig . swarmPath || 'swarm' ;
2018-10-17 05:14:55 +00:00
this . defaultAccount = options . defaultAccount ;
2018-05-28 15:50:01 +00:00
}
startSwarmDaemon ( ) {
2018-05-28 15:52:49 +00:00
const self = this ;
2018-10-17 05:14:55 +00:00
let bzzaccount ;
let password ;
// use our storage config address/password if we have it
if ( this . storageConfig . account && this . storageConfig . account . address && this . storageConfig . account . password ) {
bzzaccount = this . storageConfig . account . address ;
password = fs . dappPath ( this . storageConfig . account . password ) ;
}
// default to our blockchain config account, or our default account
else if ( ! this . blockchainConfig . isDev &&
this . blockchainConfig . mineWhenNeeded &&
this . blockchainConfig . account &&
( this . blockchainConfig . account . address || this . defaultAccount ) &&
this . blockchainConfig . account . password
) {
// defaultAccount is populated from blockchain_connector.determineDefaultAccount which is either
// config/blockchain.js > account > address or the first address returned from web3.eth.getAccounts
// (usually the default account)
bzzaccount = this . defaultAccount ;
password = fs . dappPath ( this . blockchainConfig . account . password ) ;
console . trace ( ` Swarm account/password falling back to the blockchain account ${ this . defaultAccount } . The account is either specified in config/blockchain.js > account > address or is the first address returned from web3.eth.getAccounts. The password is specified in config/blockchain.js > account > address. ` ) ;
}
else {
2018-05-28 15:50:01 +00:00
return 'Account address and password are needed in the storage config to start the Swarm process' ;
}
2018-05-28 19:37:25 +00:00
2018-09-13 12:37:44 +00:00
const datadir = this . blockchainConfig . datadir || fs . dappPath ( ` .embark/development/datadir ` ) ;
2018-05-28 19:37:25 +00:00
const args = [
2018-09-13 12:37:44 +00:00
'--datadir' , datadir ,
2018-10-17 05:14:55 +00:00
'--bzzaccount' , bzzaccount ,
2018-09-13 12:37:44 +00:00
'--corsdomain' , self . cors . join ( ',' )
] ;
2018-10-17 05:14:55 +00:00
if ( password ) args . push ( '--password' , password ) ;
2018-09-13 12:37:44 +00:00
2018-07-30 20:03:02 +00:00
console . trace ( 'Starting swarm process with arguments: ' + args . join ( ' ' ) ) ;
2018-06-08 14:40:01 +00:00
this . child = child _process . spawn ( this . command , args ) ;
2018-05-28 19:37:25 +00:00
2018-05-30 16:58:32 +00:00
this . child . on ( 'error' , ( err ) => {
2018-05-28 19:37:25 +00:00
err = err . toString ( ) ;
console . error ( 'Swarm error: ' , err ) ;
} ) ;
2018-05-30 16:58:32 +00:00
this . child . stdout . on ( 'data' , ( data ) => {
2018-05-28 19:37:25 +00:00
data = data . toString ( ) ;
console . log ( ` Swarm error: ${ data } ` ) ;
} ) ;
2018-05-28 20:02:44 +00:00
// Swarm logs appear in stderr somehow
2018-05-30 16:58:32 +00:00
this . child . stderr . on ( 'data' , ( data ) => {
2018-05-28 19:37:25 +00:00
data = data . toString ( ) ;
2018-05-24 14:25:32 +00:00
if ( ! self . readyCalled && data . indexOf ( 'Swarm http proxy started' ) > - 1 ) {
self . readyCalled = true ;
self . send ( { result : constants . storage . initiated } ) ;
}
console . log ( 'Swarm: ' + data ) ;
} ) ;
2018-05-30 16:58:32 +00:00
this . child . on ( 'exit' , ( code ) => {
2018-05-24 14:25:32 +00:00
if ( code ) {
console . error ( 'Swarm exited with error code ' + code ) ;
}
} ) ;
2018-05-28 15:50:01 +00:00
}
2018-05-30 16:58:32 +00:00
kill ( ) {
if ( this . child ) {
this . child . kill ( ) ;
}
}
2018-05-28 15:50:01 +00:00
}
process . on ( 'message' , ( msg ) => {
2018-05-30 16:58:32 +00:00
if ( msg === 'exit' ) {
return swarmProcess . kill ( ) ;
}
2018-05-28 15:50:01 +00:00
if ( msg . action === constants . storage . init ) {
swarmProcess = new SwarmProcess ( msg . options ) ;
const error = swarmProcess . startSwarmDaemon ( ) ;
2018-05-24 14:25:32 +00:00
if ( error ) {
swarmProcess . send ( { result : constants . storage . initiated , error } ) ;
}
2018-05-28 15:50:01 +00:00
}
} ) ;