m2pool-core/internal/gbt/tari/tari.go

121 lines
3.1 KiB
Go
Raw Normal View History

2025-09-03 08:00:42 +00:00
package tari
import (
"context"
"encoding/base64"
"encoding/hex"
"fmt"
base_node "pool/internal/gbt/tari/proto"
block "pool/internal/gbt/tari/proto/block"
"google.golang.org/grpc"
)
// var PowAlgoMap = []string{"randomxM", "sha3x", "randomxT"}
type BaseNodeClient struct {
Conn *grpc.ClientConn
Client base_node.BaseNodeClient
}
// 创建BaseNode客户端
func NewBaseNodeClient(address string) (*BaseNodeClient, error) {
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
return nil, fmt.Errorf("failed to connect to base node: %v", err)
}
// 移除 defer conn.Close(),让连接保持打开状态
client := base_node.NewBaseNodeClient(conn)
return &BaseNodeClient{
Conn: conn,
Client: client,
}, nil
}
// Close 关闭GRPC连接
func (c *BaseNodeClient) Close() error {
if c.Conn != nil {
return c.Conn.Close()
}
return nil
}
type TariBlockTemplate struct {
MiningHash string
Header string
Body string
Height uint64
TargetDifficulty uint64
}
func base64ToHex(data string) (string, error) {
result, err := base64.StdEncoding.DecodeString(data)
if err != nil {
return "", err
}
return hex.EncodeToString(result), nil
}
func (nc *BaseNodeClient) GetBlockTemplate(ctx context.Context, powIndex uint32) (TariBlockTemplate, error) {
var pow_algo block.PowAlgo_PowAlgos
switch powIndex {
case 0:
pow_algo = block.PowAlgo_POW_ALGOS_RANDOMXM
case 1:
pow_algo = block.PowAlgo_POW_ALGOS_SHA3X
case 2:
pow_algo = block.PowAlgo_POW_ALGOS_RANDOMXT
default:
fmt.Println("不支持", powIndex, "算法")
}
templateReq := &base_node.NewBlockTemplateRequest{
Algo: &block.PowAlgo{
PowAlgo: pow_algo,
},
MaxWeight: 0x00,
}
templateResp, err := nc.Client.GetNewBlockTemplate(ctx, templateReq)
if err != nil {
fmt.Println(pow_algo, "获取区块模板失败:", err)
return TariBlockTemplate{}, err
}
// 节点未同步完成
if !templateResp.InitialSyncAchieved {
fmt.Println("节点还未完成同步")
return TariBlockTemplate{}, err
}
blk_template, miner_data := templateResp.NewBlockTemplate, templateResp.MinerData
targetDifficulty := miner_data.TargetDifficulty
height := blk_template.Header.Height
blockBlob, err := nc.Client.GetNewBlockBlob(ctx, blk_template)
if err != nil {
fmt.Println("获得block blob失败", err)
return TariBlockTemplate{}, err
}
mining_hash, header, body := blockBlob.BlockHash, blockBlob.Header, blockBlob.BlockBody
var t_bt = TariBlockTemplate{
MiningHash: hex.EncodeToString(mining_hash),
Header: hex.EncodeToString(header),
Body: hex.EncodeToString(body),
TargetDifficulty: targetDifficulty,
Height: height,
}
return t_bt, nil
}
func (nc *BaseNodeClient) SubmitBlock(ctx context.Context, header, body []byte) ([]byte, error) {
submitReq := &base_node.BlockBlobRequest{
HeaderBlob: header,
BodyBlob: body,
}
submitResp, err := nc.Client.SubmitBlockBlob(ctx, submitReq)
if err != nil {
fmt.Println("提交区块失败:", err)
return nil, err
}
blockHash := submitResp.BlockHash
return blockHash, nil
}