modify some msg-struct and table-struct
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user