|
@@ -1,11 +1,17 @@
|
|
|
package com.ichaoj.ams.service.impl;
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
+import cn.hutool.core.date.DateTime;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.date.LocalDateTimeUtil;
|
|
|
+import cn.hutool.core.thread.ThreadUtil;
|
|
|
import cn.hutool.core.util.IdUtil;
|
|
|
import cn.hutool.core.util.RandomUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.ichaoj.ams.entity.AmsAddressAccount;
|
|
|
+import com.ichaoj.ams.entity.AmsExecuteRecord;
|
|
|
import com.ichaoj.ams.entity.AmsTradeRecord;
|
|
|
import com.ichaoj.ams.mapper.AmsTradeRecordMapper;
|
|
|
import com.ichaoj.ams.request.record.CreateTradeRecordRequest;
|
|
@@ -21,6 +27,7 @@ import com.ichaoj.mybatis.service.SuperWhaleServiceImpl;
|
|
|
import com.ichaoj.web.context.SuperWhaleContext;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.context.annotation.Lazy;
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
@@ -65,49 +72,66 @@ public class AmsTradeRecordServiceImpl extends SuperWhaleServiceImpl<AmsTradeRec
|
|
|
for (String address : addresses) {
|
|
|
addressMap.put(address, false);
|
|
|
}
|
|
|
-
|
|
|
- doTrans(intervalMin, intervalMax, amount, maxGas, executeId, addressMap, set, addresses);
|
|
|
+ prepareTrans(intervalMin, intervalMax, amount, maxGas, executeId, addressMap, set, addresses);
|
|
|
}
|
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
- protected void doTrans(Integer intervalMin, Integer intervalMax, String amount, String maxGas, String executeId, Map<String, Boolean> addressMap, Set<String> set, List<String> addresses) {
|
|
|
- while (set.size() < addresses.size() - 1) {
|
|
|
- for (int i = 0; i < addresses.size(); i++) {
|
|
|
- BigDecimal gas = getCurrentGasPrice(maxGas);
|
|
|
- log.info("当前gas: {}", gas);
|
|
|
- BigDecimal currenAmount = getCurrenAmount(amount);
|
|
|
- log.info("amount: {}", currenAmount);
|
|
|
- String address = getUnusedAddress(addressMap, addresses);
|
|
|
- int sleepSeconds = RandomUtil.randomInt(intervalMin, intervalMax);
|
|
|
- long sleep = sleepSeconds * 60L + RandomUtil.randomInt(1, 30);
|
|
|
+ protected synchronized void prepareTrans(Integer intervalMin, Integer intervalMax, String amount, String maxGas, String executeId, Map<String, Boolean> addressMap, Set<String> set, List<String> addresses) {
|
|
|
+ int i = 0;
|
|
|
+ while (set.size() < addresses.size()) {
|
|
|
+ BigDecimal gas = getCurrentGasPrice(maxGas);
|
|
|
+ BigDecimal currenAmount = getCurrenAmount(amount);
|
|
|
+ String address = getUnusedAddress(addressMap, addresses);
|
|
|
+
|
|
|
+ AmsTradeRecord record = this.getOne(
|
|
|
+ new LambdaQueryWrapper<AmsTradeRecord>()
|
|
|
+ .eq(AmsTradeRecord::getExecuteId, executeId)
|
|
|
+ .eq(AmsTradeRecord::getAddress, address)
|
|
|
+ );
|
|
|
+ if (record != null) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ addressMap.put(address, true);
|
|
|
+ set.add(address);
|
|
|
+ int sleepSeconds = RandomUtil.randomInt(intervalMin, intervalMax);
|
|
|
+ long sleep = sleepSeconds * 60L + RandomUtil.randomInt(1, 30);
|
|
|
+ if (i == 0) {
|
|
|
log.info("执行器{} ,当前总共有{} 条交易需要执行,当前是第{} 笔交易,第{}笔交易需要等待{} 分钟",
|
|
|
executeId,
|
|
|
addresses.size(),
|
|
|
i + 1,
|
|
|
i + 2,
|
|
|
sleep / 60);
|
|
|
- if (i == 0) {
|
|
|
- executeTrans(executeId, address, gas, currenAmount);
|
|
|
- } else {
|
|
|
- AmsTradeRecord record = this.getOne(
|
|
|
- new LambdaQueryWrapper<AmsTradeRecord>()
|
|
|
- .eq(AmsTradeRecord::getExecuteId, executeId)
|
|
|
- .eq(AmsTradeRecord::getAddress, address)
|
|
|
- );
|
|
|
-
|
|
|
- if (record == null) {
|
|
|
- AMS_SCHEDULER.schedule(() -> {
|
|
|
- // todo 调用链上交易
|
|
|
-
|
|
|
- //交易入库
|
|
|
- executeTrans(executeId, address, gas, currenAmount);
|
|
|
-
|
|
|
- }, sleep, TimeUnit.SECONDS);
|
|
|
- }
|
|
|
+ log.info("当前gas: {}", gas);
|
|
|
+ log.info("amount: {}", currenAmount);
|
|
|
+ executeTrans(executeId, address, gas, currenAmount);
|
|
|
+ ThreadUtil.safeSleep(sleep);
|
|
|
+ i++;
|
|
|
+ } else {
|
|
|
+ AmsTradeRecord tradeRecord = this.getOne(
|
|
|
+ new LambdaQueryWrapper<AmsTradeRecord>()
|
|
|
+ .eq(AmsTradeRecord::getExecuteId, executeId)
|
|
|
+ .eq(AmsTradeRecord::getAddress, address)
|
|
|
+ );
|
|
|
+
|
|
|
+ if (tradeRecord == null) {
|
|
|
+ log.info("执行器{} ,当前总共有{} 条交易需要执行,当前是第{} 笔交易,第{}笔交易需要等待{} 分钟",
|
|
|
+ executeId,
|
|
|
+ addresses.size(),
|
|
|
+ i + 1,
|
|
|
+ i + 2,
|
|
|
+ sleep / 60);
|
|
|
+ log.info("当前gas: {}", gas);
|
|
|
+ log.info("amount: {}", currenAmount);
|
|
|
+ AMS_SCHEDULER.schedule(() -> {
|
|
|
+ // todo 调用链上交易
|
|
|
+
|
|
|
+ //交易入库
|
|
|
+ executeTrans(executeId, address, gas, currenAmount);
|
|
|
+
|
|
|
+ }, sleep, TimeUnit.SECONDS);
|
|
|
+ i++;
|
|
|
}
|
|
|
-
|
|
|
- addressMap.put(address, true);
|
|
|
- set.add(address);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -139,6 +163,11 @@ public class AmsTradeRecordServiceImpl extends SuperWhaleServiceImpl<AmsTradeRec
|
|
|
return this.baseMapper.getExportData(userId);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public List<TradeRecordResponse> listByUserId(String userId) {
|
|
|
+ return this.baseMapper.listByUserId(userId);
|
|
|
+ }
|
|
|
+
|
|
|
private BigDecimal getCurrenAmount(String amount) {
|
|
|
return RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal(amount));
|
|
|
}
|
|
@@ -179,8 +208,22 @@ public class AmsTradeRecordServiceImpl extends SuperWhaleServiceImpl<AmsTradeRec
|
|
|
}
|
|
|
|
|
|
private String getRandomAddress(List<String> accountList) {
|
|
|
- int randomInt = RandomUtil.randomInt(0, accountList.size() - 1);
|
|
|
+ int randomInt = RandomUtil.randomInt(0, accountList.size());
|
|
|
return accountList.get(randomInt);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ @Scheduled(cron = "0/59 * * * * ? ")
|
|
|
+ public void scanTradeStatus() {
|
|
|
+ List<AmsTradeRecord> list = this.list(new LambdaQueryWrapper<AmsTradeRecord>()
|
|
|
+ .eq(AmsTradeRecord::getStatus, 0));
|
|
|
+ for (AmsTradeRecord record : list) {
|
|
|
+ DateTime dateTime = DateUtil.offsetMinute(DateUtil.date(record.getCreateTime()), 1);
|
|
|
+ if (new DateTime().isAfterOrEquals(dateTime)) {
|
|
|
+ record.setStatus(1);
|
|
|
+ this.updateById(record);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|