aozhiwei f6cff25b5f 1
2022-03-30 01:34:02 +08:00

173 lines
4.7 KiB
JavaScript

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.savedFirstBlockNumber = false;
this.firstBlockNumber = 0;
this.initedBlockNumber = false;
this.initBlockNumber = 0;
this.currBlockNumber = 0;
this.refreshCond = new sync.Cond();
this.lastRefreshTime = utils.getUtcTime();
this.actived = false;
this.lockTimes = 0;
}
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.handleRevert = true;
this.web3.eth.accounts.wallet.add(metamgr.getPrivateKey());
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.serializeBlockNumber.bind(this), 1000);
setTimeout(this.serializeFirstBlockNumber.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();
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);
}
}
async serializeBlockNumber() {
const logClass = 'serializeBlockNumber';
while (true) {
log.info(util.format('%s currBlockNumber:%s firstBlockNumber:%s actived:%s',
logClass,
this.getCurrBlockNumber(),
this.firstBlockNumber,
this.actived
));
dbhelper.insert('t_block_number',
[
['block_number', this.getCurrBlockNumber()],
['createtime', utils.getUtcTime()],
['modifytime', utils.getUtcTime()],
]);
await utils.sleep(1000 * 10);
}
}
async serializeFirstBlockNumber() {
const logClass = 'serializeFirstBlockNumber';
while (!this.savedFirstBlockNumber) {
try {
if (this.initedBlockNumber) {
const {err, row} = await dbhelper.ormSelectOne(
't_parameter',
[
['name', 'first_block_number']
]);
if (err) {
throw err;
} else {
if (row) {
this.savedFirstBlockNumber = true;
this.firstBlockNumber = '' + row['value'];
} else {
const err = await dbhelper.insert(
't_parameter',
[
['name', 'first_block_number'],
['value', this.initBlockNumber],
]
);
if (err) {
throw err;
}
}
}
}
} catch(e) {
log.warning(util.format('%s err:%s',
logClass,
e
));
}
await utils.sleep(1000 * 1);
}
}
isComfirmed(blockNumber) {
const logClass = 'isComfirmed';
try {
return Number(blockNumber) + 6 < Number(this.getCurrBlockNumber());
} catch (e) {
log.warning(util.format('%s err:%s',
logClass,
e
));
}
return false;
}
getCurrBlockNumber() {
return this.currBlockNumber;
}
async lock() {
while (this.lockTimes > 0) {
await utils.sleep(100);
}
++this.lockTimes;
}
async unLock() {
--this.lockTimes;
}
async getFirstBlockNumber() {
while (!this.savedFirstBlockNumber) {
await utils.sleep(1000 * 1);
}
return this.firstBlockNumber;
}
}
module.exports = new BlockChain();