UNPKG

int-cli

Version:

INT is the new generation of bottom-up created system of IoT and blockchain

181 lines (180 loc) 6.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = require("path"); const fs = require("fs-extra"); const process = require("process"); const error_code_1 = require("./error_code"); const logger_util_1 = require("./lib/logger_util"); class ChainCreator { constructor(options) { this.m_instances = new Map(); this.m_logger = logger_util_1.initLogger(options); this.m_networkCreator = options.networkCreator; } get networkCreator() { return this.m_networkCreator; } registerChainType(consesus, instance) { this.m_instances.set(consesus, instance); } get logger() { return this.m_logger; } _getTypeInstance(typeOptions) { let ins = this.m_instances.get(typeOptions.consensus); if (!ins) { this.m_logger.error(`chain creator has no register consensus named ${typeOptions.consensus}`); return undefined; } return ins; } async createGenesis(packagePath, dataDir, genesisOptions, externalHandler = false) { if (!path.isAbsolute(dataDir)) { dataDir = path.join(process.cwd(), dataDir); } if (!path.isAbsolute(packagePath)) { packagePath = path.join(process.cwd(), packagePath); } fs.ensureDirSync(dataDir); if (externalHandler) { let configPath = path.join(packagePath, 'config.json'); try { let _config = fs.readJSONSync(configPath); _config['handler'] = path.join(packagePath, _config['handler']); fs.writeJSONSync(path.join(dataDir, 'config.json'), _config, { spaces: 4, flag: 'w' }); } catch (e) { this.m_logger.error(`load ${configPath} failed for`, e); } } else { fs.copySync(packagePath, dataDir); } let cmir = await this.createMinerInstance(dataDir); if (cmir.err) { return { err: cmir.err }; } let lcr = this._loadConfig(dataDir); if (lcr.err) { return { err: lcr.err }; } let err = await cmir.miner.create(genesisOptions); if (err) { return { err }; } return { err: error_code_1.ErrorCode.RESULT_OK, miner: cmir.miner }; } _loadConfig(dataDir) { let configPath = path.join(dataDir, 'config.json'); let constConfig; try { constConfig = fs.readJsonSync(configPath); } catch (e) { this.m_logger.error(`can't get config from package ${dataDir} for ${e.message}`); return { err: error_code_1.ErrorCode.RESULT_EXCEPTION }; } if (!constConfig['handler']) { this.m_logger.error(`can't get handler from package ${dataDir}/config.json`); return { err: error_code_1.ErrorCode.RESULT_EXCEPTION }; } let handlerPath = constConfig['handler']; if (!path.isAbsolute(handlerPath)) { handlerPath = path.join(process.cwd(), handlerPath); } // 先判断启动的路径里面是否包含 node_modules,如果有,则为命令行启动,需要替换掉 handler.js 的加载路径 let dirPath = __dirname; if (dirPath.indexOf('node_modules') !== -1) { handlerPath = path.join(__dirname, '../../', constConfig['handler']); } let typeOptions = constConfig['type']; if (!typeOptions || !typeOptions.consensus || !typeOptions.features) { this.m_logger.error(`invalid type from package ${dataDir}`); return { err: error_code_1.ErrorCode.RESULT_EXCEPTION }; } let handler = this._loadHandler(handlerPath, typeOptions); if (!handler) { return { err: error_code_1.ErrorCode.RESULT_EXCEPTION }; } let globalOptions = constConfig['global']; if (!globalOptions) { globalOptions = {}; } return { err: error_code_1.ErrorCode.RESULT_OK, config: { handler, typeOptions, globalOptions } }; } _loadHandler(handlerPath, typeOptions) { let instance = this._getTypeInstance(typeOptions); if (!instance) { return undefined; } let handler = instance.newHandler(this, typeOptions); try { // 兼容VSCode调试器和命令行环境,win32下handlerPath的盘符需要和process.cwd返回的盘符大小写一致 // VScode环境下,cwd返回小写盘符,命令行环境下,cwd返回小写盘符 let cwdPath = process.cwd().split(':', 2); if (cwdPath.length === 2) { const isLower = cwdPath[0] >= 'a' && cwdPath[0] <= 'z'; let pathsplitter = handlerPath.split(':', 2); if (pathsplitter.length === 2) { pathsplitter[0] = isLower ? pathsplitter[0].toLowerCase() : pathsplitter[0].toUpperCase(); } handlerPath = pathsplitter.join(':'); } let handlerMod = require(handlerPath); handlerMod.registerHandler(handler); } catch (e) { console.error(`handler error: ${e.message}`); return undefined; } return handler; } async createMinerInstance(dataDir) { if (!path.isAbsolute(dataDir)) { dataDir = path.join(process.cwd(), dataDir); } let lcr = this._loadConfig(dataDir); if (lcr.err) { return { err: lcr.err }; } let instance = this._getTypeInstance(lcr.config.typeOptions); if (!instance) { return { err: error_code_1.ErrorCode.RESULT_INVALID_TYPE }; } let miner = instance.newMiner(this, dataDir, lcr.config); let err = await miner.initComponents(); if (err) { return { err }; } return { err: error_code_1.ErrorCode.RESULT_OK, miner, globalOptions: lcr.config.globalOptions }; } async createChainInstance(dataDir, options) { if (!path.isAbsolute(dataDir)) { dataDir = path.join(process.cwd(), dataDir); } let lcr = this._loadConfig(dataDir); if (lcr.err) { return { err: lcr.err }; } let instance = this._getTypeInstance(lcr.config.typeOptions); if (!instance) { return { err: error_code_1.ErrorCode.RESULT_INVALID_TYPE }; } let chain = instance.newChain(this, dataDir, lcr.config); if (options.initComponents) { let err = await chain.initComponents({ readonly: options.readonly }); if (err) { return { err }; } } return { err: error_code_1.ErrorCode.RESULT_OK, chain }; } } exports.ChainCreator = ChainCreator;