const util = require('util'); const utils = require('./utils'); const dbhelper = require("./dbhelper"); const log = require("./log"); const dblog = require("./dblog"); const bc = require('./blockchain'); const C = require('./C'); class ContractExecutor { constructor() { this.instanceName = ''; this.eventName = ''; this.eventFilter = null; this.searchLogClass = ''; this.onSearchSuccess = null; this.searchGetBlockNumber = null; this.doSuspend = null; this.syncLogClass = ''; this.isSynced = null; this.syncMethodName = ''; this.syncMethodArgs = []; this.syncResetState = null; this.syncGetBlockNumber = null; } async execute() { let tryCount = 0; do { await this.sync(); const confirmed = await this.confirm(); if (confirmed) { return; } ++tryCount; await utils.sleep(utils.randRange(1500, 4000)); } while (tryCount < 3); } async sync() { if (!this.isSynced()) { const found = await this.bcSearch(); if (!found) { const ok = await this.bcSync(); if (!ok) { this.doSuspend(); return; } } } } async confirm() { while (true) { if (bc.isComfirmed(this.syncGetBlockNumber())) { const found = await this.bcSearch(); return found; break; } await utils.sleep(1000 * 3); } return false; } async bcSearch() { if (this.searchGetBlockNumber() <= 0) { return false; } let events = []; while (true) { try { const fromBlock = Math.max(this.searchGetBlockNumber() - 1000, 0); events = await bc[this.InstanceName].getPastEvents( this.eventName, { fromBlock: fromBlock, toBlock: fromBlock + 5000 - 1, filter: this.eventFilter }); break; } catch (err) { log.warning( util.format('%s getPastEvents orderDb:%s err:%s', this.searchLogClass, utils.jsonEncode(this.getOrderDb()), err )); } await utils.sleep(1000 * 3); } if (events.length > 0) { const blockNumber = events[0]['blockNumber']; if (!blockNumber) { await this.doSuspend(this.searchLogClass, 'blocNumber is empty'); return; } this.onSearchSuccess(events[0]); } return events.length > 0; } async bcSync() { return true; } }; exports.ContractExecutor = ContractExecutor;