152 lines
4.8 KiB
Python
152 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
GBT测试脚本
|
||
用于测试GBT客户端的ZMQ通信功能
|
||
"""
|
||
|
||
import zmq
|
||
import json
|
||
import time
|
||
import threading
|
||
from typing import Dict, Any
|
||
|
||
class GbtTester:
|
||
def __init__(self, pub_port: int = 5555, sub_port: int = 5556):
|
||
self.pub_port = pub_port
|
||
self.sub_port = sub_port
|
||
self.context = zmq.Context()
|
||
|
||
# 订阅者套接字(接收挖矿任务)
|
||
self.subscriber = self.context.socket(zmq.SUB)
|
||
self.subscriber.connect(f"tcp://localhost:{self.sub_port}")
|
||
self.subscriber.setsockopt_string(zmq.SUBSCRIBE, "mining_msg")
|
||
|
||
# 发布者套接字(发送提交结果)
|
||
self.publisher = self.context.socket(zmq.PUB)
|
||
self.publisher.bind(f"tcp://*:{self.pub_port}")
|
||
|
||
self.running = False
|
||
self.received_tasks: Dict[str, Dict[str, Any]] = {}
|
||
|
||
def start(self):
|
||
"""启动测试器"""
|
||
self.running = True
|
||
|
||
# 启动接收线程
|
||
self.receive_thread = threading.Thread(target=self._receive_loop)
|
||
self.receive_thread.daemon = True
|
||
self.receive_thread.start()
|
||
|
||
print(f"GBT测试器已启动")
|
||
print(f"订阅端口: {self.sub_port}")
|
||
print(f"发布端口: {self.pub_port}")
|
||
|
||
def stop(self):
|
||
"""停止测试器"""
|
||
self.running = False
|
||
self.subscriber.close()
|
||
self.publisher.close()
|
||
self.context.term()
|
||
|
||
def _receive_loop(self):
|
||
"""接收消息循环"""
|
||
while self.running:
|
||
try:
|
||
# 非阻塞接收
|
||
message = self.subscriber.recv_multipart(flags=zmq.NOBLOCK)
|
||
if message:
|
||
topic = message[0].decode('utf-8')
|
||
data = message[1].decode('utf-8')
|
||
|
||
if topic == "mining_msg":
|
||
self._handle_mining_msg(data)
|
||
|
||
except zmq.Again:
|
||
# 没有消息,继续循环
|
||
time.sleep(0.1)
|
||
continue
|
||
except Exception as e:
|
||
print(f"接收消息错误: {e}")
|
||
time.sleep(1)
|
||
|
||
def _handle_mining_msg(self, data: str):
|
||
"""处理挖矿消息"""
|
||
try:
|
||
mining_msg = json.loads(data)
|
||
job_id = mining_msg.get('job_id')
|
||
|
||
print(f"\n收到挖矿任务: {job_id}")
|
||
print(f"区块高度: {mining_msg.get('block_header', {}).get('height')}")
|
||
print(f"output_smt_size: {mining_msg.get('output_smt_size')}")
|
||
print(f"target: {mining_msg.get('target')}")
|
||
print(f"coinbase_hash: {mining_msg.get('coinbase_hash')[:16]}...")
|
||
|
||
# 保存任务
|
||
self.received_tasks[job_id] = mining_msg
|
||
|
||
# 模拟挖矿(延迟1秒后提交)
|
||
threading.Timer(1.0, self._submit_result, args=[job_id]).start()
|
||
|
||
except json.JSONDecodeError as e:
|
||
print(f"JSON解析错误: {e}")
|
||
except Exception as e:
|
||
print(f"处理挖矿消息错误: {e}")
|
||
|
||
def _submit_result(self, job_id: str):
|
||
"""提交挖矿结果"""
|
||
if job_id not in self.received_tasks:
|
||
print(f"任务 {job_id} 不存在")
|
||
return
|
||
|
||
# 构造提交请求
|
||
submit_request = {
|
||
"job_id": job_id,
|
||
"nonce": 12345, # 模拟nonce
|
||
"solution": "test_solution_hash_12345" # 模拟solution
|
||
}
|
||
|
||
try:
|
||
# 发送提交请求
|
||
message = f"submit {json.dumps(submit_request)}"
|
||
self.publisher.send_string(message)
|
||
|
||
print(f"已提交挖矿结果: {job_id}")
|
||
print(f"nonce: {submit_request['nonce']}")
|
||
print(f"solution: {submit_request['solution']}")
|
||
|
||
except Exception as e:
|
||
print(f"提交结果错误: {e}")
|
||
|
||
def get_stats(self) -> Dict[str, Any]:
|
||
"""获取统计信息"""
|
||
return {
|
||
"received_tasks": len(self.received_tasks),
|
||
"task_ids": list(self.received_tasks.keys())
|
||
}
|
||
|
||
def main():
|
||
"""主函数"""
|
||
print("GBT ZMQ通信测试器")
|
||
print("=" * 50)
|
||
|
||
# 创建测试器
|
||
tester = GbtTester()
|
||
|
||
try:
|
||
# 启动测试器
|
||
tester.start()
|
||
|
||
# 主循环
|
||
while True:
|
||
time.sleep(5)
|
||
stats = tester.get_stats()
|
||
print(f"\n统计信息: 已接收 {stats['received_tasks']} 个任务")
|
||
|
||
except KeyboardInterrupt:
|
||
print("\n正在停止测试器...")
|
||
finally:
|
||
tester.stop()
|
||
print("测试器已停止")
|
||
|
||
if __name__ == "__main__":
|
||
main() |