aozhiwei 4483bce588 1
2022-04-16 11:02:30 +08:00

306 lines
8.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const util = require('util');
const utils = require('./utils');
const db = require("./db");
const dbhelper = require("./dbhelper");
const bchelper = require("./bchelper");
const log = require("./log");
const dblog = require("./dblog");
const bc = require('./blockchain');
const metamgr = require('./metamgr');
const C = require('./C');
class Present {
constructor(presentDb) {
this.presentDb = presentDb;
}
async start() {
const logClass = 'present.start';
try {
await this.mint();
} catch (err) {
log.error(logClass + ':' + err);
}
}
async mint() {
const logClass = 'present.mint';
await this.internalMint();
await this.updateDbMustBeSuccess(
logClass,
[
['done', 1]
]);
}
async internalMint() {
const logClass = 'present.internalMint';
if (!this.presentDb['bc_mint_itemid']) {
return;
}
if (!this.getMintMethod()){
return;
}
const getPrepareBlockNumber = () => {
return this.presentDb['bc_mint_prepare_block_number'];
};
const setPrepareBlockNumber = async (logClass, blockNumber) => {
await this.updateDbMustBeSuccess(
logClass,
[
['bc_mint_prepare_block_number', blockNumber],
]
);
};
const getSuccessBlockNumber = () => {
return this.presentDb['bc_mint_success_block_number'];
};
const setSuccessBlockNumber = async (logClass, blockNumber) => {
await this.updateDbMustBeSuccess(
logClass,
[
['bc_mint_success_block_number', blockNumber],
]
);
};
const getSyncCount = () => {
return this.presentDb['bc_mint_count'];
};
const eventFilter = {
tokenId: this.getTokenId()
};
const methodArgs = [
this.presentDb['account'],
this.getTokenId()
];
const onSyncSuccess = async (logClass, event) => {
const nowTime = utils.getUtcTime();
const blockNumber = bchelper.extractEventBlockNumber(event);
const txHash = bchelper.extractEventTxHash(event);
await this.updateDbMustBeSuccess(
logClass,
[
['bc_mint_count', this.presentDb['bc_mint_count'] + 1],
['bc_mint_time', nowTime],
['bc_mint_success_block_number', blockNumber],
['bc_mint_txhash', txHash],
]
);
};
const onConfirmed = async (logClass) => {
const nowTime = utils.getUtcTime();
await this.updateDbMustBeSuccess(
logClass,
[
['bc_minted', 1],
['bc_mint_confirm_time', nowTime]
]
);
};
const exec = new bchelper.ContractExecutor();
exec.instanceName = 'factoryInstance';
exec.suspend = this.suspend.bind(this);
exec.getLogKey = this.getTokenId.bind(this);
exec.getLogData = this.getPresentDb.bind(this);
exec.getPrepareBlockNumber = getPrepareBlockNumber;
exec.setPrepareBlockNumber = setPrepareBlockNumber;
exec.getSuccessBlockNumber = getSuccessBlockNumber;
exec.setSuccessBlockNumber = setSuccessBlockNumber;
exec.getSyncCount = getSyncCount;
exec.searchLogClass = 'mint.search';
exec.eventName = 'TokenMinted';
exec.eventFilter = eventFilter;
exec.syncLogClass = 'mint.sync';
exec.methodName = this.getMintMethod();
exec.methodArgs = methodArgs;
exec.syncDbLogClass = 'mint.sync';
exec.onSyncSuccess = onSyncSuccess;
exec.onConfirmed = onConfirmed;
exec.init();
const ok = await exec.execute();
if (!ok) {
await this.suspend(logClass, 'mint error');
}
await this.dbMint();
}
async dbMint() {
const logClass = 'dbMint';
{
const {err, row} = dbhelper.ormSelectOne(
't_nft',
[
['token_id', this.getTokenId()]
]);
if (err) {
await this.suspend(logClass, err);
return;
}
if (row) {
if (row['owner_address'] != this.presentDb['account']) {
await this.suspend(logClass, 'owner_address error');
return;
}
return;
}
}
{
const nowTime = utils.getUtcTime();
const fieldList = [
['token_id', this.getTokenId()],
['token_type', this.presentDb['bc_mint_token_type']],
['item_id', this.presentDb['bc_mint_itemid']],
['game_id', this.presentDb['game_id']],
['owner_address', this.presentDb['account']],
['createtime', nowTime],
['modifytime', nowTime],
];
const err = await dbhelper.insert(
't_nft',
fieldList);
if (err) {
log.error(util.format('%s insert nft table presentDb:%s fieldList:%s err:%s',
logClass,
utils.jsonEncode(this.presentDb),
utils.jsonEncode(fieldList),
err
)
);
await this.suspend(logClass, err);
} else {
log.info(util.format('%s insert nft table presentDb:%s',
logClass,
utils.jsonEncode(this.presentDb),
utils.jsonEncode(fieldList)
)
);
}
}
}
async updateDbMustBeSuccess(logClass, fieldList) {
const err = await dbhelper.update(
't_present',
[
['idx', this.getIdx()]
],
fieldList);
if (err) {
log.error(util.format('%s updateDbMustBeSuccess presentDb:%s fieldList:%s err:%s',
logClass,
utils.jsonEncode(this.presentDb),
utils.jsonEncode(fieldList),
err
)
);
await this.suspend(logClass + ' updateDbMustBeSuccess ', err);
} else {
fieldList.forEach((val) => {
const name = val[0];
const value = val[1];
this.presentDb[name] = value;
});
log.info(util.format('%s updateDbMustBeSuccess presentDb:%s',
logClass,
utils.jsonEncode(this.presentDb),
utils.jsonEncode(fieldList)
)
);
}
return err;
}
async suspend(logClass, reason) {
/*
挂起等待人工处理
为啥不抛出异常是因为:
如果在调用接口的外部try catch的话那么挂起操作产生的异常会被吞噬,这样非常危险!!!
挂起的操作现在为无限等待不受外部try catch影响。
*/
try {
log.warning(util.format('%s suspend presentDb:%s reason:%s',
logClass,
utils.jsonEncode(this.presentDb),
reason
)
);
await dbhelper.update(
't_present',
[
['idx', this.getIdx()]
],
[
['suspend', 1],
['suspend_reason', '' + reason],
]);
this.presentDb['suspend'] = 1;
this.presentDb['suspend_reason'] = '' + reason;
await dblog.addLog(
'order.suspend',
'',
this.getOrderId(),
utils.jsonEncode(this.getPresentDb()),
'' + reason,
logClass
);
} catch (err) {
log.error(util.format('%s suspend presentDb:%s err:%s',
logClass,
utils.jsonEncode(this.presentDb),
err
)
);
}
while (true) {
await utils.sleep(1000 * 3600 * 24);
}
}
getPresentDb() {
return this.presentDb;
}
getIdx() {
return this.presentDb['idx'];
}
getTokenId() {
return this.presentDb['bc_mint_tokenid'];
}
getMintMethod() {
switch (this.presentDb['bc_mint_token_type']) {
case C.TOKEN_TYPE_HERO:
{
return 'mintHeroTo';
}
break;
case C.TOKEN_TYPE_EQUIP:
{
return 'mintEquipTo';
}
break;
case C.TOKEN_TYPE_CHIP:
{
return 'mintChipTo';
}
break;
default:
{
return '';
break;
}
}
}
};
exports.Present = Present;