const bcutils = require('j7/bcutils'); const utils = require('j7/utils'); const app = require('j7/app'); const log = require('j7/log'); const event = require('j7/event'); const bc = require('../blockchain'); const C = require('../C'); class ExecConfirmOwner { async init(tokenId) { try { this.tryCount = 1; this.tokenId = tokenId; this.nftDb = await this.getNftDb(tokenId); if (!this.nftDb) { return; } this.addTryCount(); await this.doConfirm(); } catch (err) { console.log(err); } finally { this.destory(); } } destory() { event.emitEvent(C.DESTORY_EXEC_CONFIRM_OWNER_EVENT, this.tokenId); } addTryCount() { ++this.tryCount; } async doConfirm() { while (true) { await bc.mustBeActive(); const oldTryCount = this.tryCount; const oldBlockNumber = bc.getCurrBlockNumber(); let oldOwner = await this.getOwner(); while (oldBlockNumber + 8 < bc.getCurrBlockNumber()) { await utils.sleep(1000 + utils.randRange(0, 500)); } await bc.mustBeActive(); const newBlockNumber = bc.getCurrBlockNumber(); let newOwner = await this.getOwner(); if (oldOwner == newOwner) { await this.updateConfirmed(newOwner, oldBlockNumber); if (oldTryCount == this.tryCount) { break; } } await utils.sleep(1000 + utils.randRange(500, 1500)); } } getInstanceName() { switch (this.nftDb['token_type']) { case bcutils.HERO_TYPE: { return 'heroInstance'; } break; case bcutils.EQUIP_TYPE: { return 'equipInstance'; } break; case bcutils.CHIP_TYPE: { return 'chipInstance'; } break; case bcutils.BLIND_BOX_TYPE: { return 'luckboxInstance'; } break; } } async getNftDb(tokenId) { const {err, conn} = await app.getDbConn('MarketDb0'); if (err) { return null; } try { const {err, row} = await conn.ormSelectOne( 't_nft', [ ['token_id', tokenId] ]); return row; } finally { conn.release() } } async getOwner() { const instanceName = this.getInstanceName(); log.info('getOwner:' + instanceName + ' tryCount:' + this.tryCount); while (true) { await bc.lockQuery(); try { let owner = await bc[instanceName].methods.ownerOf(this.tokenId).call(); return owner; } catch (err) { const reason = utils.getVal(err, 'reason'); if (reason == 'ERC721: owner query for nonexistent token') { return ''; } log.error(err); } finally { await bc.unlockQuery(); } await utils.sleep(5000 + utils.randRange(1500, 2500)); } } async updateConfirmed(newOwner, blockNumber) { const {err, conn} = await app.getDbConn('MarketDb0'); if (err) { return; } try { { const {err} = await conn.update( 't_nft', [ ['token_id', this.tokenId] ], [ ['owner_address', bcutils.toNormalAddress(newOwner)], ['confirm_block_number', blockNumber] ]); } { await conn.execScript( 'UPDATE t_nft_transfer SET `owner_confirmed` = 1 WHERE block_number < ?', [ blockNumber ]); } } finally { conn.release() } } } module.exports = ExecConfirmOwner;