/ lib / modules / blockchain_process / simulator.js
simulator.js
 1  const path = require('path');
 2  const pkgUp = require('pkg-up');
 3  let shelljs = require('shelljs');
 4  let proxy = require('./proxy');
 5  const Ipc = require('../../core/ipc');
 6  const constants = require('../../constants.json');
 7  const {defaultHost, dockerHostSwap} = require('../../utils/host');
 8  const fs = require('../../core/fs.js');
 9  
10  class Simulator {
11    constructor(options) {
12      this.blockchainConfig = options.blockchainConfig;
13      this.logger = options.logger;
14    }
15  
16    run(options) {
17      let cmds = [];
18  
19      const ganache_main = require.resolve('ganache-cli', {paths: fs.embarkPath('node_modules')});
20      const ganache_json = pkgUp.sync(path.dirname(ganache_main));
21      const ganache_root = path.dirname(ganache_json);
22      const ganache_bin = require(ganache_json).bin;
23      let ganache;
24      if (typeof ganache_bin === 'string') {
25        ganache = path.join(ganache_root, ganache_bin);
26      } else {
27        ganache = path.join(ganache_root, ganache_bin['ganache-cli']);
28      }
29  
30      let useProxy = this.blockchainConfig.proxy || false;
31      let host = (dockerHostSwap(options.host || this.blockchainConfig.rpcHost) || defaultHost);
32      let port = (options.port || this.blockchainConfig.rpcPort || 8545);
33      port = parseInt(port, 10) + (useProxy ? constants.blockchain.servicePortOnProxy : 0);
34  
35      cmds.push("-p " + port);
36      cmds.push("-h " + host);
37      cmds.push("-a " + (options.numAccounts || 10));
38      cmds.push("-e " + (options.defaultBalance || 100));
39      cmds.push("-l " + (options.gasLimit || 8000000));
40  
41      // adding mnemonic only if it is defined in the blockchainConfig or options
42      let simulatorMnemonic = this.blockchainConfig.simulatorMnemonic || options.simulatorMnemonic;
43      if (simulatorMnemonic) {
44        cmds.push("--mnemonic \"" + (simulatorMnemonic) +"\"");
45      }
46  
47      // as ganache-cli documentation explains, the simulatorAccounts configuration overrides a mnemonic
48      let simulatorAccounts = this.blockchainConfig.simulatorAccounts || options.simulatorAccounts;
49      if (simulatorAccounts && simulatorAccounts.length > 0) {
50        let web3 = new (require('web3'))();
51        let AccountParser = require('../../utils/accountParser.js');
52        let parsedAccounts = AccountParser.parseAccountsConfig(simulatorAccounts, web3, this.logger);
53        parsedAccounts.forEach((account) => {
54          let cmd = '--account="' + account.privateKey + ','+account.hexBalance + '"';
55          cmds.push(cmd);
56        });
57      }
58  
59      // adding blocktime only if it is defined in the blockchainConfig or options
60      let simulatorBlocktime = this.blockchainConfig.simulatorBlocktime || options.simulatorBlocktime;
61      if (simulatorBlocktime) {
62        cmds.push("-b \"" + (simulatorBlocktime) +"\"");
63      }
64  
65      // Setting up network id for simulator from blockchainConfig or options.
66      // Otherwise ganache-cli would make random network id.
67      let networkId = this.blockchainConfig.networkId || options.networkId;
68      if (networkId) { // Don't handle networkId=="0" because it is not a valid networkId for ganache-cli.
69        cmds.push("--networkId " + networkId);
70      }
71  
72      const programName = 'ganache-cli';
73      const program = ganache;
74      console.log(`running: ${programName} ${cmds.join(' ')}`);
75      shelljs.exec(`${program} ${cmds.join(' ')}`, {async : true});
76  
77      if(useProxy){
78        let ipcObject = new Ipc({ipcRole: 'client'});
79        proxy.serve(ipcObject, host, port, false);
80      }
81    }
82  }
83  
84  module.exports = Simulator;