121 lines
3.1 KiB
Go
121 lines
3.1 KiB
Go
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
|
||
}
|