const util = require('util'); const Web3 = require('web3'); const metamgr = require('./metamgr'); const utils = require('./utils'); const sync = require("./sync"); const log = require("./log"); const C = require("./C"); const dbhelper = require("./dbhelper"); class BlockChain { constructor() { this.currBlockNumber = 0; this.refreshCond = new sync.Cond(); this.lastRefreshTime = utils.getUtcTime(); this.actived = false; } async initInstance(user, address, jsonUrl) { const json = utils.readJsonFromFile(jsonUrl); return new this.web3.eth.Contract( json.abi, address, { from: user } ); } async init() { this.web3 = new Web3(metamgr.getWeb3Conf()['block_server']); this.web3.eth.accounts.wallet.add(metamgr.getWalletAccount()); for (const data of metamgr.getContracts()) { this[`${data.name}Instance`] = await this.initInstance (metamgr.getUserAddress(), data.address, data.json); } setTimeout(this.refreshBlockNumber.bind(this), 1000 * 0.01); setTimeout(this.increaseBlockNumber.bind(this), 1000); setTimeout(this.serializeBlockNumber.bind(this), 1000); await this.mustBeActive(); utils.emitEvent(C.BC_INITIALIZED_EVENT); } async mustBeActive() { while (!this.actived) { await utils.sleep(1000); } } async refreshBlockNumber() { const logClass = 'refreshBlockNumber'; while (true) { try { this.currBlockNumber = await this.web3.eth.getBlockNumber(); this.actived = true; this.lastRefreshTime = utils.getUtcTime(); } catch (e) { this.actived = false; log.warning(util.format('%s err:%s', logClass, e )); } await this.refreshCond.wait(1000 * 3); } } async increaseBlockNumber() { if (!utils.isOnlineEnv()) { let deltaNumber = 0; while (true) { if (this.mustBeActive()) { deltaNumber += 3; if (deltaNumber > 30) { deltaNumber = 0; } this.currBlockNumber += deltaNumber; } await utils.sleep(1000 * 3); } } } async serializeBlockNumber() { const logClass = 'serializeBlockNumber'; while (true) { log.info(util.format('%s currBlockNumber:%s actived:%s', logClass, this.getCurrBlockNumber(), this.actived )); dbhelper.insert('t_block_number', [ ['block_number', this.getCurrBlockNumber()], ['createtime', utils.getUtcTime()], ['modifytime', utils.getUtcTime()], ]); await utils.sleep(1000 * 10); } } isComfirmed(blockNumber) { const logClass = 'isComfirmed'; try { return blockNumber + 6 < this.getCurrBlockNumber(); } catch (e) { log.warning(util.format('%s err:%s', logClass, e )); } return false; } getCurrBlockNumber() { return this.currBlockNumber; } } module.exports = new BlockChain();