|
@@ -1,22 +1,33 @@
|
|
|
package com.ichaoj.ams.service.impl;
|
|
|
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.thread.ThreadUtil;
|
|
|
+import cn.hutool.core.util.IdUtil;
|
|
|
+import cn.hutool.core.util.RandomUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
-import com.ichaoj.ams.entity.AmsExecuteRecord;
|
|
|
+import com.ichaoj.ams.entity.AmsAddressAccount;
|
|
|
import com.ichaoj.ams.entity.AmsTradeRecord;
|
|
|
import com.ichaoj.ams.mapper.AmsTradeRecordMapper;
|
|
|
+import com.ichaoj.ams.request.record.CreateTradeRecordRequest;
|
|
|
import com.ichaoj.ams.request.record.PageTradeRecordRequest;
|
|
|
-import com.ichaoj.ams.response.execute.ExecuteResponse;
|
|
|
import com.ichaoj.ams.response.record.TradeRecordResponse;
|
|
|
import com.ichaoj.ams.service.IAmsTradeRecordService;
|
|
|
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.ichaoj.common.model.PublicPage;
|
|
|
import com.ichaoj.mybatis.service.SuperWhaleServiceImpl;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.CompletableFuture;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.atomic.AtomicBoolean;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
/**
|
|
|
* <p>
|
|
|
* 交易 服务实现类
|
|
@@ -26,6 +37,7 @@ import org.springframework.stereotype.Service;
|
|
|
* @since 2023-05-18
|
|
|
*/
|
|
|
@Service
|
|
|
+@Slf4j
|
|
|
public class AmsTradeRecordServiceImpl extends SuperWhaleServiceImpl<AmsTradeRecordMapper, AmsTradeRecord> implements IAmsTradeRecordService {
|
|
|
|
|
|
@Override
|
|
@@ -39,4 +51,84 @@ public class AmsTradeRecordServiceImpl extends SuperWhaleServiceImpl<AmsTradeRec
|
|
|
return this.convertPublicPage(result, s -> BeanUtil.copyProperties(s, TradeRecordResponse.class));
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void randomTrans(List<AmsAddressAccount> accountList, Integer intervalMin, Integer intervalMax, String amount, String maxGas, String executeId) {
|
|
|
+ Map<String, Boolean> addressMap = new HashMap<>(accountList.size());
|
|
|
+ Set<String> set = new HashSet<>();
|
|
|
+
|
|
|
+ List<String> addresses = accountList.stream().map(AmsAddressAccount::getAddress).collect(Collectors.toList());
|
|
|
+
|
|
|
+ for (String address : addresses) {
|
|
|
+ addressMap.put(address, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ while (set.size() != addresses.size()) {
|
|
|
+ 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);
|
|
|
+ if (i == 0) {
|
|
|
+ saveTrade(executeId, address);
|
|
|
+ // todo 调用链上交易
|
|
|
+ } else {
|
|
|
+ int sleepSeconds = RandomUtil.randomInt(intervalMin, intervalMax);
|
|
|
+ log.info("当前是第{} 笔交易,需要等待{} 分钟", i + 1, sleepSeconds);
|
|
|
+ try {
|
|
|
+ AmsTradeRecord record = this.getOne(
|
|
|
+ new LambdaQueryWrapper<AmsTradeRecord>()
|
|
|
+ .eq(AmsTradeRecord::getExecuteId, executeId)
|
|
|
+ .eq(AmsTradeRecord::getAddress, address)
|
|
|
+ );
|
|
|
+ if (record == null) {
|
|
|
+ TimeUnit.MILLISECONDS.sleep(sleepSeconds * 1000L + RandomUtil.randomInt(100, 999));
|
|
|
+ saveTrade(executeId, address);
|
|
|
+ // todo 调用链上交易
|
|
|
+ }
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ addressMap.put(address, true);
|
|
|
+ set.add(address);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private BigDecimal getCurrenAmount(String amount) {
|
|
|
+ return RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal(amount));
|
|
|
+ }
|
|
|
+
|
|
|
+ private BigDecimal getCurrentGasPrice(String maxGas) {
|
|
|
+ return RandomUtil.randomBigDecimal(BigDecimal.ZERO, new BigDecimal(maxGas));
|
|
|
+ }
|
|
|
+
|
|
|
+ private void saveTrade(String executeId, String address) {
|
|
|
+ CreateTradeRecordRequest trade = CreateTradeRecordRequest.builder()
|
|
|
+ .address(address)
|
|
|
+ .executeId(executeId)
|
|
|
+ .createTime(LocalDateTime.now())
|
|
|
+ .status(0)
|
|
|
+ .txId(IdUtil.simpleUUID())
|
|
|
+ .build();
|
|
|
+ this.save(BeanUtil.copyProperties(trade, AmsTradeRecord.class));
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getUnusedAddress(Map<String, Boolean> addressMap, List<String> addresses) {
|
|
|
+ String address = null;
|
|
|
+ while (address == null) {
|
|
|
+ address = getRandomAddress(addresses);
|
|
|
+ if (addressMap.get(address)) {
|
|
|
+ address = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return address;
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getRandomAddress(List<String> accountList) {
|
|
|
+ int randomInt = RandomUtil.randomInt(0, accountList.size() - 1);
|
|
|
+ return accountList.get(randomInt);
|
|
|
+ }
|
|
|
+
|
|
|
}
|