const util = require('util'); const Web3 = require('web3'); const utils = require('j7/utils'); const event = require('j7/event'); const sync = require("j7/sync"); const log = require("j7/log"); const metaFactory = require('./metadata/factory'); const C = require("./C"); class BlockChain { constructor() { this.actived = false; this.currBlockNumber = 0; this.refreshCond = new sync.Cond(); this.lastRefreshTime = utils.getUtcTime(); this.firstBlockNumber = -1; this.netId = 0; setTimeout(this.refreshBlockNumber.bind(this), 1000 * 0.01); } 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(metaFactory.getWeb3Conf()['block_server']); this.web3.eth.handleRevert = true; for (const data of metaFactory.getContracts()) { this[`${data.name}Instance`] = await this.initInstance (metaFactory.getUserAddress(), data.address, data.json); } event.emitEvent(C.BC_INITIALIZED_EVENT); } async mustBeActive() { while (!this.actived) { await utils.sleep(1000); } } async getNetId() { return await this.web3.eth.getChainId(); } async refreshBlockNumber() { const logClass = 'refreshBlockNumber'; while (true) { try { this.currBlockNumber = await this.web3.eth.getBlockNumber(); this.actived = true; this.lastRefreshTime = utils.getUtcTime(); if (!this.initedBlockNumber) { this.initedBlockNumber = true; this.initBlockNumber = this.currBlockNumber; } } catch (e) { this.actived = false; log.warning(util.format('%s err:%s', logClass, e )); } await this.refreshCond.wait(1000 * 3); } } getCurrBlockNumber() { return this.currBlockNumber; } async getFirstBlockNumber() { while (this.firstBlockNumber < 0) { const {err, conn} = await app.getDbConn('MarketDb0'); if (err) { await utils.sleep(1000 + utils.randRange(500, 1500)); continue; } try { const {err, row} = await conn.ormSelectOne( 't_parameter', [ ['name', 'first_block_number'] ] ); if (!err && row) { this.firstBlockNumber = Number(row['value']); } } catch (e) { } finally { conn.release(); } await utils.sleep(5000 + utils.randRange(500, 1500)); } return this.firstBlockNumber; } } module.exports = new BlockChain();