131 lines
2.6 KiB
Go
131 lines
2.6 KiB
Go
|
package miner
|
|||
|
|
|||
|
import (
|
|||
|
"bufio"
|
|||
|
"encoding/json"
|
|||
|
"fmt"
|
|||
|
"net"
|
|||
|
"proxy/internal/msg"
|
|||
|
"strings"
|
|||
|
"sync"
|
|||
|
)
|
|||
|
|
|||
|
const topic string = "[miner]:"
|
|||
|
|
|||
|
type Miner struct {
|
|||
|
sync.Mutex
|
|||
|
Coin string
|
|||
|
ID string // user + miner
|
|||
|
PoolConn net.Conn
|
|||
|
MinerConn net.Conn
|
|||
|
PoolAddress string
|
|||
|
}
|
|||
|
|
|||
|
func NewMiner(coin string, poolAddress string, minerConn net.Conn) (*Miner, error) {
|
|||
|
poolConn, err := net.Dial("tcp", poolAddress)
|
|||
|
if err != nil {
|
|||
|
return nil, fmt.Errorf("pool连接失败: %v", err)
|
|||
|
}
|
|||
|
|
|||
|
return &Miner{
|
|||
|
Coin: coin,
|
|||
|
PoolConn: poolConn,
|
|||
|
MinerConn: minerConn,
|
|||
|
PoolAddress: poolAddress,
|
|||
|
}, nil
|
|||
|
}
|
|||
|
|
|||
|
// 动态切换矿池地址并建立新连接
|
|||
|
func (m *Miner) ChangePoolAddress(newAddress string) {
|
|||
|
m.Lock()
|
|||
|
defer m.Unlock()
|
|||
|
|
|||
|
// 尝试建立新连接
|
|||
|
newConn, err := net.Dial("tcp", newAddress)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("切换pool连接失败:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
|
|||
|
// 关闭旧连接
|
|||
|
if m.PoolConn != nil {
|
|||
|
_ = m.PoolConn.Close()
|
|||
|
}
|
|||
|
|
|||
|
m.PoolConn = newConn
|
|||
|
m.PoolAddress = newAddress
|
|||
|
|
|||
|
fmt.Println("成功切换矿池地址为:", newAddress)
|
|||
|
}
|
|||
|
|
|||
|
// 矿工消息处理
|
|||
|
func (m *Miner) HandleMinerMsg(ch chan string) {
|
|||
|
defer m.MinerConn.Close()
|
|||
|
defer m.PoolConn.Close()
|
|||
|
|
|||
|
reader := bufio.NewReader(m.MinerConn)
|
|||
|
sent := false // 保证 userSign 只发送一次
|
|||
|
|
|||
|
for {
|
|||
|
msgStr, err := reader.ReadString('\n')
|
|||
|
if err != nil {
|
|||
|
fmt.Println("miner消息读取失败:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
// fmt.Println("从矿工收到消息:", msgStr)
|
|||
|
switch m.Coin {
|
|||
|
case "nexa":
|
|||
|
//
|
|||
|
default:
|
|||
|
var msg msg.Authorize_msg
|
|||
|
if err := json.Unmarshal([]byte(msgStr), &msg); err == nil &&
|
|||
|
msg.Method == "mining.authorize" && len(msg.Params) >= 1 && !sent {
|
|||
|
parts := strings.Split(msg.Params[0], ".")
|
|||
|
if len(parts) >= 2 {
|
|||
|
userSign := parts[0] + "-" + parts[1]
|
|||
|
select {
|
|||
|
case ch <- userSign:
|
|||
|
sent = true
|
|||
|
default:
|
|||
|
}
|
|||
|
} else {
|
|||
|
fmt.Println(topic+"mining.authorize解析user-miner错误\n", err)
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if m.PoolConn != nil {
|
|||
|
_, err = m.PoolConn.Write([]byte(msgStr))
|
|||
|
if err != nil {
|
|||
|
fmt.Println("转发到pool失败:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 矿池消息处理
|
|||
|
func (m *Miner) HandlePoolMsg() {
|
|||
|
defer m.MinerConn.Close()
|
|||
|
defer m.PoolConn.Close()
|
|||
|
|
|||
|
reader := bufio.NewReader(m.PoolConn)
|
|||
|
for {
|
|||
|
poolMsg, err := reader.ReadString('\n')
|
|||
|
if err != nil {
|
|||
|
fmt.Println("pool消息读取失败:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
// fmt.Println("从矿池收到消息:", poolMsg)
|
|||
|
|
|||
|
if m.MinerConn != nil {
|
|||
|
_, err = m.MinerConn.Write([]byte(poolMsg))
|
|||
|
if err != nil {
|
|||
|
fmt.Println("转发到miner失败:", err)
|
|||
|
return
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|