Compare commits
6 Commits
e16db3a835
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
614f16a8b6 | ||
|
|
7e63afd621 | ||
|
|
90ae1d1852 | ||
|
|
9fe4d9145a | ||
|
|
2d8675368f | ||
|
|
da5d4ba5bc |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
config/*.conf
|
config/*.conf
|
||||||
|
gitignore
|
||||||
68
README
68
README
@@ -1,68 +0,0 @@
|
|||||||
m2pool app module code
|
|
||||||
|
|
||||||
environment:
|
|
||||||
nodejs v16.10.0 +
|
|
||||||
express
|
|
||||||
axios
|
|
||||||
mysql2
|
|
||||||
ioredis
|
|
||||||
|
|
||||||
if you want to support enx, kas...
|
|
||||||
add environment:
|
|
||||||
kaspa-rpc-client
|
|
||||||
|
|
||||||
### start common example ###
|
|
||||||
node app.js <method> <coin>
|
|
||||||
|
|
||||||
# if you used pm2, you can use this command
|
|
||||||
pm2 start app.js --name <pm2 process name> -- <method> <coin>
|
|
||||||
|
|
||||||
############# pm2 start common #############
|
|
||||||
pm2 start app.js --name nexa-hashratev2 -- hashrate nexa
|
|
||||||
pm2 start app.js --name nexa-reportv2 -- report nexa
|
|
||||||
pm2 start app.js --name nexa-confirm -- confirm nexa
|
|
||||||
pm2 start app.js --name nexa-distributionv2 -- distribution nexa
|
|
||||||
pm2 start app.js --name email -- notice nexa
|
|
||||||
pm2 start app.js --name nexa-balance -- balance nexa
|
|
||||||
|
|
||||||
pm2 start app.js --name grs-hashratev2 -- hashrate grs
|
|
||||||
pm2 start app.js --name grs-reportv2 -- report grs
|
|
||||||
pm2 start app.js --name grs-confirm -- confirm grs
|
|
||||||
pm2 start app.js --name grs-distributionv2 -- distribution grs
|
|
||||||
pm2 start app.js --name grs-balance -- balance grs
|
|
||||||
|
|
||||||
pm2 start app.js --name mona-hashratev2 -- hashrate mona
|
|
||||||
pm2 start app.js --name mona-reportv2 -- report mona
|
|
||||||
pm2 start app.js --name mona-confirm -- confirm mona
|
|
||||||
pm2 start app.js --name mona-distributionv2 -- distribution mona
|
|
||||||
pm2 start app.js --name mona-balance -- balance mona
|
|
||||||
|
|
||||||
pm2 start app.js --name dgbs-hashratev2 -- hashrate dgbs
|
|
||||||
pm2 start app.js --name dgbs-reportv2 -- report dgbs
|
|
||||||
pm2 start app.js --name dgbs-confirm -- confirm dgbs
|
|
||||||
pm2 start app.js --name dgbs-distributionv2 -- distribution dgbs
|
|
||||||
# pm2 start app.js --name dgbs-balance -- balance dgbs
|
|
||||||
|
|
||||||
pm2 start app.js --name dgbq-hashratev2 -- hashrate dgbq
|
|
||||||
pm2 start app.js --name dgbq-reportv2 -- report dgbq
|
|
||||||
pm2 start app.js --name dgbq-confirm -- confirm dgbq
|
|
||||||
pm2 start app.js --name dgbq-distributionv2 -- distribution dgbq
|
|
||||||
# pm2 start app.js --name dgbq-balance -- balance dgbq
|
|
||||||
|
|
||||||
pm2 start app.js --name dgbo-hashratev2 -- hashrate dgbo
|
|
||||||
pm2 start app.js --name dgbo-reportv2 -- report dgbo
|
|
||||||
pm2 start app.js --name dgbo-confirm -- confirm dgbo
|
|
||||||
pm2 start app.js --name dgbo-distributionv2 -- distribution dgbo
|
|
||||||
pm2 start app.js --name dgb-balance -- balance dgbo
|
|
||||||
|
|
||||||
pm2 start app.js --name rxd-hashratev2 -- hashrate rxd
|
|
||||||
pm2 start app.js --name rxd-reportv2 -- report rxd
|
|
||||||
pm2 start app.js --name rxd-confirm -- confirm rxd
|
|
||||||
pm2 start app.js --name rxd-distributionv2 -- distribution rxd
|
|
||||||
pm2 start app.js --name rxd-balance -- balance rxd
|
|
||||||
|
|
||||||
pm2 start app.js --name enx-hashrate -- hashrate enx
|
|
||||||
pm2 start app.js --name enx-report -- report enx
|
|
||||||
|
|
||||||
pm2 start app.js --name alph-report -- report alph
|
|
||||||
pm2 start app.js --name alph-hashrate -- hashrate alph
|
|
||||||
196
README.md
Normal file
196
README.md
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
### start common example ###
|
||||||
|
```
|
||||||
|
node app.js <method> <coin>
|
||||||
|
```
|
||||||
|
|
||||||
|
# if you used pm2, you can use this command
|
||||||
|
```
|
||||||
|
pm2 start app.js --name <pm2 process name> -- <method> <coin>
|
||||||
|
```
|
||||||
|
|
||||||
|
# config like this
|
||||||
|
```
|
||||||
|
// this file please use .conf
|
||||||
|
{
|
||||||
|
"master":{
|
||||||
|
"pooldb":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"sharesdb":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"distribution":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"hashrate":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"users_addresses":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"balance":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"slave":{
|
||||||
|
"pooldb_slave":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"sharesdb_slave":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"redis_options":{
|
||||||
|
"redis1":{
|
||||||
|
"host":"",
|
||||||
|
"port":,
|
||||||
|
"db":,
|
||||||
|
"connectTimeout":
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_options":{
|
||||||
|
"node1":{
|
||||||
|
"rpcUser":"",
|
||||||
|
"rpcPassword":"<alph api-key>",
|
||||||
|
"rpcPort":,
|
||||||
|
"rpcHost":""
|
||||||
|
},
|
||||||
|
"node2":{
|
||||||
|
"rpcUser":"",
|
||||||
|
"rpcPassword":"<alph api-key>",
|
||||||
|
"rpcPort":,
|
||||||
|
"rpcHost":""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"retry_options":{
|
||||||
|
"node":{
|
||||||
|
"max_retries":,
|
||||||
|
"retry_delay":
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"REPORT_ADDRESS":"",
|
||||||
|
"MAX_MATURE":,
|
||||||
|
"distribution_conf":{
|
||||||
|
"PPLNS_SIZE":,
|
||||||
|
"MODEL_PERCENT":{
|
||||||
|
"SCORE":,
|
||||||
|
"PPLNS":,
|
||||||
|
"PROPDIF":
|
||||||
|
},
|
||||||
|
"SCORE_PERCENT":{
|
||||||
|
"HASHRATE":,
|
||||||
|
"STDDEVS":
|
||||||
|
},
|
||||||
|
"POOL_FEE":
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# start examples
|
||||||
|
``` pm2 start common
|
||||||
|
pm2 start app.js --name nexa-hashratev2 -- hashrate nexa
|
||||||
|
pm2 start app.js --name nexa-reportv2 -- report nexa
|
||||||
|
pm2 start app.js --name nexa-confirm -- confirm nexa
|
||||||
|
pm2 start app.js --name nexa-distributionv2 -- distribution nexa
|
||||||
|
pm2 start app.js --name email -- notice nexa
|
||||||
|
pm2 start app.js --name nexa-balance -- balance nexa
|
||||||
|
|
||||||
|
pm2 start app.js --name grs-hashratev2 -- hashrate grs
|
||||||
|
pm2 start app.js --name grs-reportv2 -- report grs
|
||||||
|
pm2 start app.js --name grs-confirm -- confirm grs
|
||||||
|
pm2 start app.js --name grs-distributionv2 -- distribution grs
|
||||||
|
pm2 start app.js --name grs-balance -- balance grs
|
||||||
|
|
||||||
|
pm2 start app.js --name mona-hashratev2 -- hashrate mona
|
||||||
|
pm2 start app.js --name mona-reportv2 -- report mona
|
||||||
|
pm2 start app.js --name mona-confirm -- confirm mona
|
||||||
|
pm2 start app.js --name mona-distributionv2 -- distribution mona
|
||||||
|
pm2 start app.js --name mona-balance -- balance mona
|
||||||
|
|
||||||
|
pm2 start app.js --name dgbs-hashratev2 -- hashrate dgbs
|
||||||
|
pm2 start app.js --name dgbs-reportv2 -- report dgbs
|
||||||
|
pm2 start app.js --name dgbs-confirm -- confirm dgbs
|
||||||
|
pm2 start app.js --name dgbs-distributionv2 -- distribution dgbs
|
||||||
|
|
||||||
|
pm2 start app.js --name dgbq-hashratev2 -- hashrate dgbq
|
||||||
|
pm2 start app.js --name dgbq-reportv2 -- report dgbq
|
||||||
|
pm2 start app.js --name dgbq-confirm -- confirm dgbq
|
||||||
|
pm2 start app.js --name dgbq-distributionv2 -- distribution dgbq
|
||||||
|
|
||||||
|
pm2 start app.js --name dgbo-hashratev2 -- hashrate dgbo
|
||||||
|
pm2 start app.js --name dgbo-reportv2 -- report dgbo
|
||||||
|
pm2 start app.js --name dgbo-confirm -- confirm dgbo
|
||||||
|
pm2 start app.js --name dgbo-distributionv2 -- distribution dgbo
|
||||||
|
pm2 start app.js --name dgb-balance -- balance dgbo
|
||||||
|
|
||||||
|
pm2 start app.js --name rxd-hashratev2 -- hashrate rxd
|
||||||
|
pm2 start app.js --name rxd-reportv2 -- report rxd
|
||||||
|
pm2 start app.js --name rxd-confirm -- confirm rxd
|
||||||
|
pm2 start app.js --name rxd-distributionv2 -- distribution rxd
|
||||||
|
pm2 start app.js --name rxd-balance -- balance rxd
|
||||||
|
|
||||||
|
pm2 start app.js --name enx-hashrate -- hashrate enx
|
||||||
|
pm2 start app.js --name enx-report -- report enx
|
||||||
|
|
||||||
|
pm2 start app.js --name alph-report -- report alph
|
||||||
|
pm2 start app.js --name alph-hashrate -- hashrate alph
|
||||||
|
pm2 start app.js --name alph-confirm -- confirm alph
|
||||||
|
pm2 start app.js --name alph-distribution -- distribution alph
|
||||||
|
pm2 start app.js --name alph-balance -- balance alph
|
||||||
|
```
|
||||||
76
app.js
76
app.js
@@ -1,13 +1,11 @@
|
|||||||
const schedule = require("node-schedule");
|
const schedule = require("node-schedule");
|
||||||
// const executeWithRetry = require("./public/retry")
|
|
||||||
const Times = require("./public/times");
|
const Times = require("./public/times");
|
||||||
const HashRate = require("./src/hashrate");
|
const HashRate = require("./src/hashrate");
|
||||||
const {Report, ReportEnx} = require("./src/report");
|
const { Report, ReportEnx } = require("./src/report");
|
||||||
const Confirm = require("./src/confirm");
|
const Confirm = require("./src/confirm");
|
||||||
const Distribution = require("./src/distribution");
|
const Distribution = require("./src/distribution");
|
||||||
const { Balance, DGBBlance } = require("./src/blanace");
|
const { Balance, DGBBlance } = require("./src/blanace");
|
||||||
const Stats = require("./src/stat");
|
const ClearDBData = require("./src/clear");
|
||||||
const ClearDBData = require("./src/clear")
|
|
||||||
const Notice = require("./src/notice");
|
const Notice = require("./src/notice");
|
||||||
|
|
||||||
const method = process.argv[2];
|
const method = process.argv[2];
|
||||||
@@ -43,8 +41,8 @@ if (method === "hashrate") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (method === "report") {
|
if (method === "report") {
|
||||||
let report
|
let report;
|
||||||
if(coin === "enx"){
|
if (coin === "enx") {
|
||||||
report = new ReportEnx(coin);
|
report = new ReportEnx(coin);
|
||||||
} else {
|
} else {
|
||||||
report = new Report(coin);
|
report = new Report(coin);
|
||||||
@@ -60,40 +58,39 @@ if (method === "report") {
|
|||||||
}, interval);
|
}, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (method === "confirm") {
|
|
||||||
// // schedule.scheduleJob({hour:[1], minute:[30], second:[0]}, async () =>{
|
|
||||||
// // confirm.main();
|
|
||||||
// // })
|
|
||||||
// let interval = 600000;
|
|
||||||
// if (coin === "rxd") {
|
|
||||||
// interval = 1800000;
|
|
||||||
// }
|
|
||||||
// const confirm = new Confirm(coin);
|
|
||||||
// setInterval(() => {
|
|
||||||
// confirm.main();
|
|
||||||
// }, interval);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
if (method === "confirm") {
|
if (method === "confirm") {
|
||||||
|
let interval = 60000;
|
||||||
|
if (coin === "rxd") {
|
||||||
|
interval = 300000;
|
||||||
|
} else if (coin === "nexa") {
|
||||||
|
interval = 120000;
|
||||||
|
}
|
||||||
const confirm = new Confirm(coin);
|
const confirm = new Confirm(coin);
|
||||||
schedule.scheduleJob({hour:[1], minute:[30], second:[0]}, async () =>{
|
setInterval(() => {
|
||||||
confirm.main();
|
confirm.main();
|
||||||
})
|
}, interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if (method === "confirm") {
|
||||||
|
// const confirm = new Confirm(coin);
|
||||||
|
// schedule.scheduleJob({ hour: [1], minute: [30], second: [0] }, async () => {
|
||||||
|
// confirm.main();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
if (method === "distribution") {
|
if (method === "distribution") {
|
||||||
const distribution = new Distribution(coin);
|
const distribution = new Distribution(coin);
|
||||||
schedule.scheduleJob({ hour: [0], minute: [1], second: [0] }, async () => {
|
// schedule.scheduleJob({ hour: [0], minute: [1], second: [0] }, async () => {
|
||||||
const now_ts = Date.now().valueOf();
|
const now_ts = Date.now().valueOf();
|
||||||
const last_ts = now_ts - 1000 * 60 * 60 * 24;
|
const last_ts = now_ts - 1000 * 60 * 60 * 24;
|
||||||
const ymd_now = Times.utcTime(now_ts);
|
const ymd_now = Times.utcTime(now_ts);
|
||||||
const ymd_last = Times.utcTime(last_ts);
|
const ymd_last = Times.utcTime(last_ts);
|
||||||
const end_time = ymd_now.split(" ")[0] + " 00:00:00";
|
const end_time = ymd_now.split(" ")[0] + " 00:00:00";
|
||||||
const start_time = ymd_last.split(" ")[0] + " 00:00:00";
|
const start_time = ymd_last.split(" ")[0] + " 00:00:00";
|
||||||
await distribution.main(start_time, end_time);
|
distribution.main(start_time, end_time);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (method === "balance") {
|
// if (method === "balance") {
|
||||||
@@ -117,7 +114,6 @@ if (method === "distribution") {
|
|||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
if (method === "balance") {
|
if (method === "balance") {
|
||||||
const special_coins = ["dgbo", "dgbs", "dgbq"];
|
const special_coins = ["dgbo", "dgbs", "dgbq"];
|
||||||
let balance;
|
let balance;
|
||||||
@@ -127,38 +123,36 @@ if (method === "balance") {
|
|||||||
balance = new Balance(coin);
|
balance = new Balance(coin);
|
||||||
}
|
}
|
||||||
|
|
||||||
let hour = 4
|
let hour = 4;
|
||||||
if(coin === "rxd"){
|
if (coin === "rxd" || coin === "alph") {
|
||||||
hour = 9
|
hour = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function task(balance) {
|
async function task(balance) {
|
||||||
let count = 0; // 让 count 成为 task 内部变量,避免多个 schedule 共享 count
|
let count = 0; // 让 count 成为 task 内部变量,避免多个 schedule 共享 count
|
||||||
const last_height = await balance.node.getblockcount()
|
const last_height = await balance.node.getblockcount();
|
||||||
while (count < 36) { // 最多执行 36 次 (6小时)
|
while (count < 36) {
|
||||||
|
// 最多执行 36 次 (6小时)
|
||||||
const enable = await balance.query_now_height(last_height);
|
const enable = await balance.query_now_height(last_height);
|
||||||
if (enable) {
|
if (enable) {
|
||||||
await balance.main();
|
const result = await balance.main();
|
||||||
|
if(!result){
|
||||||
console.log(`${coin}转账已完成`);
|
console.log(`${coin}转账已完成`);
|
||||||
return; // 成功执行后退出循环
|
return; // 成功执行后退出循环
|
||||||
}
|
}
|
||||||
|
}
|
||||||
console.log(`等待中... (已等待 ${count * 10} 分钟)`);
|
console.log(`等待中... (已等待 ${count * 10} 分钟)`);
|
||||||
await balance.sleep(1000 * 60 * 10); // 休眠 10 分钟
|
await balance.sleep(1000 * 60 * 10); // 休眠 10 分钟
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
console.log("等待超时,任务结束!");
|
console.log("等待超时,任务结束!");
|
||||||
}
|
}
|
||||||
schedule.scheduleJob({hour: [hour], minute: [10], second: [0]}, async () => {
|
schedule.scheduleJob({ hour: [hour], minute: [10], second: [0] }, async () => {
|
||||||
await task(balance);
|
await task(balance);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (method === "stats") {
|
|
||||||
const stats = new Stats(coin);
|
|
||||||
stats.caculate_user_should_distribution("2024-11-28 00:00:00");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method === "clear") {
|
if (method === "clear") {
|
||||||
const clear = new ClearDBData(coin);
|
const clear = new ClearDBData(coin);
|
||||||
clear
|
clear
|
||||||
@@ -183,7 +177,7 @@ if (method === "clear") {
|
|||||||
|
|
||||||
if (method === "notice") {
|
if (method === "notice") {
|
||||||
const notice = new Notice(coin);
|
const notice = new Notice(coin);
|
||||||
schedule.scheduleJob({hour:[9], minute:[30], second:[0]}, () =>{
|
schedule.scheduleJob({ hour: [9], minute: [30], second: [0] }, () => {
|
||||||
notice.main()
|
notice.main();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
130
config/example.txt
Normal file
130
config/example.txt
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
// this file please use .conf
|
||||||
|
{
|
||||||
|
"master":{
|
||||||
|
"pooldb":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"sharesdb":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"distribution":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"hashrate":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"users_addresses":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"balance":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"slave":{
|
||||||
|
"pooldb_slave":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
},
|
||||||
|
"sharesdb_slave":{
|
||||||
|
"host": "",
|
||||||
|
"user": "",
|
||||||
|
"password": "",
|
||||||
|
"database": "",
|
||||||
|
"port":,
|
||||||
|
"waitForConnections": true,
|
||||||
|
"connectionLimit": 20,
|
||||||
|
"queueLimit": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"redis_options":{
|
||||||
|
"redis1":{
|
||||||
|
"host":"",
|
||||||
|
"port":,
|
||||||
|
"db":,
|
||||||
|
"connectTimeout":
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_options":{
|
||||||
|
"node1":{
|
||||||
|
"rpcUser":"",
|
||||||
|
"rpcPassword":"<alph api-key>",
|
||||||
|
"rpcPort":,
|
||||||
|
"rpcHost":""
|
||||||
|
},
|
||||||
|
"node2":{
|
||||||
|
"rpcUser":"",
|
||||||
|
"rpcPassword":"<alph api-key>",
|
||||||
|
"rpcPort":,
|
||||||
|
"rpcHost":""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"retry_options":{
|
||||||
|
"node":{
|
||||||
|
"max_retries":,
|
||||||
|
"retry_delay":
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"REPORT_ADDRESS":"",
|
||||||
|
"MAX_MATURE":,
|
||||||
|
"distribution_conf":{
|
||||||
|
"PPLNS_SIZE":,
|
||||||
|
"MODEL_PERCENT":{
|
||||||
|
"SCORE":,
|
||||||
|
"PPLNS":,
|
||||||
|
"PROPDIF":
|
||||||
|
},
|
||||||
|
"SCORE_PERCENT":{
|
||||||
|
"HASHRATE":,
|
||||||
|
"STDDEVS":
|
||||||
|
},
|
||||||
|
"POOL_FEE":
|
||||||
|
}
|
||||||
|
}
|
||||||
12
lib/node.js
12
lib/node.js
@@ -481,12 +481,18 @@ class ALPHRPCNode extends HttpNode {
|
|||||||
const coinbaseTx = transactions[transactions.length - 1].unsigned
|
const coinbaseTx = transactions[transactions.length - 1].unsigned
|
||||||
if (coinbaseTx.inputs.length === 0) {
|
if (coinbaseTx.inputs.length === 0) {
|
||||||
const {fixedOutputs} = coinbaseTx
|
const {fixedOutputs} = coinbaseTx
|
||||||
if(fixedOutputs.length === 1){
|
for(let item of fixedOutputs){
|
||||||
const {attoAlphAmount, address } = fixedOutputs[0]
|
const {attoAlphAmount, address } = item
|
||||||
if(address === REPORT_ADDRESS){
|
if(address === REPORT_ADDRESS){
|
||||||
return {height, hash: block_hash, time:Math.trunc(timestamp / 1000), block_reward: Number(attoAlphAmount), block_fees: null };
|
return {height, hash: block_hash, time:Math.trunc(timestamp / 1000), block_reward: BigInt(attoAlphAmount), block_fees: null };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// if(fixedOutputs.length === 1){
|
||||||
|
// const {attoAlphAmount, address } = fixedOutputs[0]
|
||||||
|
// if(address === REPORT_ADDRESS){
|
||||||
|
// return {height, hash: block_hash, time:Math.trunc(timestamp / 1000), block_reward: Number(attoAlphAmount), block_fees: null };
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
} catch(err){
|
} catch(err){
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class Balance extends Init {
|
|||||||
async query_now_height(last_height){
|
async query_now_height(last_height){
|
||||||
try{
|
try{
|
||||||
const [chain_height, [db_height]] = await Promise.all([this.node.getblockcount(), this.query_min_height()])
|
const [chain_height, [db_height]] = await Promise.all([this.node.getblockcount(), this.query_min_height()])
|
||||||
return chain_height > db_height.min_height + this.MAX_MATURE && chain_height > last_height + 2// 在成熟高度基础上再+2高度,防止pool_account转账未更新
|
return chain_height > db_height.min_height + this.MAX_MATURE && chain_height > last_height + 5// 在成熟高度基础上再+2高度,防止pool_account转账未更新
|
||||||
} catch(err){
|
} catch(err){
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ class DGBBlance extends Init {
|
|||||||
try{
|
try{
|
||||||
const sql = `SELECT MAX(max_height) AS max_height FROM wallet_in WHERE coin Like "dgb%" AND state = ?;`
|
const sql = `SELECT MAX(max_height) AS max_height FROM wallet_in WHERE coin Like "dgb%" AND state = ?;`
|
||||||
const [chain_height, [db_height]] = await Promise.all([this.node.getblockcount(), this.distribution.exec(sql, [0])])
|
const [chain_height, [db_height]] = await Promise.all([this.node.getblockcount(), this.distribution.exec(sql, [0])])
|
||||||
return chain_height > db_height.max_height + this.MAX_MATURE && chain_height > last_height + 2
|
return chain_height > db_height.max_height + this.MAX_MATURE && chain_height > last_height + 5
|
||||||
} catch(err){
|
} catch(err){
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
const Init = require("./init");
|
const Init = require("./init");
|
||||||
|
const Times = require("../public/times");
|
||||||
|
|
||||||
class Confirm extends Init {
|
class Confirm extends Init {
|
||||||
constructor(coin) {
|
constructor(coin) {
|
||||||
@@ -28,6 +29,7 @@ class Confirm extends Init {
|
|||||||
// 查询当前最高成熟高度,即当前最新高度 - MAX_MATURE
|
// 查询当前最高成熟高度,即当前最新高度 - MAX_MATURE
|
||||||
async query_maxture_height() {
|
async query_maxture_height() {
|
||||||
try {
|
try {
|
||||||
|
if(this.coin !== "alph"){
|
||||||
const now_height = await this.node.getblockcount();
|
const now_height = await this.node.getblockcount();
|
||||||
const max_height = Number(now_height) - this.MAX_MATURE;
|
const max_height = Number(now_height) - this.MAX_MATURE;
|
||||||
if (!this.isPositiveInteger(max_height)) {
|
if (!this.isPositiveInteger(max_height)) {
|
||||||
@@ -36,6 +38,19 @@ class Confirm extends Init {
|
|||||||
} else {
|
} else {
|
||||||
return max_height;
|
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) {
|
} catch (err) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
@@ -101,13 +116,13 @@ class Confirm extends Init {
|
|||||||
suc_heights.push(item);
|
suc_heights.push(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(err_heights.length === 0 && need_update_heights.length !== 0){
|
// if(err_heights.length === 0 && need_update_heights.length !== 0){
|
||||||
console.log(`${mature_max_height}之前有新报块,且无孤块`);
|
// console.log(`${mature_max_height}之前有新报块,且无孤块`);
|
||||||
} else if(err_heights.length !== 0 && need_update_heights.length === 0){
|
// } else if(err_heights.length !== 0 && need_update_heights.length === 0){
|
||||||
console.log(`${mature_max_height}之前有新报块,但这些报块都是孤块`);
|
// console.log(`${mature_max_height}之前有新报块,但这些报块都是孤块`);
|
||||||
} else if(err_heights.length !== 0 && need_update_heights.length !== 0){
|
// } else if(err_heights.length !== 0 && need_update_heights.length !== 0){
|
||||||
console.log(`${mature_max_height}之前有新报块,且其中有孤块`);
|
// console.log(`${mature_max_height}之前有新报块,且其中有孤块`);
|
||||||
}
|
// }
|
||||||
await this.update_blkreporprofit_state(suc_heights, err_heights);
|
await this.update_blkreporprofit_state(suc_heights, err_heights);
|
||||||
return
|
return
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class Distribution extends Init {
|
|||||||
const result = {};
|
const result = {};
|
||||||
// 计算每个用户的算力占比
|
// 计算每个用户的算力占比
|
||||||
for (let { user, mhs24h } of alluser_mhs24h) {
|
for (let { user, mhs24h } of alluser_mhs24h) {
|
||||||
result[user] = (mhs24h / totalHashrate) * hash_percent;
|
result[user] = Number(((mhs24h / totalHashrate) * hash_percent).toFixed(4));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ class Distribution extends Init {
|
|||||||
|
|
||||||
// 动态获取当前小时
|
// 动态获取当前小时
|
||||||
const currentHour = Number(Times.times()[4]);
|
const currentHour = Number(Times.times()[4]);
|
||||||
if(this.coin === "rxd"){
|
if (this.coin === "rxd") {
|
||||||
if (currentHour >= 9) {
|
if (currentHour >= 9) {
|
||||||
console.log("已超过凌晨 9 点,停止检查。");
|
console.log("已超过凌晨 9 点,停止检查。");
|
||||||
return false;
|
return false;
|
||||||
@@ -196,8 +196,9 @@ class Distribution extends Init {
|
|||||||
}
|
}
|
||||||
const heights = [];
|
const heights = [];
|
||||||
const query_blk_pool_sql = `SELECT height FROM ${table_name} WHERE DATE(date) >= ?;`;
|
const query_blk_pool_sql = `SELECT height FROM ${table_name} WHERE DATE(date) >= ?;`;
|
||||||
const [master_data, slave_data] = await Promise.all([this.pooldb.exec(query_blk_pool_sql, [yMd]), this.pooldb_slave.exec(`SELECT height FROM ${this.coin}_pool_blkstats WHERE DATE(date) >= ?;`, [yMd])])
|
// const [master_data, slave_data] = await Promise.all([this.pooldb.exec(query_blk_pool_sql, [yMd]), this.pooldb_slave.exec(`SELECT height FROM ${this.coin}_pool_blkstats WHERE DATE(date) >= ?;`, [yMd])])
|
||||||
const pool_data = master_data.concat(slave_data);
|
// const pool_data = master_data.concat(slave_data);
|
||||||
|
const pool_data = await this.pooldb.exec(query_blk_pool_sql, [yMd]);
|
||||||
for (let item of pool_data) {
|
for (let item of pool_data) {
|
||||||
heights.push(item.height);
|
heights.push(item.height);
|
||||||
}
|
}
|
||||||
@@ -243,7 +244,7 @@ class Distribution extends Init {
|
|||||||
const sql = `SELECT user, SUM(amount) AS profit FROM wallet_in WHERE coin = ? AND state = ? GROUP BY user;`;
|
const sql = `SELECT user, SUM(amount) AS profit FROM wallet_in WHERE coin = ? AND state = ? GROUP BY user;`;
|
||||||
const data = await this.distributiondb.exec(sql, [this.coin, 2]); // []
|
const data = await this.distributiondb.exec(sql, [this.coin, 2]); // []
|
||||||
if (!data || data.length === 0) {
|
if (!data || data.length === 0) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
const need_update_state = [];
|
const need_update_state = [];
|
||||||
for (let item of data) {
|
for (let item of data) {
|
||||||
@@ -294,7 +295,7 @@ class Distribution extends Init {
|
|||||||
if (!_if) {
|
if (!_if) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const check_result = await this.check_last_data_blk(end_time)
|
const check_result = await this.check_last_data_blk(end_time);
|
||||||
if (!check_result) {
|
if (!check_result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -306,33 +307,39 @@ class Distribution extends Init {
|
|||||||
console.log("users_address:", users_address);
|
console.log("users_address:", users_address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const reward = (BigInt(last_day_reward[0].reward) * BigInt((1 - this.POOL_FEE) * 10000)) / BigInt(10000);
|
||||||
const min_amount = {};
|
const min_amount = {};
|
||||||
const score_ratio = this.score(last_day_mhs24h, 1);
|
const score_ratio = this.score(last_day_mhs24h, 1);
|
||||||
const reward = Number(last_day_reward[0].reward) * (1 - this.POOL_FEE);
|
|
||||||
const max_height = last_day_reward[0].max_height;
|
const max_height = last_day_reward[0].max_height;
|
||||||
let should_out_date; // 实际转账时间
|
let should_out_date; // 实际转账时间
|
||||||
let accuracy; // user保留小数位数,100为2位,以此类推
|
let accuracy; // user保留小数位数,100为2位,以此类推
|
||||||
let count // pool_account 保留小数位数
|
let count; // pool_account 保留小数位数
|
||||||
if (this.coin === "nexa") {
|
if (this.coin === "nexa") {
|
||||||
should_out_date = Times.utcTime(new Date(end_time).valueOf() + 1000 * 60 * 60 * 24 * 7);
|
should_out_date = Times.utcTime(new Date(end_time).valueOf() + 1000 * 60 * 60 * 24 * 7);
|
||||||
accuracy = 100;
|
accuracy = 100;
|
||||||
count = 2
|
count = 2;
|
||||||
} else if (this.coin === "rxd") {
|
} else if (this.coin === "rxd") {
|
||||||
accuracy = 100;
|
accuracy = 100;
|
||||||
should_out_date = end_time;
|
should_out_date = end_time;
|
||||||
count = 2
|
count = 2;
|
||||||
|
} else if (this.coin === "alph") {
|
||||||
|
accuracy = 0;
|
||||||
|
should_out_date = end_time;
|
||||||
|
count = 0;
|
||||||
} else {
|
} else {
|
||||||
should_out_date = end_time;
|
should_out_date = end_time;
|
||||||
accuracy = 100000000;
|
accuracy = 100000000;
|
||||||
count = 8
|
count = 8;
|
||||||
}
|
}
|
||||||
let user_profit = 0;
|
let user_profit = BigInt(0)
|
||||||
const result = [];
|
const result = [];
|
||||||
let pool_account_address;
|
let pool_account_address;
|
||||||
for (let user in score_ratio) {
|
for (let user in score_ratio) {
|
||||||
const profit = Math.floor(score_ratio[user] * reward * accuracy) / accuracy;
|
// const profit = Math.floor(score_ratio[user] * reward * accuracy) / accuracy;
|
||||||
if(profit === 0){
|
const ratio = Math.round(score_ratio[user] * 10000);
|
||||||
continue
|
const profit = (reward * BigInt(ratio)) / 10000n;
|
||||||
|
if (profit === 0) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
user_profit += profit;
|
user_profit += profit;
|
||||||
for (let item of users_address) {
|
for (let item of users_address) {
|
||||||
|
|||||||
@@ -363,4 +363,39 @@ ON t1.user = t2.user AND t1.miner = t2.miner AND t1.date = t2.max_date;`;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HashRateNew extends Init {
|
||||||
|
constructor(coin) {
|
||||||
|
const method = "distribution";
|
||||||
|
super(coin, method);
|
||||||
|
this.count = 0
|
||||||
|
}
|
||||||
|
async query_blk_detail_table_name() {
|
||||||
|
try{
|
||||||
|
const sql = `SELECT \`from\`, \`to\` FROM ${this.coin}_blk_height_detail WHERE date < NOW() - INTERVAL 5 MINUTE;`
|
||||||
|
const data = await this.sharesdb.exec(sql);
|
||||||
|
let tables = [`${this.coin}_blk_detail`]
|
||||||
|
if(data.length === 0){
|
||||||
|
return tables
|
||||||
|
}
|
||||||
|
for(let item of data){
|
||||||
|
tables.push(`${this.coin}_block_detail_${item.from}_${Math.trunc(item.to - 1)}`)
|
||||||
|
}
|
||||||
|
return tables
|
||||||
|
} catch(err){
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async query_blk_detail(){
|
||||||
|
try{
|
||||||
|
|
||||||
|
} catch(err){
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
module.exports = HashRate
|
module.exports = HashRate
|
||||||
|
|
||||||
|
// SELECT COUNT(*)
|
||||||
|
// FROM information_schema.tables
|
||||||
|
// WHERE table_schema = 'alphsharesdb'
|
||||||
|
// AND table_name = 'alph_blk_detail';
|
||||||
@@ -50,7 +50,7 @@ class Report extends Init {
|
|||||||
const values = [];
|
const values = [];
|
||||||
for (let item of data) {
|
for (let item of data) {
|
||||||
const { date, height, hash, reward, fees } = item;
|
const { date, height, hash, reward, fees } = item;
|
||||||
values.push(date, height, hash, reward, fees, 0);
|
values.push(date, height, hash, reward.toString(), fees, 0);
|
||||||
sql += `(?,?,?,?,?,?), `;
|
sql += `(?,?,?,?,?,?), `;
|
||||||
}
|
}
|
||||||
sql = sql.slice(0, -2);
|
sql = sql.slice(0, -2);
|
||||||
@@ -78,7 +78,7 @@ class Report extends Init {
|
|||||||
if (check_result) {
|
if (check_result) {
|
||||||
const block = this.node.block(check_result);
|
const block = this.node.block(check_result);
|
||||||
const { height, hash, time, block_reward, block_fees } = block;
|
const { height, hash, time, block_reward, block_fees } = block;
|
||||||
suc_data.push({ date: Times.utcTime(time * 1000), height, hash, reward: block_reward, fees: block_fees });
|
suc_data.push({ date: Times.utcTime(time * 1000), height, hash, reward: block_reward.toString(), fees: block_fees });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (suc_data.length === 0) {
|
if (suc_data.length === 0) {
|
||||||
|
|||||||
112
src/stat.js
112
src/stat.js
@@ -1,112 +0,0 @@
|
|||||||
const Times = require("../public/times");
|
|
||||||
const Init = require("./init");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* earliest date : 2024-11-26 00:00:00
|
|
||||||
*/
|
|
||||||
class Stats extends Init {
|
|
||||||
constructor(coin) {
|
|
||||||
const method = "stats";
|
|
||||||
super(coin, method);
|
|
||||||
}
|
|
||||||
|
|
||||||
async query_pooldb_mhs24h(date) {
|
|
||||||
try {
|
|
||||||
const yMd = Times.utcTime(new Date(date).valueOf() - 1000 * 60 * 60 * 24).split(" ")[0];
|
|
||||||
const table_date = yMd.replace(/\-/g, "");
|
|
||||||
let table = `${this.coin}_miners_stats_${table_date}`;
|
|
||||||
console.log(table);
|
|
||||||
|
|
||||||
const sql = `SELECT user, SUM(mhs24h) AS mhs24h FROM ${table} WHERE date >= ? AND date <= ? GROUP BY user;`;
|
|
||||||
const start = yMd + " 23:55:00";
|
|
||||||
const end = yMd + " 23:59:59";
|
|
||||||
const data = await this.pooldb.exec(sql, [start, end]);
|
|
||||||
if (data.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const result = [];
|
|
||||||
for (let item of data) {
|
|
||||||
const { user, mhs24h } = item;
|
|
||||||
result.push({ user, mhs24h: Number(mhs24h) });
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async query_hashratedb_mhs24h(date) {
|
|
||||||
try {
|
|
||||||
const sql = `SELECT user, SUM(mhs24h) AS mhs24h FROM ${this.coin}_mhsv2 WHERE date = ? GROUP BY user;`;
|
|
||||||
const data = await this.hashratedb.exec(sql, [date]);
|
|
||||||
if (!data || data.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const result = [];
|
|
||||||
for (let item of data) {
|
|
||||||
const { user, mhs24h } = item;
|
|
||||||
result.push({ user, mhs24h: Number(mhs24h) });
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async query_distribution_data(date) {
|
|
||||||
try {
|
|
||||||
const sql = `SELECT user, amount FROM wallet_in WHERE coin = ? AND create_date = ? AND user != "pool_account";`;
|
|
||||||
const data = await this.distribution.exec(sql, [this.coin, date]);
|
|
||||||
if (!data || data.length === 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const result = [];
|
|
||||||
for (let item of data) {
|
|
||||||
const { user, amount } = item;
|
|
||||||
result.push({ user, amount: Number(amount) });
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
caculate_mhs24h_percent(data) {
|
|
||||||
const totalAmount = data.reduce((acc, item) => acc + item.mhs24h, 0);
|
|
||||||
const result = data.map((item) => ({
|
|
||||||
user: item.user,
|
|
||||||
mhs24h: item.mhs24h,
|
|
||||||
percentage: Number((item.mhs24h / totalAmount).toFixed(4)), // 保留两位小数
|
|
||||||
}));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
caculate_distribution_percent(data) {
|
|
||||||
const totalAmount = data.reduce((acc, item) => acc + item.amount, 0);
|
|
||||||
const result = data.map((item) => ({
|
|
||||||
user: item.user,
|
|
||||||
should_receive: Number((item.amount / 0.95).toFixed(8)),
|
|
||||||
actual_receive: item.amount,
|
|
||||||
percentage: Number(((item.amount / totalAmount)).toFixed(4)), // 保留两位小数
|
|
||||||
}));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
async caculate_user_should_distribution(date) {
|
|
||||||
try {
|
|
||||||
const [user_mhs24h, user_distribution] = await Promise.all([this.query_hashratedb_mhs24h(date), this.query_distribution_data(date)]);
|
|
||||||
const mhs24h_percent = this.caculate_mhs24h_percent(user_mhs24h)
|
|
||||||
const distribution_percent = this.caculate_distribution_percent(user_distribution)
|
|
||||||
let fees = 0
|
|
||||||
for(let item of distribution_percent){
|
|
||||||
const {user, should_receive, actual_receive, percentage} = item
|
|
||||||
fees += should_receive - actual_receive
|
|
||||||
}
|
|
||||||
console.log(fees);
|
|
||||||
} catch (err) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Stats;
|
|
||||||
116
test/caculate.js
116
test/caculate.js
@@ -1,12 +1,108 @@
|
|||||||
const Times = require('../public/times')
|
const fs = require("fs");
|
||||||
const str = "rxd_miners_stats_20241128"
|
const DBPool = require("../lib/mysql");
|
||||||
|
const Cache = require("../lib/redis");
|
||||||
|
const { NEXARPCNode, GRSRPCNode, MONARPCNode, DGBRPCNode, RXDRPCNode, ALPHRPCNode } = require("../lib/node");
|
||||||
|
|
||||||
let sql = `DROP TABLE IF EXISTS `
|
class Init {
|
||||||
const start = new Date("2024-11-28 00:00:00").valueOf()
|
constructor(coin, method) {
|
||||||
for(let i=0; i<70; i++){
|
this.coin = coin;
|
||||||
const t = Times.utcTime(start + i * 86400000)
|
const config = fs.readFileSync(`../config/${coin}.conf`, "utf-8");
|
||||||
const ymd = t.split(" ")[0].replace(/-/g, "")
|
const { master, slave, redis_options, node_options, distribution_conf, MAX_MATURE, REPORT_ADDRESS } = JSON.parse(config);
|
||||||
sql += ``+ `rxd_miners_stats_${ymd},`
|
const { pooldb, sharesdb, distribution, hashrate, users_addresses, balance } = master;
|
||||||
|
const { pooldb_slave, sharesdb_slave } = slave;
|
||||||
|
const { node1, node2 } = node_options;
|
||||||
|
const { redis1 } = redis_options;
|
||||||
|
const { POOL_FEE } = distribution_conf;
|
||||||
|
const node_map = {
|
||||||
|
mona: MONARPCNode,
|
||||||
|
nexa: NEXARPCNode,
|
||||||
|
grs: GRSRPCNode,
|
||||||
|
dgbs: DGBRPCNode,
|
||||||
|
dgbq: DGBRPCNode,
|
||||||
|
dgbo: DGBRPCNode,
|
||||||
|
rxd: RXDRPCNode,
|
||||||
|
alph: ALPHRPCNode,
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case "hashrate":
|
||||||
|
this.sharesdb = new DBPool(coin, sharesdb);
|
||||||
|
this.sharesdb_slave = new DBPool(coin, sharesdb_slave);
|
||||||
|
this.pooldb = new DBPool(coin, pooldb);
|
||||||
|
this.redis = new Cache(redis1);
|
||||||
|
// this.pooldb_slave = new DBPool(coin, pooldb_slave)
|
||||||
|
this.hashratedb = new DBPool(coin, hashrate);
|
||||||
|
break;
|
||||||
|
case "report":
|
||||||
|
this.REPORT_ADDRESS = REPORT_ADDRESS;
|
||||||
|
this.node = new node_map[coin](node2);
|
||||||
|
this.distribution = new DBPool(coin, distribution);
|
||||||
|
this.redis = new Cache(redis1);
|
||||||
|
break;
|
||||||
|
case "clear":
|
||||||
|
this.pooldb = new DBPool(coin, pooldb);
|
||||||
|
this.sharesdb = new DBPool(coin, sharesdb);
|
||||||
|
this.hashratedb = new DBPool(coin, hashrate);
|
||||||
|
break;
|
||||||
|
case "distribution":
|
||||||
|
this.pooldb = new DBPool(coin, pooldb);
|
||||||
|
this.hashratedb = new DBPool(coin, hashrate);
|
||||||
|
this.distributiondb = new DBPool(coin, distribution);
|
||||||
|
this.users_addresses = new DBPool(coin, users_addresses);
|
||||||
|
this.node = new node_map[coin](node2);
|
||||||
|
this.REPORT_ADDRESS = REPORT_ADDRESS;
|
||||||
|
this.POOL_FEE = POOL_FEE;
|
||||||
|
console.log(`当前手续费率为:${POOL_FEE}`);
|
||||||
|
// this.balance = new DBPool(coin, balance)
|
||||||
|
break;
|
||||||
|
case "balance":
|
||||||
|
this.distribution = new DBPool(coin, distribution);
|
||||||
|
this.balancedb = new DBPool(coin, balance);
|
||||||
|
break;
|
||||||
|
case "confirm":
|
||||||
|
this.MAX_MATURE = MAX_MATURE;
|
||||||
|
this.REPORT_ADDRESS = REPORT_ADDRESS;
|
||||||
|
this.node = new node_map[coin](node2);
|
||||||
|
this.distribution = new DBPool(coin, distribution);
|
||||||
|
this.pooldb = new DBPool(coin, pooldb);
|
||||||
|
break;
|
||||||
|
case "stats":
|
||||||
|
this.pooldb = new DBPool(coin, pooldb);
|
||||||
|
this.hashratedb = new DBPool(coin, hashrate);
|
||||||
|
this.distribution = new DBPool(coin, distribution);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw `暂不支持${method}方法 init`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(ms) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sql = sql.slice(0, -1)
|
|
||||||
console.log(sql);
|
const a = new Init("alph", "report")
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const sql1 = `SELECT height FROM alph_blkreportprofitv2;`
|
||||||
|
const data1 = await a.distribution.exec(sql1)
|
||||||
|
|
||||||
|
let sql = `UPDATE alph_blkreportprofitv2 SET reward = CASE height `
|
||||||
|
const heights = []
|
||||||
|
|
||||||
|
for (let item of data1) {
|
||||||
|
const { height } = item
|
||||||
|
heights.push(height)
|
||||||
|
|
||||||
|
const data = await a.node.verify_block(height, a.REPORT_ADDRESS)
|
||||||
|
const { block_reward } = data
|
||||||
|
|
||||||
|
sql += `WHEN ${height} THEN ${block_reward} `
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ 加上 END 和 WHERE
|
||||||
|
sql += `END WHERE height IN (${heights.join(",")});`
|
||||||
|
|
||||||
|
await a.distribution.exec(sql)
|
||||||
|
}
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user