2025-04-10 10:53:16 +00:00
|
|
|
|
const Init = require("./init");
|
2025-04-11 11:59:58 +00:00
|
|
|
|
const Times = require("../public/times");
|
2025-04-10 10:53:16 +00:00
|
|
|
|
|
|
|
|
|
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 {
|
2025-04-11 11:59:58 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
2025-04-10 10:53:16 +00:00
|
|
|
|
} else {
|
2025-04-11 11:59:58 +00:00
|
|
|
|
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
|
|
|
|
|
}
|
2025-04-10 10:53:16 +00:00
|
|
|
|
}
|
|
|
|
|
} 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-04-16 11:01:49 +00:00
|
|
|
|
// 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}之前有新报块,且其中有孤块`);
|
|
|
|
|
// }
|
2025-04-10 10:53:16 +00:00
|
|
|
|
await this.update_blkreporprofit_state(suc_heights, err_heights);
|
|
|
|
|
return
|
|
|
|
|
} catch (err) {
|
|
|
|
|
throw err;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = Confirm
|