update change pool address send authorize info
This commit is contained in:
parent
1af2d6f0c1
commit
50301e1771
63
README.md
63
README.md
|
@ -1 +1,62 @@
|
||||||
# 代理
|
# 代理项目
|
||||||
|
|
||||||
|
Go语言编写的矿工代理服务,支持矿工连接代理并动态切换矿池地址。
|
||||||
|
|
||||||
|
## 功能
|
||||||
|
|
||||||
|
- 矿工连接代理服务
|
||||||
|
- 默认代理到指定矿池地址
|
||||||
|
- 通过RabbitMQ消息动态切换矿池
|
||||||
|
- 支持多种加密货币
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 环境要求
|
||||||
|
- Go 1.23.1+
|
||||||
|
|
||||||
|
### 编译运行
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 编译代理程序
|
||||||
|
go build -o proxy.exe cmd/proxy.go
|
||||||
|
|
||||||
|
# 运行代理程序
|
||||||
|
./proxy.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
### 配置文件
|
||||||
|
|
||||||
|
创建 `config.json`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"coin": "your_coin",
|
||||||
|
"zmqAddr": "amqp://localhost:5672",
|
||||||
|
"tcpAddr": ":3333",
|
||||||
|
"proxyAddr": "pool.example.com:3333",
|
||||||
|
"rabbitTopic": "proxy_queue"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
├── cmd/proxy.go # 代理程序入口
|
||||||
|
├── internal/
|
||||||
|
│ ├── miner/miner.go # 矿工连接管理
|
||||||
|
│ ├── msg/msg.go # 消息结构
|
||||||
|
│ ├── proxy.go # 代理服务核心
|
||||||
|
│ └── zmq/zmq.go # RabbitMQ处理
|
||||||
|
└── go.mod # 依赖管理
|
||||||
|
```
|
||||||
|
|
||||||
|
## 使用说明
|
||||||
|
|
||||||
|
- **proxy.exe**: 矿工代理服务 (监听TCP连接)
|
||||||
|
|
||||||
|
## 工作流程
|
||||||
|
|
||||||
|
1. 矿工连接代理服务
|
||||||
|
2. 代理使用默认矿池地址
|
||||||
|
3. 收到RabbitMQ消息可切换矿池
|
||||||
|
4. 持续转发矿工和矿池消息
|
5
go.mod
5
go.mod
|
@ -2,7 +2,4 @@ module proxy
|
||||||
|
|
||||||
go 1.23.1
|
go 1.23.1
|
||||||
|
|
||||||
require (
|
require github.com/rabbitmq/amqp091-go v1.10.0
|
||||||
github.com/rabbitmq/amqp091-go v1.10.0
|
|
||||||
github.com/zeromq/goczmq v4.1.0+incompatible
|
|
||||||
)
|
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -1,6 +1,4 @@
|
||||||
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
|
github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw=
|
||||||
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o=
|
||||||
github.com/zeromq/goczmq v4.1.0+incompatible h1:cGVQaU6kIwwrGso0Pgbl84tzAz/h7FJ3wYQjSonjFFc=
|
|
||||||
github.com/zeromq/goczmq v4.1.0+incompatible/go.mod h1:1uZybAJoSRCvZMH2rZxEwWBSmC4T7CB/xQOfChwPEzg=
|
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
|
|
|
@ -35,8 +35,8 @@ func NewMiner(coin string, poolAddress string, minerConn net.Conn) (*Miner, erro
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 动态切换矿池地址并建立新连接
|
// 动态切换矿池地址并建立新连接,切换时由proxy构造,由于每个池子的authorize认证不同,需单独处理
|
||||||
func (m *Miner) ChangePoolAddress(newAddress string) {
|
func (m *Miner) ChangePoolAddress(newAddress string, authorizeMsg string) {
|
||||||
m.Lock()
|
m.Lock()
|
||||||
defer m.Unlock()
|
defer m.Unlock()
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ func (m *Miner) ChangePoolAddress(newAddress string) {
|
||||||
|
|
||||||
m.PoolConn = newConn
|
m.PoolConn = newConn
|
||||||
m.PoolAddress = newAddress
|
m.PoolAddress = newAddress
|
||||||
|
m.PoolConn.Write([]byte(authorizeMsg + "\n")) // 发送认证信息
|
||||||
fmt.Println("成功切换矿池地址为:", newAddress)
|
fmt.Println("成功切换矿池地址为:", newAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,10 +78,10 @@ func (m *Miner) HandleMinerMsg(ch chan string) {
|
||||||
case "nexa":
|
case "nexa":
|
||||||
//
|
//
|
||||||
default:
|
default:
|
||||||
var msg msg.Authorize_msg
|
var _msg msg.Authorize_msg
|
||||||
if err := json.Unmarshal([]byte(msgStr), &msg); err == nil &&
|
if err := json.Unmarshal([]byte(msgStr), &_msg); err == nil &&
|
||||||
msg.Method == "mining.authorize" && len(msg.Params) >= 1 && !sent {
|
_msg.Method == "mining.authorize" && len(_msg.Params) >= 1 && !sent {
|
||||||
parts := strings.Split(msg.Params[0], ".")
|
parts := strings.Split(_msg.Params[0], ".")
|
||||||
if len(parts) >= 2 {
|
if len(parts) >= 2 {
|
||||||
userSign := parts[0] + "-" + parts[1]
|
userSign := parts[0] + "-" + parts[1]
|
||||||
select {
|
select {
|
||||||
|
|
|
@ -4,6 +4,7 @@ type ZmqMsg struct {
|
||||||
MethodID int `json:"methodId"` //0(add), 1(delete)
|
MethodID int `json:"methodId"` //0(add), 1(delete)
|
||||||
ID string `json:"id"` // user-miner
|
ID string `json:"id"` // user-miner
|
||||||
Address string `json:"address"` // 转发目标地址
|
Address string `json:"address"` // 转发目标地址
|
||||||
|
Msg string `json:"msg"` // 转发矿池的mining.authorize方法配置参数
|
||||||
}
|
}
|
||||||
|
|
||||||
type Authorize_msg struct {
|
type Authorize_msg struct {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"proxy/internal/miner"
|
"proxy/internal/miner"
|
||||||
|
"proxy/internal/msg"
|
||||||
"proxy/internal/zmq"
|
"proxy/internal/zmq"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -18,6 +19,7 @@ type Config struct {
|
||||||
ZmqAddr string `json:"zmqAddr"`
|
ZmqAddr string `json:"zmqAddr"`
|
||||||
TcpAddr string `json:"tcpAddr"`
|
TcpAddr string `json:"tcpAddr"`
|
||||||
DefaultAddr string `json:"proxyAddr"`
|
DefaultAddr string `json:"proxyAddr"`
|
||||||
|
RabbitTopic string `json:"rabbitTopic"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProxyCtx struct {
|
type ProxyCtx struct {
|
||||||
|
@ -26,7 +28,7 @@ type ProxyCtx struct {
|
||||||
Cfg Config
|
Cfg Config
|
||||||
Listener net.Listener
|
Listener net.Listener
|
||||||
MinerConn []*miner.Miner
|
MinerConn []*miner.Miner
|
||||||
ProxyList map[string]string
|
ProxyList map[string]msg.ZmqMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() Config {
|
func initConfig() Config {
|
||||||
|
@ -52,7 +54,7 @@ func newProxy() *ProxyCtx {
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
Listener: listener,
|
Listener: listener,
|
||||||
MinerConn: []*miner.Miner{},
|
MinerConn: []*miner.Miner{},
|
||||||
ProxyList: make(map[string]string),
|
ProxyList: make(map[string]msg.ZmqMsg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,10 +81,12 @@ func (p *ProxyCtx) handleMinerConnect() {
|
||||||
select {
|
select {
|
||||||
case userSign := <-ch:
|
case userSign := <-ch:
|
||||||
p.mu.RLock()
|
p.mu.RLock()
|
||||||
addr, ok := p.ProxyList[userSign]
|
zmqMsg, ok := p.ProxyList[userSign]
|
||||||
p.mu.RUnlock()
|
p.mu.RUnlock()
|
||||||
if ok {
|
if ok {
|
||||||
minerObj.ChangePoolAddress(addr)
|
addr := zmqMsg.Address
|
||||||
|
authorizeMsg := zmqMsg.Msg
|
||||||
|
minerObj.ChangePoolAddress(addr, authorizeMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
|
@ -101,7 +105,7 @@ func (p *ProxyCtx) handleMinerConnect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProxyCtx) startZMQ() {
|
func (p *ProxyCtx) startZMQ() {
|
||||||
zmq.StartZMQ(p.Cfg.ZmqAddr, "testQueue", p.ProxyList, &p.mu)
|
zmq.StartZMQ(p.Cfg.ZmqAddr, p.Cfg.RabbitTopic, p.ProxyList, &p.mu)
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartProxy() {
|
func StartProxy() {
|
||||||
|
|
|
@ -101,7 +101,7 @@ func initRabbitConsumer(rabbitURL, queueName string) (*amqp.Connection, *amqp.Ch
|
||||||
return conn, ch, msgs, nil
|
return conn, ch, msgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleRabbitMsg(body []byte, proxyList map[string]string, proxyListLock *sync.RWMutex) {
|
func handleRabbitMsg(body []byte, proxyList map[string]msg.ZmqMsg, proxyListLock *sync.RWMutex) {
|
||||||
var data msg.ZmqMsg
|
var data msg.ZmqMsg
|
||||||
if err := json.Unmarshal(body, &data); err != nil {
|
if err := json.Unmarshal(body, &data); err != nil {
|
||||||
fmt.Println("[rabbitmq]: json unmarshal error:", err)
|
fmt.Println("[rabbitmq]: json unmarshal error:", err)
|
||||||
|
@ -110,13 +110,13 @@ func handleRabbitMsg(body []byte, proxyList map[string]string, proxyListLock *sy
|
||||||
proxyListLock.Lock()
|
proxyListLock.Lock()
|
||||||
defer proxyListLock.Unlock()
|
defer proxyListLock.Unlock()
|
||||||
if data.MethodID == 0 {
|
if data.MethodID == 0 {
|
||||||
proxyList[data.ID] = data.Address
|
proxyList[data.ID] = data
|
||||||
} else {
|
} else {
|
||||||
delete(proxyList, data.ID)
|
delete(proxyList, data.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartZMQ(rabbitURL, queueName string, proxyList map[string]string, proxyListLock *sync.RWMutex) {
|
func StartZMQ(rabbitURL, queueName string, proxyList map[string]msg.ZmqMsg, proxyListLock *sync.RWMutex) {
|
||||||
conn, ch, msgs, err := initRabbitConsumer(rabbitURL, queueName)
|
conn, ch, msgs, err := initRabbitConsumer(rabbitURL, queueName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("[rabbitmq]:", err)
|
fmt.Println("[rabbitmq]:", err)
|
||||||
|
|
Loading…
Reference in New Issue