modify some msg-struct and table-struct

This commit is contained in:
lzx
2025-11-14 17:43:25 +08:00
parent 245c9c94cb
commit ac22db02f3
11 changed files with 605 additions and 276 deletions

View File

@@ -9,6 +9,7 @@ import (
message "m2pool-payment/internal/msg"
"m2pool-payment/internal/utils"
"math/big"
"os"
"strings"
"sync"
"time"
@@ -31,6 +32,21 @@ func init_USDT() *USDT {
return usdt
}
func (e *ETHNode) initTables() error {
sql_script_path := "../public/eth.sql"
sql_byte, err := os.ReadFile(sql_script_path)
if err != nil {
return fmt.Errorf("open msg-sql file error: %v", err)
}
err = e.SqliteDB.CreateTable(string(sql_byte))
if err != nil {
return fmt.Errorf("exec eth-sql error: %v", err)
}
return nil
}
func (e *ETHNode) updateNetInfo(height uint64) {
// 创建 WaitGroup
var wg sync.WaitGroup
@@ -116,11 +132,11 @@ func (e *ETHNode) getSuggestGasPrice() (*big.Int, error) {
}
// 设置gas price上限避免在网络拥堵时费用过高
// 这里设置为20 Gwei (20 * 10^9 wei)
maxGasPrice := new(big.Int).SetUint64(20000000000) // 20 Gwei
// 这里设置为20 Gwei (2 * 10^9 wei)
maxGasPrice := new(big.Int).SetUint64(2000000000) // 2 Gwei
if gasPrice.Cmp(maxGasPrice) > 0 {
log.Printf("⚠️ 建议gas price过高 (%v wei),使用上限 20 Gwei", new(big.Int).Div(gasPrice, big.NewInt(1e18)))
log.Printf("⚠️ 建议gas price过高 (%v wei),使用上限 2 Gwei", new(big.Int).Div(gasPrice, big.NewInt(1e18)))
return maxGasPrice, nil
}
@@ -144,15 +160,15 @@ func (e *ETHNode) getEIP1559GasFees() (*big.Int, *big.Int, error) {
}
// 设置优先级费用tip这里设置为2 Gwei
maxPriorityFeePerGas := new(big.Int).SetUint64(2000000000) // 2 Gwei
maxPriorityFeePerGas := new(big.Int).SetUint64(2000000) // 0.2 Gwei
// 计算最大费用 = 基础费用 + 优先级费用
maxFeePerGas := new(big.Int).Add(baseFee, maxPriorityFeePerGas)
// 设置最大费用上限为30 Gwei
maxFeeLimit := new(big.Int).SetUint64(30000000000) // 30 Gwei
// 设置最大费用上限为2 Gwei
maxFeeLimit := new(big.Int).SetUint64(2000000000) // 2 Gwei
if maxFeePerGas.Cmp(maxFeeLimit) > 0 {
log.Printf("⚠️ 计算的最大费用过高 (%v wei),使用上限 30 Gwei", new(big.Int).Div(maxFeePerGas, big.NewInt(1e18)))
log.Printf("⚠️ 计算的最大费用过高 (%v wei),使用上限 2 Gwei", new(big.Int).Div(maxFeePerGas, big.NewInt(1e18)))
maxFeePerGas = maxFeeLimit
}
@@ -387,10 +403,11 @@ func (e *ETHNode) loadWallets() error {
addresses = append(addresses, addr)
wallets[addr] = wallet
}
log.Printf("ETH钱包加载成功%v", addresses)
if err := rows.Err(); err != nil {
return fmt.Errorf("error occurred while iterating rows: %v", err)
}
if len(addresses) > 0 {
pks, err := e.getAddressesPks(addresses)
if err != nil {
@@ -404,6 +421,10 @@ func (e *ETHNode) loadWallets() error {
e.mu.Unlock()
}
// for addr, balance := range e.Wallets {
// log.Printf("钱包:%s, wallets: %v", addr, balance)
// }
return nil
}
@@ -634,8 +655,50 @@ func (e *ETHNode) listenETHTransactions() error {
}
}
func (e *ETHNode) handleHistoryETHEvent(height uint64) {
block, err := e.RpcClient.BlockByNumber(e.Ctx, big.NewInt(int64(height)))
if err != nil {
log.Println(err)
return
}
for _, tx := range block.Transactions() {
txHash := tx.Hash().Hex()
// 只处理ETH转账Value > 0
if tx.Value().Sign() <= 0 {
continue
}
// 使用 types.Sender 获取发送方地址
signer := types.LatestSignerForChainID(e.NetID)
from, err := types.Sender(signer, tx)
if err != nil {
log.Println("获取发送方地址失败:", err)
continue
}
toAddr := ""
if tx.To() != nil {
toAddr = strings.ToLower(tx.To().Hex())
}
fromAddr := strings.ToLower(from.Hex())
// 获取交易金额
amount := utils.BigIntETHToFloat64(tx.Value())
if _, ok := e.Wallets[toAddr]; ok {
msg, err := e.MessageServer.FindTopupMsgWithToaddress("ETH", toAddr)
if err != nil {
log.Printf("❌ 未查找到ETH充值消息中有address(%s)信息", toAddr)
continue
}
log.Printf("当前交易txHash:%s, fromAddr: %s, toAddr: %s, amount: %fETH", txHash, fromAddr, toAddr, amount)
log.Println(msg)
}
}
}
func (e *ETHNode) handleETHEvent(header *types.Header) {
height := header.Number.Uint64()
log.Printf("当前区块高度:%d", height)
// 获取区块中的所有交易
block, err := e.RpcClient.BlockByHash(e.Ctx, header.Hash())
if err != nil {
@@ -666,6 +729,7 @@ func (e *ETHNode) handleETHEvent(header *types.Header) {
amount := utils.BigIntETHToFloat64(tx.Value())
// toAddr和监听钱包一致表示(充值)
if _, ok := e.Wallets[toAddr]; ok {
log.Printf("监听地址: %s交易信息%v", toAddr, tx)
msg, err := e.MessageServer.FindTopupMsgWithToaddress("ETH", toAddr)
if err != nil {
log.Printf("❌ 未查找到ETH充值消息中有address(%s)信息", toAddr)
@@ -719,7 +783,7 @@ func (e *ETHNode) handleETHEvent(header *types.Header) {
resp := message.WithdrawMsg_resp{
QueueId: v.QueueId,
Chain: "ETH",
Symbol: v.Symbol, // 使用消息中的Symbol应该是ETH
Symbol: "ETH", // 使用消息中的Symbol应该是ETH
FromAddress: fromAddr,
ToAddress: toAddr,
TxHash: txHash,
@@ -734,7 +798,7 @@ func (e *ETHNode) handleETHEvent(header *types.Header) {
QueueId: v.QueueId,
TxType: 1, // 提现类型
Chain: "ETH",
Symbol: v.Symbol, // 使用消息中的Symbol应该是ETH
Symbol: "ETH", // 使用消息中的Symbol应该是ETH
From: fromAddr,
To: toAddr,
TxHash: txHash,
@@ -746,30 +810,36 @@ func (e *ETHNode) handleETHEvent(header *types.Header) {
}
case message.PayMsg_req:
for to, transaction := range v.Transactions {
if v.FromAddress == fromAddr && to == toAddr && transaction.Amount == amount {
resp := transaction
resp.Chain = "ETH"
resp.Symbol = v.Symbol // 使用消息中的Symbol可能是ETH或USDT
resp.Status = constant.STATUS_PENDING
go e.asyncSendMsgToListen(resp, 3, 5*time.Second)
e.UnConfirmedTxs.mu.Lock()
e.UnConfirmedTxs.Transactions[txHash] = message.Transaction{
QueueId: v.QueueId,
TxType: 2, // 支付类型
Chain: "ETH",
Symbol: v.Symbol, // 使用消息中的Symbol
From: fromAddr,
To: toAddr,
TxHash: txHash,
Height: height,
Amount: tx.Value(),
Status: constant.STATUS_PENDING,
}
e.UnConfirmedTxs.mu.Unlock()
if v.FromAddress == fromAddr && v.ToAddress == toAddr && v.Amount == amount {
resp := message.PayMsg_resp{
QueueId: v.QueueId,
Chain: "ETH",
Symbol: "ETH", // 使用消息中的Symbol应该是ETH
FromAddress: fromAddr,
ToAddress: toAddr,
TxHash: txHash,
Amount: amount,
Fee: v.Fee,
BlockHeight: height,
Status: constant.STATUS_PENDING,
}
go e.asyncSendMsgToListen(resp, 3, 5*time.Second)
e.UnConfirmedTxs.mu.Lock()
e.UnConfirmedTxs.Transactions[txHash] = message.Transaction{
QueueId: v.QueueId,
TxType: 2, // 提现类型
Chain: "ETH",
Symbol: "ETH", // 使用消息中的Symbol应该是ETH
From: fromAddr,
To: toAddr,
TxHash: txHash,
Height: height,
Amount: tx.Value(),
Status: constant.STATUS_PENDING,
}
e.UnConfirmedTxs.mu.Unlock()
}
default:
}
@@ -897,7 +967,7 @@ func (e *ETHNode) handleUSDTEvent(vLog types.Log) {
QueueId: v.QueueId,
TxType: 1, // 提现类型
Chain: "ETH",
Symbol: v.Symbol, // 使用消息中的Symbol应该是USDT
Symbol: "USDT", // 使用消息中的Symbol应该是USDT
From: fromAddr,
To: toAddr,
TxHash: txHash,
@@ -909,29 +979,34 @@ func (e *ETHNode) handleUSDTEvent(vLog types.Log) {
}
case message.PayMsg_req:
for to, transaction := range v.Transactions {
if v.FromAddress == fromAddr && to == toAddr && transaction.Amount == value_float {
resp := transaction
resp.Chain = "ETH"
resp.Symbol = v.Symbol // 使用消息中的Symbol应该是USDT
resp.Status = constant.STATUS_PENDING
go e.asyncSendMsgToListen(resp, 3, 5*time.Second)
e.UnConfirmedTxs.mu.Lock()
e.UnConfirmedTxs.Transactions[txHash] = message.Transaction{
QueueId: v.QueueId,
TxType: 2, // 支付类型
Chain: "ETH",
Symbol: v.Symbol, // 使用消息中的Symbol应该是USDT
From: fromAddr,
To: toAddr,
TxHash: txHash,
Height: height,
Amount: transferEvent.Value,
Status: constant.STATUS_PENDING,
}
e.UnConfirmedTxs.mu.Unlock()
if v.FromAddress == fromAddr && v.ToAddress == toAddr && v.Amount == value_float {
resp := message.PayMsg_resp{
QueueId: v.QueueId,
Chain: "ETH",
Symbol: "USDT",
FromAddress: fromAddr,
ToAddress: toAddr,
TxHash: txHash,
Amount: value_float,
Fee: v.Fee,
BlockHeight: height,
Status: constant.STATUS_PENDING,
}
go e.asyncSendMsgToListen(resp, 3, 5*time.Second)
e.UnConfirmedTxs.mu.Lock()
e.UnConfirmedTxs.Transactions[txHash] = message.Transaction{
QueueId: v.QueueId,
TxType: 1, // 提现类型
Chain: "ETH",
Symbol: "USDT", // 使用消息中的Symbol应该是USDT
From: fromAddr,
To: toAddr,
TxHash: txHash,
Height: height,
Amount: transferEvent.Value,
Status: constant.STATUS_PENDING,
}
e.UnConfirmedTxs.mu.Unlock()
}
default:
@@ -986,7 +1061,10 @@ func (e *ETHNode) confirm() {
delete(e.UnConfirmedTxs.Transactions, txHash)
continue
}
var tableMap = map[string]string{
"ETH": "ETH_balances",
"USDT": "USDT_balances",
}
switch v := msg.(type) {
case message.TopupMsg_req:
if status == constant.STATUS_SUCCESS {
@@ -1013,6 +1091,18 @@ func (e *ETHNode) confirm() {
TxHash: txHash,
BlockHeight: tx.Height,
}
go func() {
str := "UPDATE " + tableMap[tx.Symbol] + " SET success_tx_hash = success_tx_hash || ? WHERE address = ?"
params := []any{txHash + ",", v.Address}
count, err := e.SqliteDB.Update(str, params)
if err != nil {
// 更详细的错误日志,包括 QueueId 和 Status
log.Printf("Failed to update remove_resp_msg for queue_id %s: %v", v.QueueId, err)
} else if count != 1 {
// 如果更新的行数不是 1日志中记录详细信息
log.Printf("Unexpected update count for queue_id %s: expected 1, got %d", v.QueueId, count)
}
}()
responses = append(responses, response) // 将消息提交至responses
case message.WithdrawMsg_req:
if status == constant.STATUS_SUCCESS {
@@ -1060,17 +1150,19 @@ func (e *ETHNode) confirm() {
delete(e.UnConfirmedTxs.Transactions, txHash)
continue
}
response := message.PayData{
QueueId: v.QueueId,
Chain: v.Chain,
Symbol: v.Symbol,
TxHash: txHash,
ToAddress: tx.To,
Amount: float_amount,
BlockHeight: tx.Height,
response := message.PayMsg_resp{
QueueId: tx.QueueId,
Chain: tx.Chain,
Symbol: tx.Symbol,
Status: status,
Amount: float_amount,
Fee: v.Fee,
TxHash: txHash,
FromAddress: tx.From,
ToAddress: tx.To,
BlockHeight: tx.Height,
}
responses = append(responses, response)
responses = append(responses, response) // 将消息提交至responses
default:
log.Printf("未知的消息类型: %v, 跳过此交易", v)
delete(e.UnConfirmedTxs.Transactions, txHash)
@@ -1137,6 +1229,11 @@ func (e *ETHNode) handleListen_Topup_req(msg message.TopupMsg_req) {
if err != nil {
log.Printf("Received ListenServer Topup_req msg: insert sqlite3 db error: %v", err)
}
go e.asyncSendMsgToListen(message.UpdateReqState{
QueueId: msg.QueueId,
MsgType: 0,
Status: constant.STATUS_SUCCESS,
}, 3, 5*time.Second)
}()
}
@@ -1193,6 +1290,11 @@ func (e *ETHNode) handleListen_Withdraw_req(msg message.WithdrawMsg_req) {
return
}
// 转账成功等待chain server listen监听到该笔交易
go e.asyncSendMsgToListen(message.UpdateReqState{
QueueId: msg.QueueId,
MsgType: 1,
Status: constant.STATUS_SUCCESS,
}, 3, 5*time.Second)
log.Printf("withdraw - transfer success: QueueId(%s)", msg.QueueId)
} else { // 校验失败
// 提现转账账户余额不足
@@ -1209,8 +1311,8 @@ func (e *ETHNode) handleListen_Pay_req(msg message.PayMsg_req) {
e.NetInfo.mu.Unlock()
var target_amount_eth, target_amount_usdt *big.Int
// 将 msg.Amount 和 msg.Fee 转换为 big.Int只调用一次
amountBigInt := utils.Float64ToBigInt(msg.Symbol, msg.TotalAmount)
feeBigInt := utils.Float64ToBigInt(msg.Symbol, msg.TotalFee)
amountBigInt := utils.Float64ToBigInt(msg.Symbol, msg.Amount)
feeBigInt := utils.Float64ToBigInt(msg.Symbol, msg.Fee)
switch msg.Symbol {
case "ETH":
// 计算目标金额
@@ -1223,41 +1325,46 @@ func (e *ETHNode) handleListen_Pay_req(msg message.PayMsg_req) {
default:
return
}
// 构建相应通用数据Status根据后续情况变化
result_msg := message.PayMsg_resp{
QueueId: msg.QueueId,
Chain: msg.Chain,
Symbol: msg.Symbol,
FromAddress: msg.FromAddress,
Transactions: msg.Transactions,
QueueId: msg.QueueId,
Chain: msg.Chain,
Symbol: msg.Symbol,
Amount: msg.Amount,
Fee: msg.Fee,
FromAddress: msg.FromAddress,
ToAddress: msg.ToAddress,
}
check_result, err := e.checkBalance(msg.Symbol, msg.FromAddress, target_amount_eth, target_amount_usdt)
// 余额校验错误,绕过转账,返回错误响应
if err != nil {
log.Printf("check balance error: %v", err)
result_msg.PayStatus = constant.STATUS_ERROR
for to, tx := range result_msg.Transactions {
tx.Status = constant.STATUS_ERROR
result_msg.Transactions[to] = tx
}
result_msg.Status = constant.STATUS_ERROR
go e.asyncSendMsgToListen(result_msg, 3, 5*time.Second)
return
}
// 校验成功
if check_result {
for _, tx := range result_msg.Transactions {
err := e.Transfer(msg.FromAddress, tx.ToAddress, msg.Symbol, tx.Amount, tx.Fee)
if err != nil {
log.Println(err)
tx.Status = constant.STATUS_ERROR
} else {
tx.Status = constant.STATUS_PENDING
}
// 开始转账
err := e.Transfer(msg.FromAddress, msg.ToAddress, msg.Symbol, msg.Amount, msg.Fee)
// 转账失败,返回转账失败结果
if err != nil {
log.Printf("withdraw - transfer error: %v", err)
result_msg.Status = constant.STATUS_ERROR
// 提现转账错误
go e.asyncSendMsgToListen(result_msg, 3, 5*time.Second)
return
}
// 此时所有待转账的数据均已进行转账处理
// 转账成功等待chain server listen监听到该笔交易
log.Printf("pay - transfer success: QueueId(%s)", msg.QueueId)
} else {
go e.asyncSendMsgToListen(message.UpdateReqState{
QueueId: msg.QueueId,
MsgType: 1,
Status: constant.STATUS_SUCCESS,
}, 3, 5*time.Second)
log.Printf("withdraw - transfer success: QueueId(%s)", msg.QueueId)
} else { // 校验失败
// 提现转账账户余额不足
result_msg.PayStatus = constant.STATUS_BALANCE_NOT_ENOUGH
result_msg.Status = constant.STATUS_BALANCE_NOT_ENOUGH
go e.asyncSendMsgToListen(result_msg, 3, 5*time.Second)
return
}
@@ -1276,7 +1383,7 @@ func (e *ETHNode) handleListen_Remove_req(msg message.RemoveListenMsg_req) {
}
str := "UPDATE ETH_wallets SET status = ? WHERE address = ?"
params := []any{0, msg.Address}
count, err := e.SqliteDB.Update(str, params...)
count, err := e.SqliteDB.Update(str, params)
if err != nil || count != 1 {
log.Printf("Remove address(%s) error: count(%d)", msg.Address, count)
// result_msg.Status = constant.STATUS_FAILED