update 门罗币上线m2pool矿池

This commit is contained in:
yyb 2025-09-01 11:19:49 +08:00
parent 182a2d6c43
commit a9ddc0b9d3
14 changed files with 389 additions and 37 deletions

View File

@ -18,7 +18,8 @@ public enum NodeConfig {
NEXA("nexa", "18.139.85.190", "7227", "test", "test"), NEXA("nexa", "18.139.85.190", "7227", "test", "test"),
RXD("rxd", "18.141.161.129", "7332", "test", "test"), RXD("rxd", "18.141.161.129", "7332", "test", "test"),
ALPH("alph", "18.141.161.129", "12973", "test", "test"), ALPH("alph", "18.141.161.129", "12973", "test", "test"),
ENX("enx", "13.214.6.253", "12973", "test", "test"); ENX("enx", "13.214.6.253", "12973", "test", "test"),
MONERO("monero", "", "", "test", "test");
/** 币种参数名 */ /** 币种参数名 */
private final String coin; private final String coin;

View File

@ -21,7 +21,9 @@ public enum PoolCalParamConfig {
NEXA("nexa", BigDecimal.valueOf(Math.pow(2,32)), BigDecimal.valueOf(720),BigDecimal.valueOf(0.01)), NEXA("nexa", BigDecimal.valueOf(Math.pow(2,32)), BigDecimal.valueOf(720),BigDecimal.valueOf(0.01)),
RXD("rxd", BigDecimal.valueOf(Math.pow(2,32)), BigDecimal.valueOf(288),BigDecimal.valueOf(0.01)), RXD("rxd", BigDecimal.valueOf(Math.pow(2,32)), BigDecimal.valueOf(288),BigDecimal.valueOf(0.01)),
ALPH("alph", BigDecimal.valueOf(Math.pow(2,32)), BigDecimal.valueOf(5400),BigDecimal.valueOf(0.01)), ALPH("alph", BigDecimal.valueOf(Math.pow(2,32)), BigDecimal.valueOf(5400),BigDecimal.valueOf(0.01)),
ENX("enx", BigDecimal.valueOf(Math.pow(2,32)), BigDecimal.valueOf(86400),BigDecimal.valueOf(0.00)); ENX("enx", BigDecimal.valueOf(Math.pow(2,32)), BigDecimal.valueOf(86400),BigDecimal.valueOf(0.00)),
MONERO("monero", BigDecimal.valueOf(1),BigDecimal.valueOf(720) ,BigDecimal.valueOf(0.01));
/** 币种参数名 */ /** 币种参数名 */
private final String coin; private final String coin;

View File

@ -19,7 +19,8 @@ public enum PoolProfitScale {
NEXA("nexa", 2), NEXA("nexa", 2),
RXD("rxd", 2), RXD("rxd", 2),
ALPH("alph", 2), ALPH("alph", 2),
ENX("enx", 2); ENX("enx", 2),
MONERO("monero",2);
/** 币种参数名 */ /** 币种参数名 */
private final String coin; private final String coin;

View File

@ -19,8 +19,8 @@ public enum PoolUnits {
NEXA("nexa", "MH/s", 1000*1000, 1000), NEXA("nexa", "MH/s", 1000*1000, 1000),
RXD("rxd", "MH/s", 1000*1000, 1000), RXD("rxd", "MH/s", 1000*1000, 1000),
ALPH("alph", "MH/s", 1000*1000, 1000), ALPH("alph", "MH/s", 1000*1000, 1000),
ENX("enx", "MH/s", 1000*1000, 1000); ENX("enx", "MH/s", 1000*1000, 1000),
MONERO("monero", "MH/s", 1000*1000, 1000);
/** 币种参数名 */ /** 币种参数名 */
private final String coin; private final String coin;
/** 矿池数据单位 */ /** 矿池数据单位 */

View File

@ -19,8 +19,8 @@ public enum Pools {
NEXA("nexa", "nexa", "NexaPow", "nexa_pool_blkstats", "nexa_mhs", "nexa_pool","nexa.png",0.985,120), NEXA("nexa", "nexa", "NexaPow", "nexa_pool_blkstats", "nexa_mhs", "nexa_pool","nexa.png",0.985,120),
RXD("rxd", "Radiant", "Sha512256D", "rxd_pool_blkstats", "rxd_mhs", "rxd_pool","rxd.png",0.985,300), RXD("rxd", "Radiant", "Sha512256D", "rxd_pool_blkstats", "rxd_mhs", "rxd_pool","rxd.png",0.985,300),
ALPH("alph", "Alephium", "Blake3", "alph_pool_blkstats", "alph_mhs", "alph_pool","alph.svg",0.985,0), ALPH("alph", "Alephium", "Blake3", "alph_pool_blkstats", "alph_mhs", "alph_pool","alph.svg",0.985,0),
ENX("enx", "entropyx", "kHeavyHash", "enx_pool_blkstats", "enx_mhs", "enx_pool","enx.svg",0.985,0); ENX("enx", "entropyx", "kHeavyHash", "enx_pool_blkstats", "enx_mhs", "enx_pool","enx.svg",0.985,0),
MONERO("monero", "monero", "randomx", "monero_pool_blkstats", "monero_mhs", "monero_pool","xmr.png",0.985,0);
/** 币种参数名 */ /** 币种参数名 */
private final String coin; private final String coin;

View File

@ -5,6 +5,7 @@ import com.m2pool.common.datasource.annotation.DistributionDB;
import com.m2pool.common.datasource.annotation.HashRateDB; import com.m2pool.common.datasource.annotation.HashRateDB;
import com.m2pool.common.datasource.annotation.InfoDB; import com.m2pool.common.datasource.annotation.InfoDB;
import com.m2pool.pool.dto.*; import com.m2pool.pool.dto.*;
import com.m2pool.pool.entity.BlockInfo;
import com.m2pool.pool.entity.PoolPower; import com.m2pool.pool.entity.PoolPower;
import com.m2pool.pool.vo.DateValueVo; import com.m2pool.pool.vo.DateValueVo;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
@ -35,6 +36,7 @@ public interface PoolMapper {
public List<PowerLineDto> getDailyPoolPowerList(@Param("table") String table,@Param("startDate") Date startDate,@Param("endDate") Date endDate); public List<PowerLineDto> getDailyPoolPowerList(@Param("table") String table,@Param("startDate") Date startDate,@Param("endDate") Date endDate);
public List<PowerLineDto> getHourPoolPowerList(@Param("table") String table);
public List<PowerLineDto> getHourNetPowerList(@Param("table") String table); public List<PowerLineDto> getHourNetPowerList(@Param("table") String table);
public List<BlockInfoDto> getGRSBlockInfoList(); public List<BlockInfoDto> getGRSBlockInfoList();
@ -61,6 +63,8 @@ public interface PoolMapper {
public List<BlockInfoDto> getENXBlockInfoList(); public List<BlockInfoDto> getENXBlockInfoList();
public List<BlockInfoDto> getMONEROBlockInfoList();
@DistributionDB @DistributionDB
public List<BlockInfoDto> getNewNEXABlockInfoList(@Param("date") String date); public List<BlockInfoDto> getNewNEXABlockInfoList(@Param("date") String date);
@ -88,6 +92,10 @@ public interface PoolMapper {
@DistributionDB @DistributionDB
public List<BlockInfoDto> getNewENXBlockInfoList(@Param("date") String date); public List<BlockInfoDto> getNewENXBlockInfoList(@Param("date") String date);
@DistributionDB
public List<BlockInfoDto> getNewMONEROBlockInfoList(@Param("date") String date);
@HashRateDB @HashRateDB
public List<MinerDataDto> getMinerInfoList(@Param("table") String table); public List<MinerDataDto> getMinerInfoList(@Param("table") String table);
@ -160,6 +168,8 @@ public interface PoolMapper {
public boolean batchInsertENXPoolBlkToDB(@Param("list") List<BlockInfoDto> list); public boolean batchInsertENXPoolBlkToDB(@Param("list") List<BlockInfoDto> list);
public boolean batchInsertMONEROPoolBlkToDB(@Param("list") List<BlockInfoDto> list);
//todo 矿池统计数据入库 //todo 矿池统计数据入库
public boolean insertPoolPower(@Param("table") String table,@Param("vo") PoolPower vo); public boolean insertPoolPower(@Param("table") String table,@Param("vo") PoolPower vo);
@ -249,4 +259,12 @@ public interface PoolMapper {
* @return * @return
*/ */
Integer insertDgbTotalHeight(@Param("height") Long height); Integer insertDgbTotalHeight(@Param("height") Long height);
/**
* 获取门罗币报块信息信息
* @param coin
* @return
*/
BlockInfo getMoneroBlockInfo();
} }

View File

@ -112,8 +112,9 @@ public class PoolServiceImpl implements PoolService {
} }
BigDecimal price = redisService.getCacheObject(pool.getCoin() + "_price"); BigDecimal price = redisService.getCacheObject(pool.getCoin() + "_price");
if (price != null){
dto.setPrice(price.toEngineeringString()+ " USD"); dto.setPrice(price.toEngineeringString()+ " USD");
}
} }
//从enums中拿币种名页面显示名币种对应算法 //从enums中拿币种名页面显示名币种对应算法
@ -184,7 +185,7 @@ public class PoolServiceImpl implements PoolService {
return AjaxResult.error("缺失参数:interval"); return AjaxResult.error("缺失参数:interval");
} }
List<PowerLineDto> priceList = poolMapper.getHourNetPowerList(pool.getCoin()); List<PowerLineDto> priceList = poolMapper.getHourPoolPowerList(pool.getCoin());
int scale = PoolProfitScale.getScaleByCoin(pool.getCoin()); int scale = PoolProfitScale.getScaleByCoin(pool.getCoin());
@ -201,15 +202,17 @@ public class PoolServiceImpl implements PoolService {
PageHelper.clearPage(); PageHelper.clearPage();
//矿池算力从$coin_pool_30m拿 获取的 算力单位为MH/S //矿池算力从$coin_pool_30m拿 获取的 算力单位为MH/S
List<PowerLineDto> list = poolMapper.get30mPoolPowerList(pool.getPoolTable()+"_30m",oneDayAgo,currentDate); List<PowerLineDto> list = poolMapper.get30mPoolPowerList(pool.getPoolTable()+"_30m",oneDayAgo,currentDate);
PowerUnitUtils.NetPowerUnit powerUnit;
if (!list.isEmpty()) {
//根据币种做参数处理 //根据币种做参数处理
PowerLineDto maxPv = list.stream().max(Comparator.comparing(PowerLineDto::getPv)).orElse(new PowerLineDto()); PowerLineDto maxPv = list.stream().max(Comparator.comparing(PowerLineDto::getPv)).orElse(new PowerLineDto());
PowerUnitUtils.NetPowerUnit powerUnit = PowerUnitUtils.getPowerUnit(maxPv.getPv().multiply(BigDecimal.valueOf(1000 * 1000))); powerUnit = PowerUnitUtils.getPowerUnit( maxPv.getPv().multiply(BigDecimal.valueOf(1000 * 1000)));
list = changeUnit(powerUnit, list, pool,BigDecimal.valueOf(1000 * 1000)); list = changeUnit(powerUnit, list, pool,BigDecimal.valueOf(1000 * 1000));
}else{
powerUnit = new PowerUnitUtils.NetPowerUnit("GH/S", BigDecimal.valueOf(1000 * 1000 * 1000));
}
//数据补零 //数据补零
list = fillMissingOnlineData(list,oneDayAgo,currentDate,powerUnit.getUnit(),30); list = fillMissingOnlineData(list,oneDayAgo,currentDate,powerUnit.getUnit(),30);
//通过全网算力接口 获取到的时间段价格补充到矿池算力接口的价格中 //通过全网算力接口 获取到的时间段价格补充到矿池算力接口的价格中
list.stream().forEach(e -> priceList.stream().anyMatch(p ->{ list.stream().forEach(e -> priceList.stream().anyMatch(p ->{
if(p.getDate().equals(e.getDate())){ if(p.getDate().equals(e.getDate())){

View File

@ -42,7 +42,7 @@ public class NeaxPriceTask {
//private String COINMARKETCAP_KEY="7b7a5fc2-795d-4900-a4db-152681382d52"; //private String COINMARKETCAP_KEY="7b7a5fc2-795d-4900-a4db-152681382d52";
private String ALL_COINS="nexa,monacoin,groestlcoin,digibyte,radiant,alephium"; private String ALL_COINS="nexa,monacoin,groestlcoin,digibyte,radiant,alephium,monero";
@Autowired @Autowired
private RedisService redisService; private RedisService redisService;
@ -62,7 +62,9 @@ public class NeaxPriceTask {
|| StringUtils.isNull(map.get("grs")) || StringUtils.isNull(map.get("grs"))
|| StringUtils.isNull(map.get("dgb")) || StringUtils.isNull(map.get("dgb"))
|| StringUtils.isNull(map.get("rxd")) || StringUtils.isNull(map.get("rxd"))
|| StringUtils.isNull(map.get("alph"))){ || StringUtils.isNull(map.get("alph"))
|| StringUtils.isNull(map.get("monero"))
){
if(count >= 10){ if(count >= 10){
break; break;
} }
@ -212,6 +214,29 @@ public class NeaxPriceTask {
alphVo.setValue(alph); alphVo.setValue(alph);
poolMapper.insertPrice("alph_price",date , alphVo); poolMapper.insertPrice("alph_price",date , alphVo);
} }
//处理monero
BigDecimal monero = map.get("monero");
if(StringUtils.isNull(monero)){
//重拿monero
monero = getResultFromNet("monero");
int moneroCount = 1;
while (StringUtils.isNull(monero)){
if(moneroCount >= 5){
break;
}
monero = getResultFromNet("monero");
moneroCount++;
}
}else {
redisService.setCacheObject("monero_price",monero);
//存入数据库
DateValueVo moneroVo = new DateValueVo();
moneroVo.setDate(now);
moneroVo.setValue(monero);
poolMapper.insertPrice("monero_price",date , moneroVo);
}
} }
} }
@ -365,6 +390,8 @@ public class NeaxPriceTask {
} }
else if("alephium".equals(coin.toLowerCase())){ else if("alephium".equals(coin.toLowerCase())){
object = data.getJSONObject("14878"); object = data.getJSONObject("14878");
}else if ("monero".equalsIgnoreCase(coin)){
object = data.getJSONObject("328");
} }
if (StringUtils.isNull(object)){ if (StringUtils.isNull(object)){
@ -401,6 +428,7 @@ public class NeaxPriceTask {
map.put("dgb",null); map.put("dgb",null);
map.put("rxd",null); map.put("rxd",null);
map.put("alph",null); map.put("alph",null);
map.put("monero",null);
@ -429,6 +457,7 @@ public class NeaxPriceTask {
JSONObject dgbObject = data.getJSONObject("109"); JSONObject dgbObject = data.getJSONObject("109");
JSONObject rxdObject = data.getJSONObject("22866"); JSONObject rxdObject = data.getJSONObject("22866");
JSONObject alphObject = data.getJSONObject("14878"); JSONObject alphObject = data.getJSONObject("14878");
JSONObject moneroObject = data.getJSONObject("328");
BigDecimal nexaPrice = getPriceByCoinIdJSONObject(nexaObject); BigDecimal nexaPrice = getPriceByCoinIdJSONObject(nexaObject);
BigDecimal monaPrice = getPriceByCoinIdJSONObject(monaObject); BigDecimal monaPrice = getPriceByCoinIdJSONObject(monaObject);
@ -436,6 +465,7 @@ public class NeaxPriceTask {
BigDecimal dgbPrice = getPriceByCoinIdJSONObject(dgbObject); BigDecimal dgbPrice = getPriceByCoinIdJSONObject(dgbObject);
BigDecimal rxdPrice = getPriceByCoinIdJSONObject(rxdObject); BigDecimal rxdPrice = getPriceByCoinIdJSONObject(rxdObject);
BigDecimal alphPrice = getPriceByCoinIdJSONObject(alphObject); BigDecimal alphPrice = getPriceByCoinIdJSONObject(alphObject);
BigDecimal moneroPrice = getPriceByCoinIdJSONObject(moneroObject);
map.put("nexa",nexaPrice); map.put("nexa",nexaPrice);
map.put("mona",monaPrice); map.put("mona",monaPrice);
@ -443,6 +473,7 @@ public class NeaxPriceTask {
map.put("dgb",dgbPrice); map.put("dgb",dgbPrice);
map.put("rxd",rxdPrice); map.put("rxd",rxdPrice);
map.put("alph",alphPrice); map.put("alph",alphPrice);
map.put("monero",moneroPrice);
return map; return map;

View File

@ -7,6 +7,7 @@ import com.m2pool.common.core.utils.StringUtils;
import com.m2pool.common.redis.service.RedisService; import com.m2pool.common.redis.service.RedisService;
import com.m2pool.pool.dto.BlockInfoDto; import com.m2pool.pool.dto.BlockInfoDto;
import com.m2pool.pool.entity.BlockInfo; import com.m2pool.pool.entity.BlockInfo;
import com.m2pool.pool.enums.PoolCalParamConfig;
import com.m2pool.pool.mapper.PoolMapper; import com.m2pool.pool.mapper.PoolMapper;
import com.m2pool.pool.utils.NodeRpc; import com.m2pool.pool.utils.NodeRpc;
import com.m2pool.pool.vo.DateValueVo; import com.m2pool.pool.vo.DateValueVo;
@ -14,21 +15,20 @@ import lombok.Data;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -662,7 +662,7 @@ public class NodeTask {
//总高度 - 上次的总高度 然后循环遍历这些块高度来判断该块的算法类型, //总高度 - 上次的总高度 然后循环遍历这些块高度来判断该块的算法类型,
for (int i = Integer.parseInt(height) ; i > lastHeight ; i--){ for (int i = Integer.parseInt(height) ; i > lastHeight ; i--){
String hashBlock = NodeRpc.getBlockHash("dgbq", i); String hashBlock = NodeRpc.getBlockInfoByHeight("dgbq", i);
System.out.println("dgb 总高度hashBlock:"+hashBlock); System.out.println("dgb 总高度hashBlock:"+hashBlock);
String dgbType = NodeRpc.getBlockInfoByHash("dgbq", hashBlock); String dgbType = NodeRpc.getBlockInfoByHash("dgbq", hashBlock);
System.out.println("dgb 总高度dgbType:"+dgbType); System.out.println("dgb 总高度dgbType:"+dgbType);
@ -718,4 +718,88 @@ public class NodeTask {
} }
} }
public BlockInfo getMONEROBlock() {
BlockInfo moneroBlockInfo = poolMapper.getMoneroBlockInfo();
System.out.println("moneroBlockInfo"+moneroBlockInfo);
if(StringUtils.isNull(moneroBlockInfo)){
return null;
}
BigDecimal moreroBlocks = PoolCalParamConfig.getCoinCount("morero");
BigDecimal profit = moneroBlockInfo.getReward();
// 保留两位小数
profit = profit.setScale(1, RoundingMode.HALF_UP);
moneroBlockInfo.setProfit(profit);
return moneroBlockInfo;
}
//TODO
@Scheduled(cron = "40 0,30 * * * ?")
public void MONEROBlockInfoToRedisAndDB(){
System.out.println("执行全网算力入库monero");
if(!enable){
return;
}
BlockInfo blockInfo = getMONEROBlock();
int count = 1;
while (StringUtils.isNull(blockInfo)){
if(count >= 10){
break;
}
blockInfo = getMONEROBlock();
count++;
}
System.out.println("monero blockInfo 的信息"+blockInfo);
if(StringUtils.isNotNull(blockInfo)){
if(StringUtils.isNotNull(blockInfo.getPower())){
redisService.setCacheObject("monero_block",blockInfo);
//存入数据库
DateValueVo vo = new DateValueVo();
Date now = new Date();
int minute = (now.getMinutes() / 30) * 30;
now.setMinutes( minute);
now.setSeconds(0);
vo.setDate(now);
String date = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);
System.out.println("monero全网算力数据入库时间:"+date);
vo.setValue(blockInfo.getPower());
poolMapper.insertNetPower("monero_net_power",date,vo);
}
}
}
//TODO
@Scheduled(cron = "0 0/1 * * * ?")
public void MONEROBlockInfoToRedis(){
if(!enable){
return;
}
BlockInfo blockInfo = getMONEROBlock();
int count = 0;
while (StringUtils.isNull(blockInfo)){
if(count >= 3){
break;
}
blockInfo = getMONEROBlock();
count++;
}
if(StringUtils.isNotNull(blockInfo)){
if(StringUtils.isNotNull(blockInfo.getPower())){
if (redisService.hasKey("monero_block")){
redisService.deleteObject("monero_block");
redisService.setCacheObject("monero_block",blockInfo);
}else {
redisService.setCacheObject("monero_block",blockInfo);
}
}
}
}
} }

View File

@ -764,4 +764,91 @@ public class OffLineNoticeTask {
} }
@Scheduled(cron = "25 26,46 * * * ?")
public void MONERO30mDataToDB(){
//String nowStr = DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:00");
if(!enable){
System.out.println("OffLineNoticeTask 定时任务已关闭请在nacos修改配置");
return;
}
Date now = new Date();
int minute = (now.getMinutes() / 30) * 30;
now.setMinutes( minute);
now.setSeconds(0);
String nowStr = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, now);
System.out.println("MONERO 预警定时任务执行时间:"+now);
//检查二级表是否有当前时间数据
int count = poolMapper.getLastDataTime(Pools.MONERO.getMhs() + "30m", nowStr);
System.out.println("count:"+count);
if(count > 0) {
//查询离线矿机数和离线矿机 按挖矿账户分
List<OfflineUserMinerDto> list = poolMapper.getOfflineList(Pools.MONERO.getMhs() + "30m", nowStr);
System.out.println("查询到离线矿机结果 "+list.size()+"");
if(StringUtils.isNotEmpty(list)){
//list不为空才处理
//先获取通知列表 TODO 这里查询notice_info为空,notice_info 里面存的从哪里来
List<NoticeMinerCoinListDto> nmcList = noticeMapper.getNoticeEmailListByMinerAndCoin(list, Pools.MONERO.getCoin());
System.out.println("查询到离线通知列表"+nmcList);
Map<String, List<String>> userEmails = nmcList.stream().
collect(Collectors.groupingBy(
NoticeMinerCoinListDto::getMiner,
Collectors.mapping(NoticeMinerCoinListDto::getEmail, Collectors.toList())
));
if(StringUtils.isNotEmpty(userEmails)){
//获取上一次离线矿机数 可能为null 要做处理 如果没有redis记录 则上次离线数设置为0 若有redis但是key没有此挖矿账户也设置上次离线数为0 TODO 这里也没看到redis里面存储的位置
Map<String, Long> map = redisService.getCacheMap("MONERO_USERS_OFFLINE");
list.stream().forEach(e -> {
long lastOff = 0;
if(StringUtils.isNotNull(map)){
lastOff =map.getOrDefault(e.getUser(),0L);
}
if(e.getOffline() > lastOff){
//对比redis中该挖矿账户上一次离线矿机数 上一次不存在则设上一次离线数为0来进行比较
//仅当本次离线数大于上次离线数时才通知
//执行通知
List<String> emails = userEmails.getOrDefault(e.getUser(), null);
if(StringUtils.isNotNull(emails)){
String text = "您的"+Pools.MONERO.getCoin()+"下挖矿账户: "+e.getUser()+"有矿机离线!离线矿机列表如下:\n" +
e.getMiners() + " \n"+
"若您的矿机是因异常断开,请及时处理!";
emails.stream().forEach(email ->{
System.out.println("用户"+e.getUser()+"矿机离线通知到"+email);
EmailEntity entity = new EmailEntity();
entity.setSubject("[M2Pool] 矿机离线提示");
entity.setEmail(email);
entity.setText(text);
mailService.sendTextMail(entity);
});
}else {
System.out.println("该用户未添加离线通知 :"+userEmails.toString());
}
}else {
//不满足通知条件 不通知
System.out.println("挖矿账户"+e.getUser()+"本次无需通知,本次离线为"+e.getOffline()+",上次离线数"+
map.getOrDefault(e.getUser(),0L));
}
});
}else {
System.out.println("未获取到MONERO下相关的离线告警订阅信息");
}
}
}else{
//最新数据未入库暂不做处理
}
}
} }

View File

@ -198,6 +198,26 @@ public class PoolBlkStatsTask {
} }
} }
@Scheduled(cron = "45 0/2 * * * ?")
public void MONEROBlockInfoToRedis(){
if(!enable){
return;
}
boolean result = MONEROBlockInfo();
int count = 1;
//执行失败返回false 再次执行
while (!result){
if(count >= 3){
break;
}
result = MONEROBlockInfo();
count++;
}
}
public boolean NEXABlockInfo(){ public boolean NEXABlockInfo(){
try { try {
String lastDate= ""; String lastDate= "";
@ -506,4 +526,37 @@ public class PoolBlkStatsTask {
} }
} }
public boolean MONEROBlockInfo(){
try {
String lastDate= "";
if(redisService.hasKey("monero_pool_last_date")){
lastDate = (String) redisService.getCacheObject("monero_pool_last_date");
System.out.println("redis中的lastDate:"+lastDate);
}else {
List<BlockInfoDto> list = poolMapper.getMONEROBlockInfoList();
if (list.size() > 0){
lastDate =DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,list.get(0).getDate());
}else {
lastDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,new Date());
}
}
System.out.println("最终的lastDate:"+lastDate);
List<BlockInfoDto> list = poolMapper.getNewMONEROBlockInfoList(lastDate);
if(!list.isEmpty()){
//存入数据库
poolMapper.batchInsertNexaPoolBlkToDB(list);
//把最大时间存入redis
String maxDate =DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS,list.get(list.size()-1).getDate());
redisService.setCacheObject("monero_pool_last_date",maxDate);
}
return true;
}catch (Exception e){
System.out.println("出错内容:"+e);
return false;
}
}
} }

View File

@ -11,6 +11,7 @@ import com.m2pool.common.core.utils.StringUtils;
import com.m2pool.pool.config.ApacheHttpClientPoolUtil; import com.m2pool.pool.config.ApacheHttpClientPoolUtil;
import com.m2pool.pool.entity.BlockInfo; import com.m2pool.pool.entity.BlockInfo;
import com.m2pool.pool.enums.NodeConfig; import com.m2pool.pool.enums.NodeConfig;
import com.m2pool.pool.mapper.PoolMapper;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders; import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
@ -18,9 +19,12 @@ import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Base64; import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -216,10 +220,20 @@ public class NodeRpc{
} }
public static boolean checkAddress(String coin,String address) { public static boolean checkAddress(String coin,String address) {
//不同币种要单独设置验证方法 //不同币种要单独设置验证方法
String[] params = {address}; String[] params = {address};
if (coin.equals("monero")){
int length = address.length();
if(StringUtils.isNotEmpty(address) && (length == 95 || length == 106) ){
if (address.startsWith("4") || address.startsWith("8")){
return true;
}
return false;
}
return false;
}
String result = getResultTest(coin, "validateaddress", params); String result = getResultTest(coin, "validateaddress", params);
//处理result //处理result
if(StringUtils.isBlank(result)){ if(StringUtils.isBlank(result)){
@ -243,7 +257,7 @@ public class NodeRpc{
* @param height * @param height
* @return * @return
*/ */
public static String getBlockHash(String coin,Integer height){ public static String getBlockInfoByHeight(String coin, Integer height){
Integer[] params = {height}; Integer[] params = {height};
String result = getResultTest(coin, "getblockhash",params); String result = getResultTest(coin, "getblockhash",params);
return result; return result;
@ -298,7 +312,6 @@ public class NodeRpc{
} }
public static BlockInfo getBlock(String coin) { public static BlockInfo getBlock(String coin) {
BlockInfo blockInfo = new BlockInfo(); BlockInfo blockInfo = new BlockInfo();
if(StringUtils.isBlank(coin)){ if(StringUtils.isBlank(coin)){
return blockInfo; return blockInfo;
@ -331,9 +344,10 @@ public class NodeRpc{
String[] params = {}; String[] params = {};
Object[] statsParams = {Convert.toLong(nowHeight)}; Object[] statsParams = {Convert.toLong(nowHeight)};
//全网算力
String result = getResult(coin, "getmininginfo", params); String result = getResult(coin, "getmininginfo", params);
//本次报块奖励
String result2 = getResultTest(coin, "getblockstats", statsParams); String result2 = getResultTest(coin, "getblockstats", statsParams);
System.out.println("yyb-全网算力nexa"+result);
BlockInfo blockInfo = new BlockInfo(); BlockInfo blockInfo = new BlockInfo();
if(StringUtils.isBlank(result)){ if(StringUtils.isBlank(result)){
@ -358,17 +372,14 @@ public class NodeRpc{
return blockInfo; return blockInfo;
} }
if(StringUtils.isNotNull(difficulty)){ if(StringUtils.isNotNull(difficulty)){
blockInfo.setDifficulty(difficulty.setScale(2,BigDecimal.ROUND_HALF_UP)); blockInfo.setDifficulty(difficulty.setScale(2, RoundingMode.HALF_UP));
//NodeConstant constant = (NodeConstant) EnumUtils.get(NodeConstant.class, coin); //NodeConstant constant = (NodeConstant) EnumUtils.get(NodeConstant.class, coin);
//BigDecimal factor = constant.getFactor(); //BigDecimal factor = constant.getFactor();
//if(StringUtils.isNotNull(factor)){ //if(StringUtils.isNotNull(factor)){
// blockInfo.setPower(difficulty.multiply(factor).setScale(2,BigDecimal.ROUND_HALF_UP)); // blockInfo.setPower(difficulty.multiply(factor).setScale(2,BigDecimal.ROUND_HALF_UP));
//} //}
} }
BigDecimal netPower = jsonObject.getBigDecimal("networkhashps"); BigDecimal netPower = jsonObject.getBigDecimal("networkhashps");
System.out.println("yyb-全网算力nexa"+netPower);
if (StringUtils.isNotNull(netPower)){ if (StringUtils.isNotNull(netPower)){
blockInfo.setPower(netPower); blockInfo.setPower(netPower);
} }
@ -1103,7 +1114,6 @@ public class NodeRpc{
} }
} }

View File

@ -44,7 +44,7 @@ public class PowerUnitUtils {
} }
else if (value.compareTo(BigDecimal.valueOf(1000*1000*1000)) >= 0){ else if (value.compareTo(BigDecimal.valueOf(1000*1000*1000)) >= 0){
//1G 1G以上 10T以下 转换为G //1G 1G以上 10T以下 转换为G
return gValue.setScale(scale,BigDecimal.ROUND_HALF_UP).toEngineeringString() + " GH/s"; return gValue.setScale(scale,BigDecimal.ROUND_HALF_UP).toString() + " GH/s";
} }
else if (value.compareTo(BigDecimal.valueOf(1000*1000)) >= 0){ else if (value.compareTo(BigDecimal.valueOf(1000*1000)) >= 0){
//1M 1M以上 1G一下则转换为M //1M 1M以上 1G一下则转换为M
@ -55,7 +55,7 @@ public class PowerUnitUtils {
return value.divide(BigDecimal.valueOf(1000), scale,BigDecimal.ROUND_HALF_UP).toEngineeringString() + " KH/s"; return value.divide(BigDecimal.valueOf(1000), scale,BigDecimal.ROUND_HALF_UP).toEngineeringString() + " KH/s";
} }
else { else {
return value.setScale(scale,BigDecimal.ROUND_HALF_UP).toEngineeringString() + " H/s"; return value.setScale(scale,BigDecimal.ROUND_HALF_UP).toString() + " H/s";
} }
} }

View File

@ -371,7 +371,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by `date` order by `date`
</select> </select>
<select id="getHourNetPowerList" resultType="com.m2pool.pool.dto.PowerLineDto"> <select id="getHourPoolPowerList" resultType="com.m2pool.pool.dto.PowerLineDto">
select select
p.date `date`, p.date `date`,
COALESCE(p.value,0) price, COALESCE(p.value,0) price,
@ -381,6 +381,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
left join ${table}_net_power np on p.date = np.date left join ${table}_net_power np on p.date = np.date
</select> </select>
<select id="getHourNetPowerList" resultType="com.m2pool.pool.dto.PowerLineDto">
select
np.date `date`,
COALESCE(p.value,0) price,
COALESCE(np.value,0) pv
from
${table}_price p
RIGHT join ${table}_net_power np on p.date = np.date
</select>
<select id="getNewNEXABlockInfoList" resultType="com.m2pool.pool.dto.BlockInfoDto"> <select id="getNewNEXABlockInfoList" resultType="com.m2pool.pool.dto.BlockInfoDto">
select select
height, height,
@ -561,6 +571,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by `date` desc order by `date` desc
</select> </select>
<select id="getMONEROBlockInfoList" resultType="com.m2pool.pool.dto.BlockInfoDto">
select
height,
`date`,
hash,
reward,
fees
from
monero_pool_blkstats
order by `date` desc
</select>
<select id="getNewALPHBlockInfoList" resultType="com.m2pool.pool.dto.BlockInfoDto"> <select id="getNewALPHBlockInfoList" resultType="com.m2pool.pool.dto.BlockInfoDto">
select select
height, height,
@ -589,6 +611,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by `date` order by `date`
</select> </select>
<select id="getNewMONEROBlockInfoList" resultType="com.m2pool.pool.dto.BlockInfoDto">
select
height,
`date`,
hash,
reward,
fees
from
monero_blkreportprofitv2
where
`date` > #{date}
order by `date`
</select>
<insert id="batchInsertMhsDataToDB" statementType="STATEMENT"> <insert id="batchInsertMhsDataToDB" statementType="STATEMENT">
insert into ${table}( insert into ${table}(
@ -885,6 +921,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
`date` = VALUES(`date`) `date` = VALUES(`date`)
</insert> </insert>
<insert id="batchInsertMONEROPoolBlkToDB">
insert into monero_pool_blkstats (
`date`,
height,
hash,
reward,
fees
) values
<foreach collection="list" item="i" separator=",">
(
#{i.date},
#{i.height},
#{i.hash},
#{i.reward},
#{i.fees}
)
</foreach>
ON DUPLICATE KEY UPDATE
`date` = VALUES(`date`)
</insert>
<insert id="insertNetBlock"> <insert id="insertNetBlock">
insert into ${tableName} (`height`) values(#{height}) ON DUPLICATE KEY UPDATE `height` = VALUES(`height`) insert into ${tableName} (`height`) values(#{height}) ON DUPLICATE KEY UPDATE `height` = VALUES(`height`)
@ -892,6 +948,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<insert id="insertDgbTotalHeight"> <insert id="insertDgbTotalHeight">
insert into dgb_total_block (`height`) values(#{height}) ON DUPLICATE KEY UPDATE `height` = VALUES(`height`) insert into dgb_total_block (`height`) values(#{height}) ON DUPLICATE KEY UPDATE `height` = VALUES(`height`)
</insert> </insert>
<select id="selectNetBlock" resultType="com.m2pool.pool.dto.BlockInfoDto"> <select id="selectNetBlock" resultType="com.m2pool.pool.dto.BlockInfoDto">
SELECT `date`,height FROM ${tableName} WHERE `date` >= DATE_SUB(now(),INTERVAL 90 DAY) ORDER BY `date` DESC SELECT `date`,height FROM ${tableName} WHERE `date` >= DATE_SUB(now(),INTERVAL 90 DAY) ORDER BY `date` DESC
</select> </select>
@ -915,6 +972,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="getDgbTotalHeight" resultType="java.lang.Integer"> <select id="getDgbTotalHeight" resultType="java.lang.Integer">
select height from dgb_total_block order by `date` DESC LIMIT 1; select height from dgb_total_block order by `date` DESC LIMIT 1;
</select> </select>
<select id="getMoneroBlockInfo" resultType="com.m2pool.pool.entity.BlockInfo">
select height,difficulty,power,reward,fees,profit from monero_block_info order by id desc limit 1;
</select>
</mapper> </mapper>