const Init = require("./init"); const Times = require("../public/times"); class Confirm extends Init { constructor(coin) { const method = "confirm"; super(coin, method); } isPositiveInteger(num) { return Number.isInteger(num) && num > 0; } // 查询当前所有满足查验要求的报块,即 <= 最高成熟高度 且 状态为待定(0)的报块 async query_need_update_data(mature_height) { try { const sql = `SELECT height FROM ${this.coin}_blkreportprofitv2 WHERE height <= ? AND state = ?;`; const data = await this.distribution.exec(sql, [mature_height, 0]); if (!data || data.length === 0) { console.log(`${mature_height}高度之前暂无需要更新的报块`); return false; } return data.map(item => item.height); } catch (err) { throw err; } } // 查询当前最高成熟高度,即当前最新高度 - MAX_MATURE async query_maxture_height() { try { if(this.coin !== "alph"){ const now_height = await this.node.getblockcount(); const max_height = Number(now_height) - this.MAX_MATURE; if (!this.isPositiveInteger(max_height)) { console.log(`当前节点最大高度为${now_height}, 当前成熟高度为${max_height}`); return false; } else { return max_height; } } else { const now = Date.now().valueOf() const max_mature_time = now - this.MAX_MATURE * 60 * 1000 const ymd = Times.utcTime(max_mature_time) const sql = `SELECT MAX(height) AS max_height FROM alph_blkreportprofitv2 WHERE date <= ? AND state = ?;` const data = await this.distribution.exec(sql, [ymd, 0]) if(!data[0]){ console.log(`alph当前时间没有需要更新的成熟区块`); return false } else { return data[0].max_height } } } catch (err) { throw err; } } // 通过报块地址,校验高度是否为本矿池报块 async verify_block(height) { try { return await this.node.verify_block(height, this.REPORT_ADDRESS); } catch (err) { throw err; } } // 根据校验通过和校验失败的高度更新blkreportprofit表,1为成功,2为失败 async update_blkreporprofit_state(suc_heights, err_heights) { try { const sql = `UPDATE ${this.coin}_blkreportprofitv2 SET state = ? WHERE height IN (?);`; if (err_heights.length === 0 && suc_heights.length !== 0) { // 只有 suc_heights 更新 await this.distribution.exec_transaction(sql, [1, suc_heights]); } else if (err_heights.length !== 0 && suc_heights.length === 0) { // 只有 err_heights 更新 await this.distribution.exec_transaction(sql, [2, err_heights]); } else if (err_heights.length !== 0 && suc_heights.length !== 0) { // 同时更新 suc_heights 和 err_heights await Promise.all([ this.distribution.exec_transaction(sql, [1, suc_heights]), this.distribution.exec_transaction(sql, [2, err_heights]), ]); } return; } catch (err) { throw err; } } /** * 1,查验区块链最高成熟高度 * 2,查验blk表中所有<=最高成熟高度 且 状态为待定(0)的区块 * 3,遍历这些区块高度,并通过node.verify方法校验 * 4,将校验通过(正常报块)和校验不通过(孤块)分为两组 * 5,将正常报块组的状态改为1,将孤块组状态改为2 * @returns */ async main() { try { const mature_max_height = await this.query_maxture_height(); if (!mature_max_height) { return; } const need_update_heights = await this.query_need_update_data(mature_max_height); if (!need_update_heights) { return; } const suc_heights = []; const err_heights = []; for (let item of need_update_heights) { const verify_result = await this.verify_block(item); if (!verify_result) { err_heights.push(item); } else { suc_heights.push(item); } } // if(err_heights.length === 0 && need_update_heights.length !== 0){ // console.log(`${mature_max_height}之前有新报块,且无孤块`); // } else if(err_heights.length !== 0 && need_update_heights.length === 0){ // console.log(`${mature_max_height}之前有新报块,但这些报块都是孤块`); // } else if(err_heights.length !== 0 && need_update_heights.length !== 0){ // console.log(`${mature_max_height}之前有新报块,且其中有孤块`); // } await this.update_blkreporprofit_state(suc_heights, err_heights); return } catch (err) { throw err; } } } module.exports = Confirm