2022-04-21 23:20:50 +08:00

119 lines
2.9 KiB
JavaScript

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;
this.queryLockTimes = 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;
}
async lockQuery() {
while (this.queryLockTimes > 3) {
await utils.sleep(100);
}
++this.queryLockTimes;
}
async unlockQuery() {
--this.queryLockTimes;
}
}
module.exports = new BlockChain();