173 lines
4.7 KiB
JavaScript
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();
|