2017-03-31 11:34:43 +00:00
var shelljs = require ( 'shelljs' ) ;
2016-08-21 14:42:42 +00:00
2017-03-31 11:34:43 +00:00
var fs = require ( '../../core/fs.js' ) ;
2017-02-19 17:51:32 +00:00
2017-03-31 11:34:43 +00:00
var GethCommands = require ( './geth_commands.js' ) ;
2017-02-19 17:51:32 +00:00
2018-01-24 00:36:02 +00:00
/*eslint complexity: ["error", 35]*/
2017-03-31 11:34:43 +00:00
var Blockchain = function ( options ) {
this . blockchainConfig = options . blockchainConfig ;
this . env = options . env || 'development' ;
this . client = options . client ;
2018-05-14 18:32:19 +00:00
this . isDev = options . isDev ;
2017-03-31 11:34:43 +00:00
2018-01-12 22:16:46 +00:00
if ( ( this . blockchainConfig === { } || JSON . stringify ( this . blockchainConfig ) === '{"enabled":true}' ) && this . env !== 'development' ) {
2018-05-08 21:49:46 +00:00
console . log ( "===> " + _ _ ( "warning: running default config on a non-development environment" ) ) ;
2018-01-12 22:16:46 +00:00
}
2017-03-31 11:34:43 +00:00
this . config = {
geth _bin : this . blockchainConfig . geth _bin || 'geth' ,
networkType : this . blockchainConfig . networkType || 'custom' ,
genesisBlock : this . blockchainConfig . genesisBlock || false ,
datadir : this . blockchainConfig . datadir || false ,
mineWhenNeeded : this . blockchainConfig . mineWhenNeeded || false ,
rpcHost : this . blockchainConfig . rpcHost || 'localhost' ,
rpcPort : this . blockchainConfig . rpcPort || 8545 ,
rpcCorsDomain : this . blockchainConfig . rpcCorsDomain || false ,
2018-05-11 14:23:52 +00:00
networkId : this . blockchainConfig . networkId || 1337 ,
2017-03-31 11:34:43 +00:00
port : this . blockchainConfig . port || 30303 ,
nodiscover : this . blockchainConfig . nodiscover || false ,
mine : this . blockchainConfig . mine || false ,
account : this . blockchainConfig . account || { } ,
whisper : ( this . blockchainConfig . whisper === undefined ) || this . blockchainConfig . whisper ,
maxpeers : ( ( this . blockchainConfig . maxpeers === 0 ) ? 0 : ( this . blockchainConfig . maxpeers || 25 ) ) ,
bootnodes : this . blockchainConfig . bootnodes || "" ,
rpcApi : ( this . blockchainConfig . rpcApi || [ 'eth' , 'web3' , 'net' ] ) ,
2018-01-11 13:55:28 +00:00
wsRPC : ( this . blockchainConfig . wsRPC === undefined ) || this . blockchainConfig . wsRPC ,
2017-10-19 22:55:49 +00:00
wsHost : this . blockchainConfig . wsHost || 'localhost' ,
wsPort : this . blockchainConfig . wsPort || 8546 ,
wsOrigins : this . blockchainConfig . wsOrigins || false ,
wsApi : ( this . blockchainConfig . wsApi || [ 'eth' , 'web3' , 'net' , 'shh' ] ) ,
2018-01-17 16:23:32 +00:00
vmdebug : this . blockchainConfig . vmdebug || false ,
2018-01-22 07:54:49 +00:00
targetGasLimit : this . blockchainConfig . targetGasLimit || false ,
light : this . blockchainConfig . light || false ,
2018-05-18 13:34:59 +00:00
fast : this . blockchainConfig . fast || false
2017-03-31 11:34:43 +00:00
} ;
2018-01-12 22:16:46 +00:00
if ( this . blockchainConfig === { } || JSON . stringify ( this . blockchainConfig ) === '{"enabled":true}' ) {
this . config . account = { } ;
2018-03-29 23:23:24 +00:00
this . config . account . password = fs . embarkPath ( "templates/boilerplate/config/development/password" ) ;
this . config . genesisBlock = fs . embarkPath ( "templates/boilerplate/config/development/genesis.json" ) ;
2018-01-12 22:16:46 +00:00
this . config . datadir = fs . embarkPath ( ".embark/development/datadir" ) ;
}
2018-05-09 13:17:48 +00:00
this . client = new options . client ( { config : this . config , env : this . env , isDev : this . isDev } ) ;
2016-08-21 14:42:42 +00:00
} ;
2017-04-02 18:30:00 +00:00
Blockchain . prototype . runCommand = function ( cmd , options ) {
2018-05-08 21:49:46 +00:00
console . log ( _ _ ( "running: %s" , cmd . underline ) . green ) ;
2018-05-08 20:25:48 +00:00
return shelljs . exec ( cmd , options , ( err , stdout , _stderr ) => {
2018-05-14 18:32:19 +00:00
if ( err && this . env === 'development' && stdout . indexOf ( 'Failed to unlock' ) > 0 ) {
2018-05-08 21:49:46 +00:00
console . warn ( '\n' + _ _ ( 'Development blockchain has changed to use the --dev option.' ) . yellow ) ;
console . warn ( _ _ ( 'You can reset your workspace to fix the problem with' ) . yellow + ' embark reset' . cyan ) ;
console . warn ( _ _ ( 'Otherwise, you can change your data directory in blockchain.json (datadir)' ) . yellow ) ;
2018-05-08 20:25:48 +00:00
}
} ) ;
2017-03-31 11:34:43 +00:00
} ;
2016-08-21 14:42:42 +00:00
2017-03-31 11:34:43 +00:00
Blockchain . prototype . run = function ( ) {
var self = this ;
console . log ( "===============================================================================" . magenta ) ;
console . log ( "===============================================================================" . magenta ) ;
2018-05-08 21:49:46 +00:00
console . log ( _ _ ( "Embark Blockchain Using: %s" , this . client . name . underline ) . magenta ) ;
2017-03-31 11:34:43 +00:00
console . log ( "===============================================================================" . magenta ) ;
console . log ( "===============================================================================" . magenta ) ;
2017-12-13 22:58:07 +00:00
if ( ! this . isClientInstalled ( ) ) {
2018-05-08 21:49:46 +00:00
console . log ( _ _ ( "could not find {{geth_bin}} command; is {{client_name}} installed or in the PATH?" , { geth _bin : this . config . geth _bin , client _name : this . client . name } ) . green ) ;
2017-12-13 22:58:07 +00:00
return ;
}
2018-05-08 20:25:48 +00:00
let address = '' ;
2018-05-09 13:17:48 +00:00
if ( ! this . isDev ) {
2018-05-08 20:25:48 +00:00
address = this . initChainAndGetAddress ( ) ;
}
2017-03-31 11:34:43 +00:00
this . client . mainCommand ( address , function ( cmd ) {
2017-04-02 18:30:00 +00:00
self . runCommand ( cmd , { async : true } ) ;
2017-03-31 11:34:43 +00:00
} ) ;
} ;
2016-08-21 14:42:42 +00:00
2017-12-13 22:58:07 +00:00
Blockchain . prototype . isClientInstalled = function ( ) {
let versionCmd = this . client . determineVersion ( ) ;
let result = this . runCommand ( versionCmd ) ;
if ( result . output === undefined || result . output . indexOf ( "not found" ) >= 0 ) {
return false ;
}
return true ;
} ;
2017-03-31 11:34:43 +00:00
Blockchain . prototype . initChainAndGetAddress = function ( ) {
var address = null , result ;
// ensure datadir exists, bypassing the interactive liabilities prompt.
this . datadir = '.embark/' + this . env + '/datadir' ;
fs . mkdirpSync ( this . datadir ) ;
2018-05-17 19:32:57 +00:00
// copy mining script
fs . copySync ( fs . embarkPath ( "js" ) , ".embark/" + this . env + "/js" , { overwrite : true } ) ;
2017-03-31 11:34:43 +00:00
// check if an account already exists, create one if not, return address
result = this . runCommand ( this . client . listAccountsCommand ( ) ) ;
2017-06-18 11:16:11 +00:00
if ( result . output === undefined || result . output . match ( /{(\w+)}/ ) === null || result . output . indexOf ( "Fatal" ) >= 0 ) {
2018-05-08 21:49:46 +00:00
console . log ( _ _ ( "no accounts found" ) . green ) ;
2017-03-31 11:34:43 +00:00
if ( this . config . genesisBlock ) {
2018-05-08 21:49:46 +00:00
console . log ( _ _ ( "initializing genesis block" ) . green ) ;
2017-03-31 11:34:43 +00:00
result = this . runCommand ( this . client . initGenesisCommmand ( ) ) ;
2017-03-30 11:12:39 +00:00
}
2016-08-21 14:42:42 +00:00
2017-03-31 11:34:43 +00:00
result = this . runCommand ( this . client . newAccountCommand ( ) ) ;
address = result . output . match ( /{(\w+)}/ ) [ 1 ] ;
} else {
2018-05-08 21:49:46 +00:00
console . log ( _ _ ( "already initialized" ) . green ) ;
2017-03-31 11:34:43 +00:00
address = result . output . match ( /{(\w+)}/ ) [ 1 ] ;
}
return address ;
} ;
2018-05-18 13:34:59 +00:00
var BlockchainClient = function ( blockchainConfig , client , env , isDev ) {
2018-05-18 17:27:01 +00:00
// TODO add other clients at some point
2017-03-31 11:34:43 +00:00
if ( client === 'geth' ) {
2018-05-18 13:34:59 +00:00
return new Blockchain ( { blockchainConfig , client : GethCommands , env , isDev } ) ;
2017-03-31 11:34:43 +00:00
} else {
throw new Error ( 'unknown client' ) ;
2016-08-21 14:42:42 +00:00
}
2017-03-31 11:34:43 +00:00
} ;
2016-08-21 14:42:42 +00:00
module . exports = BlockchainClient ;